From fb7061ad962953359cc713d8d1c2485b941dc8b0 Mon Sep 17 00:00:00 2001 From: Pierre Raybaut Date: Fri, 15 May 2026 06:42:08 +0200 Subject: [PATCH 001/108] feat(history): add icons for history panel Assisted-by: Claude Opus 4.7 --- datalab/data/icons/edit_mode.svg | 44 +++++++++++++++ datalab/data/icons/record.svg | 43 +++++++++++++++ datalab/data/icons/replay.svg | 51 ++++++++++++++++++ datalab/data/icons/restore_and_replay.svg | 66 +++++++++++++++++++++++ datalab/data/icons/restore_selection.svg | 52 ++++++++++++++++++ 5 files changed, 256 insertions(+) create mode 100644 datalab/data/icons/edit_mode.svg create mode 100644 datalab/data/icons/record.svg create mode 100644 datalab/data/icons/replay.svg create mode 100644 datalab/data/icons/restore_and_replay.svg create mode 100644 datalab/data/icons/restore_selection.svg diff --git a/datalab/data/icons/edit_mode.svg b/datalab/data/icons/edit_mode.svg new file mode 100644 index 000000000..6afff8120 --- /dev/null +++ b/datalab/data/icons/edit_mode.svg @@ -0,0 +1,44 @@ + + + + diff --git a/datalab/data/icons/record.svg b/datalab/data/icons/record.svg new file mode 100644 index 000000000..5017f50e7 --- /dev/null +++ b/datalab/data/icons/record.svg @@ -0,0 +1,43 @@ + + + + + + + diff --git a/datalab/data/icons/replay.svg b/datalab/data/icons/replay.svg new file mode 100644 index 000000000..7dd374a1f --- /dev/null +++ b/datalab/data/icons/replay.svg @@ -0,0 +1,51 @@ + + + + + + + + + + diff --git a/datalab/data/icons/restore_and_replay.svg b/datalab/data/icons/restore_and_replay.svg new file mode 100644 index 000000000..f27f163c3 --- /dev/null +++ b/datalab/data/icons/restore_and_replay.svg @@ -0,0 +1,66 @@ + + + + + + + + + + + + + diff --git a/datalab/data/icons/restore_selection.svg b/datalab/data/icons/restore_selection.svg new file mode 100644 index 000000000..156b7126c --- /dev/null +++ b/datalab/data/icons/restore_selection.svg @@ -0,0 +1,52 @@ + + + + + + + + + + From 28d8df537aa77eda86e4dae4ec23e1d8ba8cd42c Mon Sep 17 00:00:00 2001 From: Pierre Raybaut Date: Fri, 15 May 2026 09:24:43 +0200 Subject: [PATCH 002/108] feat: add history panel Migrated from history panel legacy branch --- datalab/gui/main.py | 36 +- datalab/gui/panel/base.py | 69 ++ datalab/gui/panel/history.py | 876 ++++++++++++++++++ datalab/gui/panel/image.py | 7 + datalab/gui/panel/signal.py | 7 + datalab/gui/processor/base.py | 63 +- datalab/h5/native.py | 106 +++ datalab/locale/fr/LC_MESSAGES/datalab.po | 171 +++- .../tests/features/common/history_app_test.py | 39 + 9 files changed, 1354 insertions(+), 20 deletions(-) create mode 100644 datalab/gui/panel/history.py create mode 100644 datalab/tests/features/common/history_app_test.py diff --git a/datalab/gui/main.py b/datalab/gui/main.py index fc08b0a6f..c798a4e7d 100644 --- a/datalab/gui/main.py +++ b/datalab/gui/main.py @@ -67,7 +67,7 @@ from datalab.gui.actionhandler import ActionCategory from datalab.gui.docks import DockablePlotWidget from datalab.gui.h5io import H5InputOutput -from datalab.gui.panel import base, image, macro, signal +from datalab.gui.panel import base, history, image, macro, signal from datalab.gui.pluginconfig import PluginConfigDialog from datalab.gui.settings import AI_OPTION_NAMES, edit_settings from datalab.objectmodel import ObjectGroup @@ -168,6 +168,7 @@ def __init__(self, console=None, hide_on_close=False): # pylint: disable=too-ma self.console: DockableConsole | None = None self._startup_errors: list[str] = [] self.macropanel: MacroPanel | None = None + self.historypanel: history.HistoryPanel | None = None self.aiassistantpanel = None # type: ignore[assignment] self.main_toolbar: QW.QToolBar | None = None @@ -715,12 +716,17 @@ def get_webapi_status(self) -> dict: # ------Misc. @property def panels(self) -> tuple[AbstractPanel, ...]: - """Return the tuple of implemented panels (signal, image) + """Return the tuple of implemented panels (signal, image, macro, history) Returns: Tuple of panels """ - return (self.signalpanel, self.imagepanel, self.macropanel) + return ( + self.signalpanel, + self.imagepanel, + self.macropanel, + self.historypanel, + ) def __set_low_memory_state(self, state: bool) -> None: """Set memory warning state""" @@ -1000,6 +1006,7 @@ def setup(self, console: bool = False) -> None: self.__flush_startup_errors() self.__update_actions(update_other_data_panel=True) self.__add_macro_panel() + self.__add_history_panel() self.__add_aiassistant_panel() self.__configure_panels() # Now that everything is set up, we can restore the window state: @@ -1667,6 +1674,14 @@ def __add_macro_panel(self) -> None: self.tabifyDockWidget(self.docks[self.imagepanel], mdock) self.docks[self.signalpanel].raise_() + def __add_history_panel(self) -> None: + """Add history panel""" + self.historypanel = history.HistoryPanel(self) + hdock = self.__add_dockwidget(self.historypanel, _("History Panel")) + self.docks[self.historypanel] = hdock + self.tabifyDockWidget(self.docks[self.macropanel], hdock) + self.docks[self.signalpanel].raise_() + def __add_aiassistant_panel(self) -> None: """Add AI Assistant panel""" # Local import to keep AI assistant fully optional/loadable on demand @@ -2047,6 +2062,9 @@ def save_to_h5_file(self, filename=None) -> None: ) if not filename: return + self.historypanel.add_entry( + _("Save to HDF5 file"), False, self.save_to_h5_file, filename=filename + ) with qth.qt_try_loadsave_file(self, filename, "save"): self.save_h5_workspace(filename) @@ -2119,6 +2137,18 @@ def open_h5_files( ) if not h5files: return + if len(h5files) > 1: + entry_title = _("Open %d HDF5 files") % len(h5files) + else: + entry_title = _("Open HDF5 file") + self.historypanel.add_entry( + entry_title, + False, + self.open_h5_files, + h5files=h5files, + import_all=import_all, + reset_all=reset_all, + ) filenames, dsetnames = [], [] for fname_with_dset in h5files: if "," in fname_with_dset: diff --git a/datalab/gui/panel/base.py b/datalab/gui/panel/base.py index 9fde16514..b24c523ed 100644 --- a/datalab/gui/panel/base.py +++ b/datalab/gui/panel/base.py @@ -1718,6 +1718,9 @@ def duplicate_object(self) -> None: """Duplication signal/image object""" if not self.mainwindow.confirm_memory_state(): return + self.mainwindow.historypanel.add_entry( + _("Duplicate object or group"), False, self.duplicate_object + ) # Duplicate individual objects (exclusive with respect to groups) for oid in self.objview.get_sel_object_uuids(): self.__duplicate_individual_obj(oid, set_current=False) @@ -1732,6 +1735,9 @@ def duplicate_object(self) -> None: def copy_metadata(self) -> None: """Copy object metadata""" + self.mainwindow.historypanel.add_entry( + _("Copy metadata"), False, self.copy_metadata + ) obj = self.objview.get_sel_objects()[0] self.metadata_clipboard = obj.metadata.copy() @@ -1788,6 +1794,9 @@ def paste_metadata(self, param: PasteMetadataParam | None = None) -> None: ) if not param.edit(parent=self.parentWidget()): return + self.mainwindow.historypanel.add_entry( + _("Paste metadata"), False, self.paste_metadata, param=param + ) metadata = {} if param.keep_roi and ROI_KEY in self.metadata_clipboard: metadata[ROI_KEY] = self.metadata_clipboard[ROI_KEY] @@ -1886,6 +1895,12 @@ def remove_object(self, force: bool = False) -> None: ) if answer == QW.QMessageBox.No: return + self.mainwindow.historypanel.add_entry( + _("Remove selected objects"), + False, + self.remove_object, + force=force, + ) sel_objects = self.objview.get_sel_objects(include_groups=True) for obj in sorted(sel_objects, key=get_short_id, reverse=True): dlg_list: list[QW.QDialog] = [] @@ -2011,6 +2026,13 @@ def new_group(self) -> None: # Open a message box to enter the group name group_name, ok = QW.QInputDialog.getText(self, _("New group"), _("Group name:")) if ok: + self.mainwindow.historypanel.add_entry( + _('New group "%s"') % group_name, + False, + self.add_group, + title=group_name, + select=False, + ) self.add_group(group_name) def rename_selected_object_or_group(self, new_name: str | None = None) -> None: @@ -2019,6 +2041,12 @@ def rename_selected_object_or_group(self, new_name: str | None = None) -> None: Args: new_name: new name (default: None, i.e. ask user) """ + self.mainwindow.historypanel.add_entry( + _("Rename selected object or group"), + False, + self.rename_selected_object_or_group, + new_name=new_name, + ) sel_objects = self.objview.get_sel_objects(include_groups=False) sel_groups = self.objview.get_sel_groups() if (not sel_objects and not sel_groups) or len(sel_objects) + len( @@ -2095,6 +2123,12 @@ def set_current_object_title(self, title: str) -> None: obj = self.objview.get_current_object() obj.title = title self.objview.update_item(get_uuid(obj)) + self.mainwindow.historypanel.add_entry( + _('Set current object title to "%s"') % title, + False, + self.set_current_object_title, + title=title, + ) def __load_from_file( self, filename: str, create_group: bool = True, add_objects: bool = True @@ -2226,6 +2260,20 @@ def load_from_files( filenames, _filt = getopenfilenames(self, _("Open"), basedir, filters) # Sort filenames to ensure consistent alphabetical order across all platforms filenames = sorted(filenames) + nbf = len(filenames) + if nbf > 1: + entry_title = _("Load from %d files") % nbf + else: + entry_title = _('Load "%s"') % osp.basename(filenames[0]) + self.mainwindow.historypanel.add_entry( + entry_title, + False, + self.load_from_files, + filenames=filenames, + create_group=create_group, + add_objects=add_objects, + ignore_errors=ignore_errors, + ) objs = [] for filename in filenames: with qt_try_loadsave_file(self.parentWidget(), filename, "load"): @@ -2254,6 +2302,14 @@ def save_to_files(self, filenames: list[str] | str | None = None) -> None: assert len(filenames) == len(objs), ( "Number of filenames must match number of objects" ) + nbf = len(filenames) + if nbf > 1: + entry_title = _("Save to %d different files") % nbf + else: + entry_title = _('Save to "%s"') % osp.basename(filenames[0]) + self.mainwindow.historypanel.add_entry( + entry_title, False, self.save_to_files, filenames=filenames + ) for index, obj in enumerate(objs): filename = filenames[index] if filename is None: @@ -3308,6 +3364,9 @@ def plot_results( def delete_results(self) -> None: """Delete results""" + self.mainwindow.historypanel.add_entry( + _("Delete results"), False, self.delete_results + ) objs = self.objview.get_sel_objects(include_groups=True) rdatadict = create_resultdata_dict(objs) if rdatadict: @@ -3355,6 +3414,16 @@ def add_label_with_title( added as an annotation, and that it can be edited or removed using the annotation editing window. """ + if title is None: + action_title = _("Add object title to plot") + else: + action_title = _("Add label with title") + self.mainwindow.historypanel.add_entry( + action_title, + False, + self.add_label_with_title, + title=title, + ) objs = self.objview.get_sel_objects(include_groups=True) for obj in objs: create_adapter_from_object(obj).add_label_with_title(title=title) diff --git a/datalab/gui/panel/history.py b/datalab/gui/panel/history.py new file mode 100644 index 000000000..a7b30505e --- /dev/null +++ b/datalab/gui/panel/history.py @@ -0,0 +1,876 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +""" +.. History panel (see parent package :mod:`datalab.gui.panel`) +""" + +# pylint: disable=invalid-name # Allows short reference names like x, y, ... + +from __future__ import annotations + +import functools +import inspect +import os +from typing import TYPE_CHECKING, Any, Callable, Generator +from uuid import uuid4 + +from guidata.configtools import get_icon +from guidata.qthelpers import add_actions, create_action +from guidata.widgets.dockable import DockableWidgetMixin +from qtpy import QtCore as QC +from qtpy import QtWidgets as QW + +from datalab.config import _ +from datalab.gui import ObjItf +from datalab.gui.panel.base import AbstractPanel + +if TYPE_CHECKING: + from datalab.gui.main import DLMainWindow + from datalab.gui.panel.base import BaseDataPanel + from datalab.gui.processor.base import BaseProcessor + from datalab.h5.native import NativeH5Reader, NativeH5Writer + + +def get_datetime_str() -> str: + """Return current date and time as a string""" + return QC.QDateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss") + + +def add_to_history(kwargs_names: list[str] = [], title: str | None = None): + """Method decorator to add the method call to the history panel + + Args: + kwargs_names: List of keyword arguments to add to the history action. + Defaults to []. + title: Title of the history action. Defaults to None. + """ + + def add_to_history_decorator(func): + """Decorator function""" + + @functools.wraps(func) + def method_wrapper(*args, **kwargs): + """Decorator wrapper function""" + self: BaseDataPanel | BaseProcessor = args[0] + history: HistoryPanel = self.mainwindow.historypanel + histkwargs = {k: kwargs[k] for k in kwargs_names if k in kwargs} + history.add_entry( + kwargs.get("title", title), + kwargs.get("save_state", True), + func, + *args, + **histkwargs, + ) + return func(*args, **kwargs) + + return method_wrapper + + return add_to_history_decorator + + +class HistoryAction(ObjItf): + """Object representing an action in the history panel. + + An action is basically a function that can be called in the same conditions as + when it was added to the history panel. Replay an action is done by calling the + function with the same parameters. + + Args: + title: Title of the history action + func: Function to call + args: Function arguments + kwargs: Function keyword arguments + state: State of the workspace before the action + """ + + FUNC_EDIT_MODE = "edit" # Name of the function parameter to enable edit mode + + def __init__( + self, + title: str | None = None, + func: Callable | None = None, + args: tuple | None = None, + kwargs: dict[str, Any] | None = None, + state: WorkspaceState | None = None, + ) -> None: + """Create a new action""" + super().__init__() + self.__title = "" if title is None else title + if func is None: + + def default_func(): + """Default function""" + # This function is used to create a default action when the + # function is not provided. + pass + + func = default_func + else: + if not callable(func): + raise TypeError("func must be callable") + self.func = func + self.args = () if args is None else args + kwargs = {} if kwargs is None else kwargs + self.kwargs = {k: v for k, v in kwargs.items() if v is not None} + self.state = WorkspaceState() if state is None else state + self.dtstr: str = get_datetime_str() + self.uuid: str = str(uuid4()) + + def regenerate_uuid(self): + """Regenerate UUID + + This method is used to regenerate UUID after loading the object from a file. + This is required to avoid UUID conflicts when loading objects from file + without clearing the workspace first. + """ + # No UUID to regenerate for history action + + @property + def title(self) -> str: + """Return object title""" + return self.__title + + @property + def description(self) -> str: + """Return object description (string representing function parameters)""" + desc = "" + no_parameters = True + for kwname in self.kwargs: + if kwname.endswith("param"): + param = self.kwargs[kwname] + # Note: `param` can't be None because we removed None values from kwargs + if desc: + desc += os.linesep + desc += str(param) + no_parameters = False + if desc or no_parameters: + return desc + if len(self.args) >= 2 and isinstance(self.args[1], Callable): + doc: str = self.args[1].__doc__ + return doc.splitlines()[0] if doc else "" + return self.func.__doc__ or "" + + def is_current_state_compatible( + self, mainwindow: DLMainWindow, restore_selection: bool + ) -> bool: + """Check if the current workspace state is compatible with the saved state + + Args: + mainwindow: DataLab's main window + restore_selection: True to restore the selection before checking the state + + Returns: + bool: True if the current workspace state is compatible with the saved state + """ + return self.state.is_current_state_compatible(mainwindow, restore_selection) + + def restore(self, mainwindow: DLMainWindow) -> None: + """Restore the associated workspace state + + Args: + mainwindow: DataLab's main window + """ + self.state.restore(mainwindow) + + def replay( + self, mainwindow: DLMainWindow, restore_selection: bool, edit: bool + ) -> None: + """Replay the action + + Args: + mainwindow: DataLab's main window + restore_selection: True to restore the workspace selection before replaying + edit: if True, always open the dialog boxes to edit parameters, if False, + use the parameters passed when creating the action + """ + if restore_selection: + self.state.restore(mainwindow) + sig = inspect.signature(self.func) + if self.FUNC_EDIT_MODE in sig.parameters: + self.kwargs[self.FUNC_EDIT_MODE] = edit + self.func(*self.args, **self.kwargs) + + def serialize(self, writer: NativeH5Writer) -> None: + """Serialize this action + + Args: + writer: Writer + """ + with writer.group("func"): + writer.write(self.func) + with writer.group("args"): + writer.write(self.args) + with writer.group("kwargs"): + writer.write_dict(self.kwargs) + with writer.group("state"): + self.state.serialize(writer) + with writer.group("dtstr"): + writer.write(self.dtstr) + + def deserialize(self, reader: NativeH5Reader) -> None: + """Deserialize this action + + Args: + reader: Reader + """ + with reader.group("func"): + self.func = reader.read_any() + with reader.group("args"): + self.args = reader.read_any() + with reader.group("kwargs"): + self.kwargs = reader.read_dict() + with reader.group("state"): + self.state.deserialize(reader) + with reader.group("dtstr"): + self.dtstr = reader.read_any() + + +class WorkspaceState: + """Object representing the workspace state at a given time. + + The workspace state is the state of the workspace at a given time. It contains + the list of objects in the workspace and the selection of objects. Instead of + storing the objects themselves, the workspace state only stores what is relevant + to the history panel, i.e. the object data shape and the object title (even + if the latter is purely informative). + """ + + def __init__(self) -> None: + """Create a new workspace state""" + # The selection is stored as a dictionary where the key is the panel name + # and the value is the list of selected object numbers (1 to N). + self.selection: dict[str, list[int]] = {} + # The states are stored as a dictionary where the key is the panel name + # and the value is the list of states (str) of the objects in the panel. The + # state is a string containing the object data shape (for now, only the shape, + # but we could add more information if needed). The idea is that two objects + # have the same state, we can apply the same action (processing, operation, ...) + # to both objects. + self.states: dict[str, list[str]] = {} + # The titles are stored as a dictionary where the key is the panel name and the + # value is the list of titles of the objects in the panel. The title is only + # informative and is not used to determine if two objects have the same state. + self.titles: dict[str, list[str]] = {} + + def serialize(self, writer: NativeH5Writer) -> None: + """Serialize this workspace state + + Args: + writer: Writer + """ + with writer.group("selection"): + writer.write_dict(self.selection) + with writer.group("states"): + writer.write_dict(self.states) + with writer.group("titles"): + writer.write_dict(self.titles) + + def deserialize(self, reader: NativeH5Reader) -> None: + """Deserialize this workspace state + + Args: + reader: Reader + """ + with reader.group("selection"): + self.selection = reader.read_dict() + with reader.group("states"): + self.states = reader.read_dict() + with reader.group("titles"): + self.titles = reader.read_dict() + + def get_current_selection(self, mainwindow: DLMainWindow) -> dict[str, list[int]]: + """Get the current selection in the workspace + + Args: + mainwindow: DataLab's main window + + Returns: + dict[str, list[int]]: Current selection in the workspace + """ + selection: dict[str, list[int]] = {} + for panel in (mainwindow.signalpanel, mainwindow.imagepanel): + selection[panel.PANEL_STR] = [ + obj.number for obj in panel.objview.get_sel_objects(include_groups=True) + ] + return selection + + def save(self, mainwindow: DLMainWindow) -> None: + """Save the current workspace state + + Args: + mainwindow: DataLab's main window + """ + self.selection = self.get_current_selection(mainwindow) + for panel in (mainwindow.signalpanel, mainwindow.imagepanel): + selection = self.selection[panel.PANEL_STR] + self.states[panel.PANEL_STR] = [ + str(obj.data.shape) for obj in panel.objmodel if obj.number in selection + ] + self.titles[panel.PANEL_STR] = [ + obj.title for obj in panel.objmodel if obj.number in selection + ] + + def is_current_state_compatible( + self, mainwindow: DLMainWindow, restore_selection: bool + ) -> bool: + """Check if the current workspace state is compatible with the saved state + + Args: + mainwindow: DataLab's main window + restore_selection: True to restore the selection before checking the state + + Returns: + bool: True if the current workspace state is compatible with the saved state + """ + # A compatible state is a state where the selected objects are the same as the + # saved selected objects in terms of position in the list of objects and of + # data shape (title is not relevant). + # To check this, we have to try to restore the selection (without restoring it) + # and compare the current selection with the saved selection in terms of + # position in the list of objects and of data shape. + if self.states == {}: + return True + current_states: dict[str, list[str]] = {} + selection = self.selection + if not restore_selection: + selection = self.get_current_selection(mainwindow) + for panel in (mainwindow.signalpanel, mainwindow.imagepanel): + numbers = selection[panel.PANEL_STR] + current_states[panel.PANEL_STR] = [ + str(obj.data.shape) for obj in panel.objmodel if obj.number in numbers + ] + return current_states == self.states + + def restore(self, mainwindow: DLMainWindow) -> None: + """Restore the workspace state + + Only the selection is restored, not the objects themselves because they are + not stored in the workspace state. Before restoring the selection, we may + check if the current workspace objects are compatible with the saved + workspace state. If not, we raise a `ValueError`. + + Args: + mainwindow: DataLab's main window + + Raises: + ValueError: If the current workspace state is not compatible with the + saved state + """ + if self.selection == {}: + return + if not self.is_current_state_compatible(mainwindow, False): + raise ValueError( + "Current workspace state is not compatible with saved state" + ) + for panel in (mainwindow.signalpanel, mainwindow.imagepanel): + numbers = self.selection[panel.PANEL_STR] + panel.objview.select_objects(numbers) + + +class HistorySession: + """Object representing a history session, i.e. a list of actions. + + A history session is a list of actions that can be replayed in the same order + as they were added to the history session. The history session can be saved to + a file and loaded from a file. + + Args: + title: Title of the history session + number: Number of the history session + """ + + def __init__(self, title: str = "", number: int = 0) -> None: + """Create a new history session""" + prefix = _("Session") + self.title = title if title else f"{prefix} {number:03d}" + self.number = number + self.dtstr: str = get_datetime_str() + self.actions: list[HistoryAction] = [] + + def add_action(self, action: HistoryAction) -> None: + """Add an action to the history session + + Args: + action: Action to add + """ + self.actions.append(action) + + def is_current_state_compatible( + self, mainwindow: DLMainWindow, restore_selection: bool + ) -> bool: + """Check if the current workspace state is compatible with the saved state + + Args: + mainwindow: DataLab's main window + restore_selection: True to restore the selection before checking the state + + Returns: + bool: True if the current workspace state is compatible with the saved state + """ + if self.actions: + return self.actions[0].is_current_state_compatible( + mainwindow, restore_selection + ) + return True + + def restore(self, mainwindow: DLMainWindow) -> None: + """Restore the state of the workspace associated to the first action of session + + Args: + mainwindow: DataLab's main window + """ + if self.actions: + self.actions[0].restore(mainwindow) + + def replay( + self, mainwindow: DLMainWindow, restore_selection: bool, edit: bool + ) -> None: + """Replay the history session + + Args: + mainwindow: DataLab's main window + restore_selection: True to restore the workspace selection before replaying + edit: if True, always open the dialog boxes to edit parameters, if False, + use the parameters passed when creating the action + """ + for action in self.actions[:]: + action.replay(mainwindow, restore_selection=restore_selection, edit=edit) + + def serialize(self, writer: NativeH5Writer) -> None: + """Serialize this history session + + Args: + writer: Writer + """ + with writer.group("title"): + writer.write(self.title) + with writer.group("number"): + writer.write(self.number) + with writer.group("dtstr"): + writer.write(self.dtstr) + writer.write_object_list(self.actions, "actions") + + def deserialize(self, reader: NativeH5Reader) -> None: + """Deserialize this history session + + Args: + reader: Reader + """ + with reader.group("title"): + self.title = reader.read_any() + with reader.group("number"): + self.number = reader.read_any() + with reader.group("dtstr"): + self.dtstr = reader.read_any() + self.actions = reader.read_object_list("actions", HistoryAction) + + def remove_action(self, action: HistoryAction) -> None: + """Remove an action from the history session + + This implies removing all subsequent actions. If action is not found, this + fails silently. + + Args: + action: Action to remove + """ + if action in self.actions: + index = self.actions.index(action) + self.actions = self.actions[:index] + + +class HistoryTree(QW.QTreeWidget): + """Tree widget for the history panel""" + + def __init__(self, parent: QW.QWidget) -> None: + """Create a new history tree widget""" + super().__init__(parent) + self.setHeaderLabels([_("Title"), _("Date and time"), _("Description")]) + self.setContextMenuPolicy(QC.Qt.CustomContextMenu) + self.setSelectionMode(QW.QAbstractItemView.ContiguousSelection) + + @staticmethod + def action_to_tree_item(action: HistoryAction) -> QW.QTreeWidgetItem: + """Convert an action to a tree item + + Args: + action: Action to convert + + Returns: + QW.QTreeWidgetItem: Tree item + """ + item = QW.QTreeWidgetItem([action.title, action.dtstr, action.description]) + item.setData(0, QC.Qt.UserRole, action.uuid) + return item + + def populate_tree(self, history_sessions: list[HistorySession]) -> None: + """Populate the history tree widget + + Args: + history_sessions: List of history sessions + """ + self.clear() + for session in history_sessions: + ritem = QW.QTreeWidgetItem([session.title, session.dtstr]) + self.addTopLevelItem(ritem) + for action in session.actions: + ritem.addChild(self.action_to_tree_item(action)) + self.expandAll() + for col in (0, 1): + self.resizeColumnToContents(col) + + def rearrange_tree(self) -> None: + """Rearrange the history tree widget""" + self.expandAll() + for col in (0, 1): + self.resizeColumnToContents(col) + + def add_action_to_tree(self, action: HistoryAction) -> None: + """Add an action to the history tree widget + + Args: + action: Action to add + """ + item = self.action_to_tree_item(action) + ritem = self.topLevelItem(self.topLevelItemCount() - 1) + ritem.addChild(item) + + def get_action_from_uuid( + self, uuid: str, history_sessions: list[HistorySession] + ) -> HistoryAction: + """Get the action from its UUID + + Args: + uuid: Action UUID + history_sessions: List of history sessions + + Returns: + HistoryAction: Action + """ + for session in history_sessions: + for action in session.actions: + if action.uuid == uuid: + return action + raise ValueError("Action not found") + + def get_selected_actions_or_sessions( + self, history_sessions: list[HistorySession] + ) -> list[HistoryAction | HistorySession]: + """Get the selected actions or sessions + + Args: + history_sessions: List of history sessions + + Returns: + list[HistoryAction | HistorySession]: List of selected actions or sessions + """ + selected: list[HistoryAction | HistorySession] = [] + for item in self.selectedItems(): + if item.parent() is None: + index = self.indexOfTopLevelItem(item) + selected.append(history_sessions[index]) + else: + uuid = item.data(0, QC.Qt.UserRole) + selected.append(self.get_action_from_uuid(uuid, history_sessions)) + return selected + + def get_selected_actions( + self, history_sessions: list[HistorySession] + ) -> list[HistoryAction]: + """Get the selected actions + + Args: + history_sessions: List of history sessions + + Returns: + list[HistoryAction]: List of selected actions + """ + selected: list[HistoryAction] = [] + for item in self.selectedItems(): + if item.parent() is not None: + uuid = item.data(0, QC.Qt.UserRole) + selected.append(self.get_action_from_uuid(uuid, history_sessions)) + return selected + + +class HistoryPanel(AbstractPanel, DockableWidgetMixin): + """History panel""" + + LOCATION = QC.Qt.RightDockWidgetArea + PANEL_STR = _("History panel") + + H5_PREFIX = "DataLab_His" + + SIG_OBJECT_MODIFIED = QC.Signal() + + FILE_FILTERS = f"{_('History files')} (*.cdlhist)" + + def __init__(self, parent: DLMainWindow) -> None: + super().__init__(parent) + self.setWindowTitle(self.PANEL_STR) + self.setWindowIcon(get_icon("history.svg")) + self.setOrientation(QC.Qt.Vertical) + + self.__record_mode = False + self.__edit_mode = False + self.__menu_actions: list[QW.QAction] = self.__create_menu_actions() + + self.mainwindow = parent + self.tree = HistoryTree(self) + self.tree.customContextMenuRequested.connect(self.show_context_menu) + self.tree.itemDoubleClicked.connect(self.replay_restore_actions) + + toolbar = QW.QToolBar(self) + add_actions(toolbar, self.__menu_actions) + widget = QW.QWidget(self) + layout = QW.QVBoxLayout() + layout.addWidget(toolbar) + layout.addWidget(self.tree) + layout.setContentsMargins(0, 0, 0, 0) + widget.setLayout(layout) + + self.addWidget(widget) + + self.__history_sessions: list[HistorySession] = [] + self.__session_increment = 0 + + def __create_menu_actions(self) -> list[QW.QAction]: + """Create menu actions for the history panel + + Returns: + list[QW.QAction]: List of menu actions + """ + edit_action = create_action( + self, + _("Edit mode"), + toggled=self.toggle_edit_mode, + icon=get_icon("edit_mode.svg"), + ) + edit_action.setChecked(self.__edit_mode) + record_action = create_action( + self, + _("Record mode"), + toggled=self.toggle_record_mode, + icon=get_icon("record.svg"), + ) + record_action.setChecked(self.__record_mode) + return [ + record_action, + None, + create_action( + self, + _("Replay"), + lambda: self.replay_restore_actions(restore_selection=False), + icon=get_icon("replay.svg"), + ), + create_action( + self, + _("Restore selection"), + lambda: self.replay_restore_actions( + restore_selection=True, replay=False + ), + icon=get_icon("restore_selection.svg"), + ), + create_action( + self, + _("Restore selection and replay"), + self.replay_restore_actions, + icon=get_icon("restore_and_replay.svg"), + ), + edit_action, + None, + create_action( + self, + _("Delete"), + self.delete_actions, + icon=get_icon("delete.svg"), + ), + ] + + def toggle_edit_mode(self, checked: bool) -> None: + """Toggle edit mode + + Args: + checked: True if the edit mode is checked, False otherwise + """ + self.__edit_mode = checked + + def toggle_record_mode(self, checked: bool) -> None: + """Toggle record mode + + Args: + checked: True if the record mode is checked, False otherwise + """ + self.__record_mode = checked + + def show_context_menu(self, pos: QC.QPoint) -> None: + """Show the context menu + + Args: + pos: Position of the context menu + """ + menu = QW.QMenu() + add_actions(menu, self.__menu_actions) + menu.exec_(self.tree.mapToGlobal(pos)) + + def get_action_from_uuid(self, uuid: str) -> HistoryAction: + """Get the action from its UUID + + Args: + uuid: Action UUID + + Returns: + HistoryAction: Action + """ + for session in self.__history_sessions: + for action in session.actions: + if action.uuid == uuid: + return action + raise ValueError("Action not found") + + def replay_restore_actions( + self, replay: bool = True, restore_selection: bool = True + ) -> None: + """Replay and/or restore selection for the selected actions""" + for session_or_action in self.tree.get_selected_actions_or_sessions( + self.__history_sessions + ): + if not session_or_action.is_current_state_compatible( + self.mainwindow, restore_selection=restore_selection + ): + QW.QMessageBox.critical( + self.mainwindow, + _("Error"), + _("The current workspace state is not compatible with the action."), + ) + return + if replay: + session_or_action.replay( + self.mainwindow, + restore_selection=restore_selection, + edit=self.__edit_mode, + ) + elif restore_selection: + session_or_action.restore(self.mainwindow) + + def delete_actions(self) -> None: + """Delete the selected actions""" + # Ask for confirmation as this will delete the action and all subsequent actions + reply = QW.QMessageBox.question( + self.mainwindow, + _("Delete actions"), + _( + "Do you really want to delete the selected action " + "and all the next ones?" + ), + QW.QMessageBox.Yes | QW.QMessageBox.No, + QW.QMessageBox.No, + ) + if reply == QW.QMessageBox.Yes: + for action in self.tree.get_selected_actions(self.__history_sessions): + for session in self.__history_sessions: + if action in session.actions: + session.remove_action(action) + self.tree.populate_tree(self.__history_sessions) + + def serialize_to_hdf5(self, writer: NativeH5Writer) -> None: + """Serialize whole panel to a HDF5 file + + Args: + writer: HDF5 writer + """ + writer.write_object_list(self.__history_sessions, self.H5_PREFIX) + + def deserialize_from_hdf5( + self, reader: NativeH5Reader, reset_all: bool = False + ) -> None: + """Deserialize whole panel from a HDF5 file + + Args: + reader: HDF5 reader + reset_all: Unused (kept for compatibility with panel API) + """ + self.__history_sessions: list[HistorySession] = ( + reader.read_object_list(self.H5_PREFIX, HistorySession) or [] + ) + if self.__history_sessions: + self.__session_increment = self.__history_sessions[-1].number + self.tree.populate_tree(self.__history_sessions) + + def __len__(self) -> int: + """Return number of objects""" + return sum(len(session.actions) for session in self.__history_sessions) + + def __getitem__(self, nb: int) -> HistoryAction: + """Return object from its number (1 to N)""" + for session in self.__history_sessions: + if nb <= len(session.actions): + return session.actions[nb - 1] + nb -= len(session.actions) + raise IndexError("Index out of range") + + def __iter__(self) -> Generator[HistoryAction, None, None]: + """Iterate over objects""" + for session in self.__history_sessions: + for action in session.actions: + yield action + + def create_new_session(self) -> None: + """Create a new history list""" + self.__session_increment += 1 + session = HistorySession(number=self.__session_increment) + self.__history_sessions.append(session) + self.tree.populate_tree(self.__history_sessions) + + def add_entry( + self, + action_title: str, + save_state: bool, + func: Callable, + *args, + **kwargs, + ) -> None: + """Add an entry to the current history list + + Args: + action_title: Title of the history action + save_state: If True, the current workspace state is saved before adding the + action (this is the most common case). If False, the action is added + without saving the state: this may be useful when the action is not + related to the current workspace state (e.g. when creating a new object). + func: Function to call + args: Function arguments + kwargs: Function keyword arguments + + .. warning:: + + Action will **not** be added to history if *record mode* is disabled. + """ + assert isinstance(action_title, str), "action_title must be a string" + assert isinstance(save_state, bool), "save_state must be a boolean" + assert callable(func), "func must be callable" + if not self.__record_mode: + return + if save_state: + state = WorkspaceState() + state.save(self.mainwindow) + else: + state = None + obj = HistoryAction(action_title, func, args, kwargs, state) + self.add_object(obj) + + # ------ AbstractPanel interface --------------------------------------------------- + def create_object(self) -> HistoryAction: + """Create and return object""" + return HistoryAction() + + def add_object(self, obj: HistoryAction) -> None: + """Add object to panel""" + if not self.__history_sessions: + self.create_new_session() + self.__history_sessions[-1].add_action(obj) + self.tree.add_action_to_tree(obj) + self.tree.rearrange_tree() + + def remove_all_objects(self): + """Remove all objects""" + super().remove_all_objects() diff --git a/datalab/gui/panel/image.py b/datalab/gui/panel/image.py index 661c752e9..4fa20f99d 100644 --- a/datalab/gui/panel/image.py +++ b/datalab/gui/panel/image.py @@ -255,6 +255,13 @@ def new_object( image = create_image_gui(param, edit=edit, parent=self.parentWidget()) if image is None: return None + self.mainwindow.historypanel.add_entry( + _("New image"), + False, + self.new_object, + param=param, + add_to_panel=add_to_panel, + ) if add_to_panel: self.add_object(image) return image diff --git a/datalab/gui/panel/signal.py b/datalab/gui/panel/signal.py index 26d8abca1..eedaf0115 100644 --- a/datalab/gui/panel/signal.py +++ b/datalab/gui/panel/signal.py @@ -146,6 +146,13 @@ def new_object( signal = create_signal_gui(param, edit=edit, parent=self.parentWidget()) if signal is None: return None + self.mainwindow.historypanel.add_entry( + _("New signal"), + False, + self.new_object, + param=param, + add_to_panel=add_to_panel, + ) if add_to_panel: self.add_object(signal) return signal diff --git a/datalab/gui/processor/base.py b/datalab/gui/processor/base.py index 0d4a659c7..01bb384f7 100644 --- a/datalab/gui/processor/base.py +++ b/datalab/gui/processor/base.py @@ -45,7 +45,7 @@ from datalab.adapters_plotpy import coordutils from datalab.config import Conf, _ from datalab.gui.processor.catcher import CompOut, wng_err_func -from datalab.objectmodel import get_short_id, get_uuid, patch_title_with_ids +from datalab.objectmodel import get_number, get_short_id, get_uuid, patch_title_with_ids from datalab.utils.qthelpers import create_progress_bar, qt_try_except from datalab.widgets.warningerror import show_warning_error @@ -1342,6 +1342,14 @@ def compute_1_to_n( group = gds.DataSetGroup(params, title=_("Parameters")) if not group.edit(parent=self.mainwindow): return + self.mainwindow.historypanel.add_entry( + title, + True, + self.compute_1_to_n, + func, + params=params, + title=title, + ) self._compute_1_to_1_subroutine([func] * len(params), params, title) def compute_1_to_0( @@ -1471,6 +1479,7 @@ def compute_n_to_1( title: str | None = None, comment: str | None = None, edit: bool | None = None, + pairwise: bool | None = None, ) -> None: """Generic processing method: n objects in → 1 object out. @@ -1503,9 +1512,20 @@ def compute_n_to_1( objs = self.panel.objview.get_sel_objects(include_groups=True) objmodel = self.panel.objmodel - pairwise = is_pairwise_mode() + pairwise = is_pairwise_mode() if pairwise is None else pairwise name = func.__name__ + self.mainwindow.historypanel.add_entry( + name, + True, + self.compute_n_to_1, + func, + param=param, + title=title, + comment=comment, + pairwise=pairwise, + ) + if pairwise: src_grps, src_gids, src_objs, _nbobj, valid = ( self.__get_src_grps_gids_objs_nbobj_valid(min_group_nb=2) @@ -1698,7 +1718,12 @@ def compute_n_to_1( def compute_2_to_1( self, - obj2: SignalObj | ImageObj | list[SignalObj | ImageObj] | None, + obj2: SignalObj + | ImageObj + | list[SignalObj | ImageObj] + | int + | list[int] + | None, obj2_name: str, func: Callable, param: gds.DataSet | None = None, @@ -1707,6 +1732,7 @@ def compute_2_to_1( comment: str | None = None, edit: bool | None = None, skip_xarray_compat: bool | None = None, + pairwise: bool | None = None, ) -> None: """Generic processing method: binary operation 1+1 → 1. @@ -1745,7 +1771,7 @@ def compute_2_to_1( objs = self.panel.objview.get_sel_objects(include_groups=True) objmodel = self.panel.objmodel - pairwise = is_pairwise_mode() + pairwise = is_pairwise_mode() if pairwise is None else pairwise name = func.__name__ if obj2 is None: @@ -1755,6 +1781,9 @@ def compute_2_to_1( assert pairwise else: objs2 = [obj2] + if objs2 and all(isinstance(obj, int) for obj in objs2): + # If obj2 is a list of object numbers, convert to objects + objs2 = [objmodel.get_object_from_number(obj) for obj in objs2] dlg_title = _("Select %s") % obj2_name @@ -1779,6 +1808,19 @@ def compute_2_to_1( if objs2 is None: return + self.mainwindow.historypanel.add_entry( + title, + True, + self.compute_2_to_1, + [get_number(obj) for obj in objs2], + obj2_name, + func, + param=param, + title=title, + comment=comment, + pairwise=True, + ) + n_pairs = len(src_objs[src_gids[0]]) max_i_pair = min( n_pairs, max(len(src_objs[get_uuid(grp)]) for grp in src_grps) @@ -1904,6 +1946,19 @@ def compute_2_to_1( return obj2 = objs2[0] + self.mainwindow.historypanel.add_entry( + title, + True, + self.compute_2_to_1, + get_number(obj2), + obj2_name, + func, + param=param, + title=title, + comment=comment, + pairwise=False, + ) + # Initialize signal mapping for potential interpolations signal_map = {} diff --git a/datalab/h5/native.py b/datalab/h5/native.py index 84419e4e8..78aaff0b8 100644 --- a/datalab/h5/native.py +++ b/datalab/h5/native.py @@ -8,11 +8,18 @@ from __future__ import annotations +import importlib +from typing import Any, Callable + from guidata.io import HDF5Reader, HDF5Writer +from guidata.io.h5fmt import NoDefault import datalab DATALAB_VERSION_NAME = "DataLab_Version" +DATALAB_PACKAGE_NAME = "datalab" + +H5_CALLABLE_PREFIX = "#callable#" class NativeH5Writer(HDF5Writer): @@ -26,6 +33,45 @@ def __init__(self, filename: str) -> None: super().__init__(filename) self.h5[DATALAB_VERSION_NAME] = datalab.__version__ + @staticmethod + def serialize_func_or_class(obj: Callable | type) -> str: + """Serialize a function or a class object + + Args: + obj: Object to serialize + + Returns: + str: Serialized object + """ + if not obj.__module__.startswith(DATALAB_PACKAGE_NAME): + raise ValueError( + f"Only {DATALAB_PACKAGE_NAME} functions and classes can be serialized" + ) + val = f"{H5_CALLABLE_PREFIX}{obj.__module__}." + if isinstance(obj, type): + return val + obj.__name__ + return val + obj.__qualname__ + + # Reimplement the write method to handle callable objects + def write(self, val: Any, group_name: str | None = None) -> None: + """ + Write a value depending on its type, optionally within a named group. + + Args: + val: The value to be written. + group_name: The name of the group. If provided, the group + context will be used for writing the value. + """ + try: + super().write(val, group_name) + except NotImplementedError: + if callable(val): + super().write_str(self.serialize_func_or_class(val)) + if group_name: + self.end(group_name) + else: + raise + class NativeH5Reader(HDF5Reader): """DataLab signal/image objects HDF5 guidata dataset Writer class @@ -37,3 +83,63 @@ class NativeH5Reader(HDF5Reader): def __init__(self, filename: str) -> None: super().__init__(filename) self.version = self.h5[DATALAB_VERSION_NAME] + + @staticmethod + def deserialize_func_or_class(obj: str) -> Callable | type: + """Deserialize a function or a class object + + Args: + obj: Serialized object + + Returns: + Callable | type: Deserialized object + """ + parts = obj[len(H5_CALLABLE_PREFIX) :].split(".") + if not parts or not parts[0].startswith(DATALAB_PACKAGE_NAME): + raise ValueError( + f"Only {DATALAB_PACKAGE_NAME} functions and classes can be deserialized" + ) + # Walk path parts: find longest valid module prefix, then resolve the + # remaining attribute chain (supports methods like ``Class.method``). + for split_index in range(len(parts) - 1, 0, -1): + module_name = ".".join(parts[:split_index]) + try: + module = importlib.import_module(module_name) + except ImportError: + continue + attr: Any = module + try: + for name in parts[split_index:]: + attr = getattr(attr, name) + except AttributeError: + continue + return attr + raise ImportError(f"Cannot deserialize callable: {obj}") + + # Reimplement the read method to handle callable objects + def read( + self, + group_name: str | None = None, + func: Callable[[], Any] | None = None, + instance: Any | None = None, + default: Any | NoDefault = NoDefault, + ) -> Any: + """ + Read a value from the current group or specified group_name. + + Args: + group_name: The name of the group to read from. Defaults to None. + func: The function to use for reading the value. Defaults to None. + instance: An object that implements the DataSet-like `deserialize` method. + Defaults to None. + default: The default value to return if the value is not found. + Defaults to `NoDefault` (no default value: raises an exception if the + value is not found). + + Returns: + The read value. + """ + val = super().read(group_name) + if isinstance(val, str) and val.startswith(H5_CALLABLE_PREFIX): + return self.deserialize_func_or_class(val) + return val diff --git a/datalab/locale/fr/LC_MESSAGES/datalab.po b/datalab/locale/fr/LC_MESSAGES/datalab.po index 84f62f00e..1378ff0d8 100644 --- a/datalab/locale/fr/LC_MESSAGES/datalab.po +++ b/datalab/locale/fr/LC_MESSAGES/datalab.po @@ -50,6 +50,12 @@ msgstr "Inactif" msgid "Ask the assistant… (Ctrl+Enter to send, Ctrl+Up/Down to navigate previous prompts)" msgstr "Posez une question à l'assistant… (Ctrl+Entrée pour envoyer, Ctrl+Flèche haut/bas pour naviguer dans les questions précédentes)" +msgid "Stop" +msgstr "Arrêter" + +msgid "Cancel the in-flight request (Esc)." +msgstr "Annuler la requête en cours (Échap)." + msgid "Send" msgstr "Envoyer" @@ -76,6 +82,24 @@ msgstr "Macro '%s' enregistrée dans le panneau de macros." msgid "Thinking…" msgstr "Réflexion en cours…" +msgid "Cumulative token usage" +msgstr "Utilisation cumulative des jetons" + +#, python-format +msgid "Prompt: %d" +msgstr "Invite : %d" + +#, python-format +msgid "Completion: %d" +msgstr "Complétion : %d" + +#, python-format +msgid "Total: %d" +msgstr "Total : %d" + +msgid "Stopping…" +msgstr "Arrêt en cours…" + #, python-brace-format msgid "" "\n" @@ -101,6 +125,9 @@ msgstr "Conversation réinitialisée." msgid "Tool execution cancelled by user." msgstr "Exécution de l'outil annulée par l'utilisateur." +msgid "Stopped by user." +msgstr "Arrêté par l'utilisateur." + #, python-format msgid "Error: %s" msgstr "Erreur : %s" @@ -133,6 +160,18 @@ msgstr "Charger" msgid "Delete" msgstr "Supprimer" +msgid "Rename" +msgstr "Renommer" + +msgid "Rename the selected conversation (F2)." +msgstr "Renommer la conversation sélectionnée (F2)." + +msgid "Export…" +msgstr "Exporter…" + +msgid "Save the selected conversation as a Markdown file." +msgstr "Enregistrer la conversation sélectionnée au format Markdown." + msgid "Refresh" msgstr "Actualiser" @@ -161,6 +200,28 @@ msgstr "Supprimer la conversation" msgid "Delete the selected conversation? This cannot be undone." msgstr "Supprimer la conversation sélectionnée ? Cette action est irréversible." +msgid "Rename conversation" +msgstr "Renommer la conversation" + +msgid "New title:" +msgstr "Nouveau titre :" + +msgid "Export failed" +msgstr "Échec de l'exportation" + +msgid "Could not load conversation: %s" +msgstr "Impossible de charger la conversation : %s" + +msgid "Export conversation" +msgstr "Exporter la conversation" + +msgid "Markdown files (*.md);;All files (*)" +msgstr "Fichiers Markdown (*.md);;Tous les fichiers (*)" + +#, python-format +msgid "Could not write file: %s" +msgstr "Impossible d'écrire le fichier : %s" + msgid "Enable AI Assistant" msgstr "Activer l'assistant IA" @@ -301,9 +362,6 @@ msgstr "Sélectionner les objets source" msgid "Select source object(s) used to create the selected %s" msgstr "Sélectionner le ou les objets source utilisés pour créer l'objet %s sélectionné" -msgid "Rename" -msgstr "Renommer" - #, python-format msgid "Edit title of selected %s or group" msgstr "Modifier le titre de l'objet %s ou du groupe sélectionné" @@ -1127,6 +1185,9 @@ msgstr "Console" msgid "Macro Panel" msgstr "Gestionnaire de Macros" +msgid "History Panel" +msgstr "Historique" + msgid "Disable auto-refresh?" msgstr "Désactiver le rafraîchissement automatique ?" @@ -1164,6 +1225,13 @@ msgstr "Ouvrir" msgid "HDF5 files (*.h5 *.hdf5 *.hdf *.he5);;All files (*)" msgstr "Fichiers HDF5 (*.h5 *.hdf5 *.hdf *.he5);;Tous les fichiers (*)" +#, python-format +msgid "Open %d HDF5 files" +msgstr "Ouvrir %d fichiers HDF5" + +msgid "Open HDF5 file" +msgstr "Ouvrir un fichier HDF5" + msgid "not started" msgstr "non démarré" @@ -1396,6 +1464,10 @@ msgstr "Modèle de valeur" msgid "Conversion" msgstr "Conversion" +#, python-format +msgid "Duplicate object or group" +msgstr "Dupliquer l'objet ou le groupe %s" + msgid "Select what to keep from the clipboard.

Result shapes and annotations, if kept, will be merged with existing ones. All other metadata will be replaced." msgstr "Sélectionnez ce que vous souhaitez conserver dans le presse-papier.

Les formes graphiques et les annotations, si conservées, seront fusionnées avec celles existantes. Toutes les autres métadonnées seront remplacées." @@ -1405,6 +1477,10 @@ msgstr "Supprimer le(s) groupe(s)" msgid "Are you sure you want to delete the selected group(s)?" msgstr "Êtes-vous sûr de vouloir supprimer le(s) groupe(s) sélectionné(s) ?" +#, python-format +msgid "Remove selected objects" +msgstr "Supprimer les objets sélectionnés" + #, python-format msgid "Do you want to delete all objects (%s)?" msgstr "Souhaitez-vous supprimer tous les objets (%s) ?" @@ -1421,6 +1497,14 @@ msgstr "Nouveau groupe" msgid "Group name:" msgstr "Nom du groupe :" +#, python-format +msgid "New group \"%s\"" +msgstr "Nouveau groupe \"%s\"" + +#, python-format +msgid "Rename selected object or group" +msgstr "Renommer l'objet ou le groupe sélectionné" + msgid "Rename object" msgstr "Renommer l'objet" @@ -1430,6 +1514,10 @@ msgstr "Nom de l'objet :" msgid "Rename group" msgstr "Renommer le groupe" +#, python-format +msgid "Set current object title to \"%s\"" +msgstr "Définir le titre de l'objet courant à \"%s\"" + msgid "Reading objects from file" msgstr "Lecture des objets depuis le fichier" @@ -1439,6 +1527,22 @@ msgstr "Ajout d'objets à l'espace de travail" msgid "Scanning directory" msgstr "Analyse du répertoire" +#, python-format +msgid "Load from %d files" +msgstr "Charger depuis %d fichiers" + +#, python-format +msgid "Load \"%s\"" +msgstr "Charger \"%s\"" + +#, python-format +msgid "Save to %d different files" +msgstr "Enregistrer dans %d fichiers différents" + +#, python-format +msgid "Save to \"%s\"" +msgstr "Enregistrer dans \"%s\"" + msgid "Save as" msgstr "Enregistrer sous" @@ -1520,12 +1624,60 @@ msgstr "Tous les objets associés aux résultats doivent avoir les mêmes ROIs p msgid "Are you sure you want to delete all results of the selected object(s)?" msgstr "Êtes-vous sûr de vouloir supprimer tous les résultats des objets sélectionnés ?" +msgid "Add object title to plot" +msgstr "Ajouter le titre de l'objet au graphique" + +msgid "Add label with title" +msgstr "Ajouter une étiquette avec le titre" + msgid "Annotation added" msgstr "Annotation ajoutée" msgid "The label has been added as an annotation. You can edit or remove it using the annotation editing window.

Choosing to ignore this message will prevent it from being displayed again." msgstr "L'étiquette a été ajoutée comme annotation. Vous pouvez la modifier ou la supprimer en utilisant la fenêtre d'édition des annotations.

Ignorer ce message empêchera son affichage ultérieur." +msgid "Session" +msgstr "Session" + +msgid "Date and time" +msgstr "Date et heure" + +msgid "Description" +msgstr "Description" + +msgid "Title" +msgstr "Titre" + +msgid "History panel" +msgstr "Panneau de l'historique" + +msgid "Edit mode" +msgstr "Mode d'édition" + +msgid "Record mode" +msgstr "Mode enregistrement" + +msgid "Replay" +msgstr "Rejouer" + +msgid "Restore selection" +msgstr "Restaurer la sélection" + +msgid "Restore selection and replay" +msgstr "Restaurer la sélection et rejouer" + +msgid "The current workspace state is not compatible with the action." +msgstr "L'état actuel de l'espace de travail n'est pas compatible avec l'action." + +msgid "Delete actions" +msgstr "Supprimer les actions" + +msgid "Do you really want to delete the selected action and all the next ones?" +msgstr "Voulez-vous vraiment supprimer l'action sélectionnée et toutes les suivantes ?" + +msgid "New image" +msgstr "Nouvelle image" + msgid "Macro panel" msgstr "Panneau des macros" @@ -1556,15 +1708,15 @@ msgstr "Supprimer la macro" msgid "Macro editor toolbar" msgstr "Barre d'outils des macros" -msgid "New title:" -msgstr "Nouveau titre :" - msgid "When closed, the macro is permanently destroyed, unless it has been exported first." msgstr "Lorsqu'elle est fermée, une macro est détruite de manière définitive, sauf si elle a été exportée au préalable." msgid "Do you want to continue?" msgstr "Souhaitez-vous vraiment continuer ?" +msgid "New signal" +msgstr "Nouveau signal" + msgid "Creating geometric shapes" msgstr "Création des formes géométriques" @@ -3312,9 +3464,6 @@ msgstr "Afficher le tableau" msgid "Path" msgstr "Chemin" -msgid "Description" -msgstr "Description" - msgid "Textual preview" msgstr "Aperçu textuel" @@ -3596,9 +3745,6 @@ msgstr "Tout sélectionner" msgid "Adding data to the plot" msgstr "Ajout des données au graphique" -msgid "Title" -msgstr "Titre" - msgid "X label" msgstr "Titre X" @@ -3739,4 +3885,3 @@ msgstr "Aucun contour n'a été trouvé pour la plage de niveaux sélectionnée. msgid "Show contour plot..." msgstr "Afficher le tracé de contours..." - diff --git a/datalab/tests/features/common/history_app_test.py b/datalab/tests/features/common/history_app_test.py new file mode 100644 index 000000000..ff43f27ed --- /dev/null +++ b/datalab/tests/features/common/history_app_test.py @@ -0,0 +1,39 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +""" +History application test +""" + +# pylint: disable=invalid-name # Allows short reference names like x, y, ... +# guitest: show + +import sigima.params +import sigima.proc.signal as sips +from qtpy import QtCore as QC +from sigima.tests.data import create_paracetamol_signal + +from datalab.env import execenv +from datalab.tests import datalab_test_app_context + + +def test_history_app(): + """Run history application test scenario""" + with datalab_test_app_context() as win: + dock = win.docks[win.historypanel] + win.addDockWidget(QC.Qt.LeftDockWidgetArea, dock) + win.resize(int(win.width() * 1.7), win.height()) + win.move(50, 50) + execenv.print("History application test:") + panel = win.signalpanel + sig = create_paracetamol_signal() + panel.add_object(sig) + panel.processor.run_feature(sips.derivative) + panel.processor.run_feature(sips.absolute) + panel.processor.run_feature(sips.log10) + param = sigima.params.NormalizeParam.create(method="energy") + panel.processor.run_feature(sips.normalize, param) + execenv.print("==> OK") + + +if __name__ == "__main__": + test_history_app() From 27acd38db7659d3dabd806e561bf33524f8bf2d3 Mon Sep 17 00:00:00 2001 From: Pierre Raybaut Date: Fri, 15 May 2026 09:59:53 +0200 Subject: [PATCH 003/108] fix(test): locate duplicate/result via group in geometry_results test After eba8385c, plot_results creates a "Results" group in the signal panel, breaking panel-wide index lookups. Use group-local lookups so the test is robust against extra groups. (cherry picked from commit 5e08f9caa1d18aef878c74008e00e2cfe2b9e483) (cherry picked from commit b2c49657cb58bebf41dbf2cb2ae2771c9a297c6d) --- .../features/common/geometry_results_app_test.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/datalab/tests/features/common/geometry_results_app_test.py b/datalab/tests/features/common/geometry_results_app_test.py index 9bd73d840..dc3cde07e 100644 --- a/datalab/tests/features/common/geometry_results_app_test.py +++ b/datalab/tests/features/common/geometry_results_app_test.py @@ -116,11 +116,20 @@ def test_geometry_results() -> None: with Conf.proc.keep_results.temp(keep_results): # Test merging result shapes (duplicate obj, then compute average): for panel in (win.signalpanel, win.imagepanel): - panel.objview.select_objects((2,)) + src_obj = panel[2] + group_id = panel.objmodel.get_object_group_id(src_obj) + panel.objview.select_objects([src_obj]) panel.duplicate_object() - panel.objview.select_objects((2, len(panel))) + # The duplicate is the last object of the source object's group + duplicate = panel.objmodel[ + panel.objmodel.get_group_object_ids(group_id)[-1] + ] + panel.objview.select_objects([src_obj, duplicate]) panel.processor.run_feature("average") - last_obj = panel[len(panel)] + # The average result is the last object of the source group + last_obj = panel.objmodel[ + panel.objmodel.get_group_object_ids(group_id)[-1] + ] if keep_results: __check_geometry_results_merge(panel[2], last_obj) if panel is win.imagepanel: From 95c420997f82d03440523e4e94f8569e450c5092 Mon Sep 17 00:00:00 2001 From: Pierre Raybaut Date: Fri, 15 May 2026 16:03:21 +0200 Subject: [PATCH 004/108] feat(history): add delete action and update menu state in history panel --- datalab/gui/panel/history.py | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/datalab/gui/panel/history.py b/datalab/gui/panel/history.py index a7b30505e..a8009c3e9 100644 --- a/datalab/gui/panel/history.py +++ b/datalab/gui/panel/history.py @@ -612,6 +612,7 @@ def __init__(self, parent: DLMainWindow) -> None: self.__record_mode = False self.__edit_mode = False + self.__delete_action: QW.QAction | None = None self.__menu_actions: list[QW.QAction] = self.__create_menu_actions() self.mainwindow = parent @@ -632,6 +633,12 @@ def __init__(self, parent: DLMainWindow) -> None: self.__history_sessions: list[HistorySession] = [] self.__session_increment = 0 + self.__update_actions_state() + + def __update_actions_state(self) -> None: + """Update the enabled state of menu actions depending on history content.""" + if self.__delete_action is not None: + self.__delete_action.setEnabled(len(self) > 0) def __create_menu_actions(self) -> list[QW.QAction]: """Create menu actions for the history panel @@ -653,6 +660,12 @@ def __create_menu_actions(self) -> list[QW.QAction]: icon=get_icon("record.svg"), ) record_action.setChecked(self.__record_mode) + self.__delete_action = create_action( + self, + _("Delete"), + self.delete_actions, + icon=get_icon("delete.svg"), + ) return [ record_action, None, @@ -678,12 +691,7 @@ def __create_menu_actions(self) -> list[QW.QAction]: ), edit_action, None, - create_action( - self, - _("Delete"), - self.delete_actions, - icon=get_icon("delete.svg"), - ), + self.__delete_action, ] def toggle_edit_mode(self, checked: bool) -> None: @@ -771,6 +779,7 @@ def delete_actions(self) -> None: if action in session.actions: session.remove_action(action) self.tree.populate_tree(self.__history_sessions) + self.__update_actions_state() def serialize_to_hdf5(self, writer: NativeH5Writer) -> None: """Serialize whole panel to a HDF5 file @@ -795,6 +804,7 @@ def deserialize_from_hdf5( if self.__history_sessions: self.__session_increment = self.__history_sessions[-1].number self.tree.populate_tree(self.__history_sessions) + self.__update_actions_state() def __len__(self) -> int: """Return number of objects""" @@ -870,7 +880,9 @@ def add_object(self, obj: HistoryAction) -> None: self.__history_sessions[-1].add_action(obj) self.tree.add_action_to_tree(obj) self.tree.rearrange_tree() + self.__update_actions_state() def remove_all_objects(self): """Remove all objects""" super().remove_all_objects() + self.__update_actions_state() From 3498eb6dfb1883c666879d94020bac2c3e083081 Mon Sep 17 00:00:00 2001 From: Pierre Raybaut Date: Fri, 15 May 2026 16:11:31 +0200 Subject: [PATCH 005/108] feat(history): add entry logging to history panel for compute operations --- datalab/gui/panel/history.py | 14 ++++++++++---- datalab/gui/processor/base.py | 26 ++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/datalab/gui/panel/history.py b/datalab/gui/panel/history.py index a8009c3e9..f31c1fa08 100644 --- a/datalab/gui/panel/history.py +++ b/datalab/gui/panel/history.py @@ -23,6 +23,7 @@ from datalab.config import _ from datalab.gui import ObjItf from datalab.gui.panel.base import AbstractPanel +from datalab.objectmodel import get_number if TYPE_CHECKING: from datalab.gui.main import DLMainWindow @@ -290,7 +291,8 @@ def get_current_selection(self, mainwindow: DLMainWindow) -> dict[str, list[int] selection: dict[str, list[int]] = {} for panel in (mainwindow.signalpanel, mainwindow.imagepanel): selection[panel.PANEL_STR] = [ - obj.number for obj in panel.objview.get_sel_objects(include_groups=True) + get_number(obj) + for obj in panel.objview.get_sel_objects(include_groups=True) ] return selection @@ -304,10 +306,12 @@ def save(self, mainwindow: DLMainWindow) -> None: for panel in (mainwindow.signalpanel, mainwindow.imagepanel): selection = self.selection[panel.PANEL_STR] self.states[panel.PANEL_STR] = [ - str(obj.data.shape) for obj in panel.objmodel if obj.number in selection + str(obj.data.shape) + for obj in panel.objmodel + if get_number(obj) in selection ] self.titles[panel.PANEL_STR] = [ - obj.title for obj in panel.objmodel if obj.number in selection + obj.title for obj in panel.objmodel if get_number(obj) in selection ] def is_current_state_compatible( @@ -337,7 +341,9 @@ def is_current_state_compatible( for panel in (mainwindow.signalpanel, mainwindow.imagepanel): numbers = selection[panel.PANEL_STR] current_states[panel.PANEL_STR] = [ - str(obj.data.shape) for obj in panel.objmodel if obj.number in numbers + str(obj.data.shape) + for obj in panel.objmodel + if get_number(obj) in numbers ] return current_states == self.states diff --git a/datalab/gui/processor/base.py b/datalab/gui/processor/base.py index 01bb384f7..e1618b618 100644 --- a/datalab/gui/processor/base.py +++ b/datalab/gui/processor/base.py @@ -1268,6 +1268,15 @@ def compute_1_to_1( if param is not None: if edit and not param.edit(parent=self.mainwindow): return + self.mainwindow.historypanel.add_entry( + title or func.__name__, + True, + self.compute_1_to_1, + func, + param=param, + title=title, + comment=comment, + ) self._compute_1_to_1_subroutine([func], [param], title) def compute_multiple_1_to_1( @@ -1306,6 +1315,14 @@ def compute_multiple_1_to_1( return if len(funcs) != len(params): raise ValueError("Number of functions must match number of parameters") + self.mainwindow.historypanel.add_entry( + title or "compute_multiple_1_to_1", + True, + self.compute_multiple_1_to_1, + funcs, + params=params, + title=title, + ) self._compute_1_to_1_subroutine(funcs, params, title) def compute_1_to_n( @@ -1404,6 +1421,15 @@ def compute_1_to_0( ) current_obj = self.panel.objview.get_current_object() title = func.__name__ if title is None else title + self.mainwindow.historypanel.add_entry( + title, + True, + self.compute_1_to_0, + func, + param=param, + title=title, + comment=comment, + ) refresh_needed = False with create_progress_bar(self.panel, title, max_=len(objs)) as progress: rdata = ResultData() From 9af626609fcc23dcba1157d45181f5e41eeacd38 Mon Sep 17 00:00:00 2001 From: Pierre Raybaut Date: Fri, 15 May 2026 16:20:22 +0200 Subject: [PATCH 006/108] test(history): enhance history application tests with comprehensive scenarios --- .../tests/features/common/history_app_test.py | 154 +++++++++++++++++- 1 file changed, 148 insertions(+), 6 deletions(-) diff --git a/datalab/tests/features/common/history_app_test.py b/datalab/tests/features/common/history_app_test.py index ff43f27ed..32b6047d0 100644 --- a/datalab/tests/features/common/history_app_test.py +++ b/datalab/tests/features/common/history_app_test.py @@ -2,6 +2,17 @@ """ History application test + +Exercises the History panel's full feature set: + +* Record-mode toggle gating +* Entry recording for object creation, 1-to-1, 1-to-0, n-to-1 and 2-to-1 + processing patterns (covering ``BaseProcessor.compute_*`` and + ``BaseDataPanel`` history-emitting methods) +* Workspace state attached to processing entries +* Session creation and session-aware indexing +* Replay of a recorded action +* Action deletion (cascade within a session) """ # pylint: disable=invalid-name # Allows short reference names like x, y, ... @@ -13,25 +24,156 @@ from sigima.tests.data import create_paracetamol_signal from datalab.env import execenv +from datalab.gui.panel.history import HistoryAction, HistorySession, WorkspaceState from datalab.tests import datalab_test_app_context +def _entry_titles(history) -> list[str]: + """Return the list of recorded entry titles, in chronological order.""" + return [action.title for action in history] + + def test_history_app(): """Run history application test scenario""" with datalab_test_app_context() as win: - dock = win.docks[win.historypanel] + history = win.historypanel + dock = win.docks[history] win.addDockWidget(QC.Qt.LeftDockWidgetArea, dock) win.resize(int(win.width() * 1.7), win.height()) win.move(50, 50) execenv.print("History application test:") + panel = win.signalpanel - sig = create_paracetamol_signal() - panel.add_object(sig) + + # --- Record mode is OFF by default: nothing should be recorded --------- + assert len(history) == 0 + panel.add_object(create_paracetamol_signal()) + panel.processor.run_feature(sips.derivative) + assert len(history) == 0, ( + "Record mode is disabled: no entry should have been recorded" + ) + + # Reset workspace before starting the recorded scenario + # (this also clears the history panel) + win.reset_all() + assert len(history) == 0 + + # --- Enable record mode and start recording ---------------------------- + history.toggle_record_mode(True) + + # Pre-populate two real signals (``add_object`` does not record entries). + panel.add_object(create_paracetamol_signal()) + panel.add_object(create_paracetamol_signal()) + assert len(history) == 0 + + # 1) Object creation through the GUI path (BaseDataPanel.new_object): + # save_state=False, no workspace state is captured. + panel.new_object() + assert len(history) == 1 + creation_entry = history[1] + assert isinstance(creation_entry, HistoryAction) + assert creation_entry.title == "New signal" + assert creation_entry.state.selection == {} + assert creation_entry.state.states == {} + + # 2) 1-to-1 processing (compute_1_to_1) on signal #1: save_state=True + panel.objview.select_objects([1]) panel.processor.run_feature(sips.derivative) + assert len(history) == 2 + deriv_entry = history[2] + assert deriv_entry.title # title must be non-empty + # Workspace state must remember the single-object selection + assert deriv_entry.state.selection.get(panel.PANEL_STR) == [1] + assert len(deriv_entry.state.states.get(panel.PANEL_STR, [])) == 1 + + # 3) 1-to-1 with parameters (compute_1_to_1 + DataSet param) + norm_param = sigima.params.NormalizeParam.create(method="maximum") + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.normalize, norm_param) + assert len(history) == 3 + norm_entry = history[3] + # The recorded kwargs must include the parameter (used in description) + assert any(k.endswith("param") for k in norm_entry.kwargs) + assert norm_entry.description # description is built from the param + + # 4) 1-to-0 analysis (compute_1_to_0) + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.fwhm, sigima.params.FWHMParam()) + assert len(history) == 4 + fwhm_entry = history[4] + assert fwhm_entry.state.selection.get(panel.PANEL_STR) == [1] + + # 5) n-to-1 aggregation (compute_n_to_1) on signals #1 and #2 + panel.objview.select_objects([1, 2]) + panel.processor.run_feature(sips.average) + assert len(history) == 5 + avg_entry = history[5] + assert sorted(avg_entry.state.selection.get(panel.PANEL_STR, [])) == [1, 2] + + # 6) 2-to-1 binary operation (compute_2_to_1) + obj2 = panel.objmodel.get_object_from_number(2) + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.difference, obj2) + assert len(history) == 6 + diff_entry = history[6] + assert diff_entry.state.selection.get(panel.PANEL_STR) == [1] + + # --- Iteration / indexing API ------------------------------------------ + all_titles = _entry_titles(history) + assert len(all_titles) == 6 + assert all_titles[0] == "New signal" + # Indexing is 1-based; iteration order matches index order + assert history[1] is creation_entry + assert history[6] is diff_entry + + # --- Sessions ---------------------------------------------------------- + history.create_new_session() + # New session does not change the action count + assert len(history) == 6 + before = len(history) + panel.objview.select_objects([1]) panel.processor.run_feature(sips.absolute) - panel.processor.run_feature(sips.log10) - param = sigima.params.NormalizeParam.create(method="energy") - panel.processor.run_feature(sips.normalize, param) + after = len(history) + assert after == before + 1 + new_session_entry = history[after] + assert new_session_entry.title + + # --- Replay ------------------------------------------------------------ + # Replaying the derivative entry must produce a new object without raising. + n_objects_before_replay = len(panel.objmodel) + deriv_entry.replay(win, restore_selection=True, edit=False) + assert len(panel.objmodel) > n_objects_before_replay + + # --- Record mode OFF stops further recording --------------------------- + count_before_off = len(history) + history.toggle_record_mode(False) + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.absolute) + assert len(history) == count_before_off, ( + "Record mode disabled: subsequent operations must not be recorded" + ) + + # --- Workspace state types are well-formed ----------------------------- + for action in history: + assert isinstance(action, HistoryAction) + assert isinstance(action.state, WorkspaceState) + assert isinstance(action.title, str) + assert isinstance(action.dtstr, str) and action.dtstr + + # --- Delete cascade within a session ----------------------------------- + # ``delete_actions`` itself opens a confirmation dialog; we exercise the + # underlying ``HistorySession.remove_action`` path used by it. + target = new_session_entry + target_session: HistorySession | None = None + for session in history._HistoryPanel__history_sessions: # noqa: SLF001 + if target in session.actions: + target_session = session + break + assert target_session is not None + n_before = len(history) + target_session.remove_action(target) + assert len(history) < n_before + execenv.print("==> OK") From 4b0ebd07aba567aebb050d30e083933a580580e6 Mon Sep 17 00:00:00 2001 From: Pierre Raybaut Date: Fri, 15 May 2026 16:42:20 +0200 Subject: [PATCH 007/108] feat(history): enhance history panel with collapsible description widget and HTML rendering --- datalab/gui/panel/history.py | 207 +++++++++++++++++++++-- datalab/locale/fr/LC_MESSAGES/datalab.po | 10 +- 2 files changed, 204 insertions(+), 13 deletions(-) diff --git a/datalab/gui/panel/history.py b/datalab/gui/panel/history.py index f31c1fa08..326d6324b 100644 --- a/datalab/gui/panel/history.py +++ b/datalab/gui/panel/history.py @@ -9,12 +9,14 @@ from __future__ import annotations import functools +import html import inspect import os from typing import TYPE_CHECKING, Any, Callable, Generator from uuid import uuid4 from guidata.configtools import get_icon +from guidata.dataset.datatypes import DataSet from guidata.qthelpers import add_actions, create_action from guidata.widgets.dockable import DockableWidgetMixin from qtpy import QtCore as QC @@ -131,19 +133,23 @@ def title(self) -> str: """Return object title""" return self.__title + def __iter_param_kwargs(self) -> Generator[Any, None, None]: + """Yield kwargs values whose name ends with ``param`` (typically DataSets).""" + for kwname in self.kwargs: + if kwname.endswith("param"): + # Note: value can't be None (None values were filtered in __init__) + yield self.kwargs[kwname] + @property def description(self) -> str: """Return object description (string representing function parameters)""" desc = "" no_parameters = True - for kwname in self.kwargs: - if kwname.endswith("param"): - param = self.kwargs[kwname] - # Note: `param` can't be None because we removed None values from kwargs - if desc: - desc += os.linesep - desc += str(param) - no_parameters = False + for param in self.__iter_param_kwargs(): + if desc: + desc += os.linesep + desc += str(param) + no_parameters = False if desc or no_parameters: return desc if len(self.args) >= 2 and isinstance(self.args[1], Callable): @@ -151,6 +157,52 @@ def description(self) -> str: return doc.splitlines()[0] if doc else "" return self.func.__doc__ or "" + @property + def description_summary(self) -> str: + """Return a short, single-line summary of the description (collapsed view). + + For DataSet parameters, uses the dataset titles; otherwise falls back to + the first non-empty line of the full description. + """ + titles: list[str] = [] + for param in self.__iter_param_kwargs(): + if isinstance(param, DataSet): + title = param.get_title() + if title: + titles.append(title) + if titles: + return ", ".join(titles) + for line in self.description.splitlines(): + stripped = line.strip() + if stripped: + return stripped + return "" + + @property + def description_html(self) -> str: + """Return rich-text (HTML) description used for the expanded view. + + For DataSet parameters, delegates to :meth:`DataSet.to_html` to mirror + the *Properties* tab rendering; otherwise returns the plain description + wrapped in HTML-safe ``
``-separated lines. + """ + parts: list[str] = [] + no_parameters = True + for param in self.__iter_param_kwargs(): + no_parameters = False + if isinstance(param, DataSet): + parts.append(param.to_html()) + else: + parts.append(html.escape(str(param)).replace("\n", "
")) + if parts: + return "

".join(parts) + if no_parameters: + text = self.description + if not text: + return "" + return html.escape(text).replace("\n", "
") + return "" + def is_current_state_compatible( self, mainwindow: DLMainWindow, restore_selection: bool ) -> bool: @@ -484,15 +536,131 @@ def remove_action(self, action: HistoryAction) -> None: self.actions = self.actions[:index] +class CollapsibleDescriptionWidget(QW.QWidget): + """Compact, expandable cell widget for the history Description column. + + Shows a single-line summary by default; a chevron toggle reveals the full + HTML description (mirroring the *Properties* tab rendering). + """ + + toggled = QC.Signal(bool) + + def __init__( + self, + summary: str, + html_text: str, + expanded: bool = False, + parent: QW.QWidget | None = None, + ) -> None: + super().__init__(parent) + self._summary = summary + self._html = html_text + self._expanded = expanded + + self._toggle = QW.QToolButton(self) + self._toggle.setAutoRaise(True) + self._toggle.setCheckable(True) + self._toggle.setFocusPolicy(QC.Qt.NoFocus) + self._toggle.setArrowType(QC.Qt.RightArrow) + self._toggle.setToolTip(_("Show details")) + + self._label = QW.QLabel(self) + self._label.setTextFormat(QC.Qt.RichText) + self._label.setWordWrap(True) + self._label.setTextInteractionFlags(QC.Qt.TextSelectableByMouse) + self._label.setAlignment(QC.Qt.AlignTop | QC.Qt.AlignLeft) + + layout = QW.QHBoxLayout(self) + layout.setContentsMargins(0, 0, 0, 0) + layout.setSpacing(2) + layout.addWidget(self._toggle, 0, QC.Qt.AlignTop) + layout.addWidget(self._label, 1) + + # Hide the toggle when there is nothing more to show than the summary. + if not self._html or self._html_matches_summary(): + self._toggle.setVisible(False) + + self._toggle.toggled.connect(self._on_toggled) + self._refresh() + + def _html_matches_summary(self) -> bool: + """Return True when the HTML rendering would not add information.""" + return self._html.strip() == html.escape(self._summary).strip() + + def _on_toggled(self, checked: bool) -> None: + self._expanded = checked + self._refresh() + self.toggled.emit(checked) + + def _refresh(self) -> None: + if self._expanded: + self._toggle.setArrowType(QC.Qt.DownArrow) + self._toggle.setToolTip(_("Hide details")) + self._label.setText(self._html or html.escape(self._summary)) + else: + self._toggle.setArrowType(QC.Qt.RightArrow) + self._toggle.setToolTip(_("Show details")) + self._label.setText(html.escape(self._summary)) + self.updateGeometry() + + def is_expanded(self) -> bool: + """Return current expanded state.""" + return self._expanded + + def set_expanded(self, expanded: bool) -> None: + """Programmatically set the expanded state.""" + if expanded == self._expanded: + return + self._toggle.setChecked(expanded) + + class HistoryTree(QW.QTreeWidget): """Tree widget for the history panel""" + DESCRIPTION_COLUMN = 2 + def __init__(self, parent: QW.QWidget) -> None: """Create a new history tree widget""" super().__init__(parent) self.setHeaderLabels([_("Title"), _("Date and time"), _("Description")]) self.setContextMenuPolicy(QC.Qt.CustomContextMenu) self.setSelectionMode(QW.QAbstractItemView.ContiguousSelection) + self.setUniformRowHeights(False) + header = self.header() + header.setSectionResizeMode(self.DESCRIPTION_COLUMN, QW.QHeaderView.Stretch) + # Per-action expanded state, preserved across repopulate (delete/replay). + self.__expanded_state: dict[str, bool] = {} + + def __on_description_toggled(self, uuid: str, expanded: bool) -> None: + """Remember the expanded state of a description cell.""" + self.__expanded_state[uuid] = expanded + # Force the tree to recompute row heights now that the label content + # has changed. + self.scheduleDelayedItemsLayout() + + def __install_description_widget( + self, item: QW.QTreeWidgetItem, action: HistoryAction + ) -> None: + """Attach the collapsible description widget to ``item`` (column 2). + + The item must already be inserted in the tree before calling this. + """ + expanded = self.__expanded_state.get(action.uuid, False) + widget = CollapsibleDescriptionWidget( + action.description_summary, + action.description_html, + expanded=expanded, + parent=self, + ) + widget.toggled.connect( + lambda checked, uuid=action.uuid: self.__on_description_toggled( + uuid, checked + ) + ) + # Clear any text the item may carry for that column to avoid double + # rendering behind the widget. + item.setText(self.DESCRIPTION_COLUMN, "") + self.setItemWidget(item, self.DESCRIPTION_COLUMN, widget) @staticmethod def action_to_tree_item(action: HistoryAction) -> QW.QTreeWidgetItem: @@ -504,22 +672,40 @@ def action_to_tree_item(action: HistoryAction) -> QW.QTreeWidgetItem: Returns: QW.QTreeWidgetItem: Tree item """ - item = QW.QTreeWidgetItem([action.title, action.dtstr, action.description]) + # Description column is left empty: a CollapsibleDescriptionWidget is + # installed by ``HistoryTree`` once the item is inserted in the tree. + item = QW.QTreeWidgetItem([action.title, action.dtstr, ""]) item.setData(0, QC.Qt.UserRole, action.uuid) return item + def __forget_orphan_expanded_states( + self, history_sessions: list[HistorySession] + ) -> None: + """Drop expanded-state entries for actions that no longer exist.""" + live_uuids = { + action.uuid for session in history_sessions for action in session.actions + } + self.__expanded_state = { + uuid: state + for uuid, state in self.__expanded_state.items() + if uuid in live_uuids + } + def populate_tree(self, history_sessions: list[HistorySession]) -> None: """Populate the history tree widget Args: history_sessions: List of history sessions """ + self.__forget_orphan_expanded_states(history_sessions) self.clear() for session in history_sessions: ritem = QW.QTreeWidgetItem([session.title, session.dtstr]) self.addTopLevelItem(ritem) for action in session.actions: - ritem.addChild(self.action_to_tree_item(action)) + child = self.action_to_tree_item(action) + ritem.addChild(child) + self.__install_description_widget(child, action) self.expandAll() for col in (0, 1): self.resizeColumnToContents(col) @@ -539,6 +725,7 @@ def add_action_to_tree(self, action: HistoryAction) -> None: item = self.action_to_tree_item(action) ritem = self.topLevelItem(self.topLevelItemCount() - 1) ritem.addChild(item) + self.__install_description_widget(item, action) def get_action_from_uuid( self, uuid: str, history_sessions: list[HistorySession] diff --git a/datalab/locale/fr/LC_MESSAGES/datalab.po b/datalab/locale/fr/LC_MESSAGES/datalab.po index 1378ff0d8..374dd39f5 100644 --- a/datalab/locale/fr/LC_MESSAGES/datalab.po +++ b/datalab/locale/fr/LC_MESSAGES/datalab.po @@ -209,6 +209,7 @@ msgstr "Nouveau titre :" msgid "Export failed" msgstr "Échec de l'exportation" +#, python-format msgid "Could not load conversation: %s" msgstr "Impossible de charger la conversation : %s" @@ -1464,7 +1465,6 @@ msgstr "Modèle de valeur" msgid "Conversion" msgstr "Conversion" -#, python-format msgid "Duplicate object or group" msgstr "Dupliquer l'objet ou le groupe %s" @@ -1477,7 +1477,6 @@ msgstr "Supprimer le(s) groupe(s)" msgid "Are you sure you want to delete the selected group(s)?" msgstr "Êtes-vous sûr de vouloir supprimer le(s) groupe(s) sélectionné(s) ?" -#, python-format msgid "Remove selected objects" msgstr "Supprimer les objets sélectionnés" @@ -1501,7 +1500,6 @@ msgstr "Nom du groupe :" msgid "New group \"%s\"" msgstr "Nouveau groupe \"%s\"" -#, python-format msgid "Rename selected object or group" msgstr "Renommer l'objet ou le groupe sélectionné" @@ -1639,6 +1637,12 @@ msgstr "L'étiquette a été ajoutée comme annotation. Vous pouvez la modifier msgid "Session" msgstr "Session" +msgid "Show details" +msgstr "Afficher les détails" + +msgid "Hide details" +msgstr "Masquer les détails" + msgid "Date and time" msgstr "Date et heure" From d5a7bba6c4656cae0e47368ded3d4fa3b94f6e0f Mon Sep 17 00:00:00 2001 From: Pierre Raybaut Date: Fri, 15 May 2026 17:13:54 +0200 Subject: [PATCH 008/108] feat(history): implement UUID-based selection tracking in history panel and related components --- datalab/gui/panel/base.py | 34 +++-- datalab/gui/panel/history.py | 135 ++++++++++-------- datalab/gui/processor/base.py | 8 +- .../tests/features/common/history_app_test.py | 17 ++- 4 files changed, 114 insertions(+), 80 deletions(-) diff --git a/datalab/gui/panel/base.py b/datalab/gui/panel/base.py index b24c523ed..665e778e2 100644 --- a/datalab/gui/panel/base.py +++ b/datalab/gui/panel/base.py @@ -2596,16 +2596,19 @@ def properties_changed(self) -> None: # Get only the properties that have changed from the original values changed_props = self.objprop.get_changed_properties() - # Apply only the changed properties to all selected objects - for obj in self.objview.get_sel_objects(include_groups=True): - obj.mark_roi_as_changed() - # Update only the changed properties instead of all properties - update_dataset(obj, changed_props) - self.objview.update_item(get_uuid(obj)) + # Apply only the changed properties to all selected objects. + # The ``replaying()`` guard suppresses the synthetic history entries + # that the auto-recompute below would otherwise create for each object. + with self.mainwindow.historypanel.replaying(): + for obj in self.objview.get_sel_objects(include_groups=True): + obj.mark_roi_as_changed() + # Update only the changed properties instead of all properties + update_dataset(obj, changed_props) + self.objview.update_item(get_uuid(obj)) - # Auto-recompute analysis if the object had analysis parameters - # Since properties have changed, any analysis results may now be invalid - self.processor.auto_recompute_analysis(obj) + # Auto-recompute analysis if the object had analysis parameters + # Since properties have changed, any analysis results may now be invalid + self.processor.auto_recompute_analysis(obj) # Refresh all selected items, including non-visible ones (only_visible=False) # This ensures that plot items are updated for all selected objects, even if @@ -2649,10 +2652,15 @@ def recompute_processing(self) -> None: ) return - # Recompute each object - with create_progress_bar( - self, _("Recomputing objects"), max_=len(recomputable_objects) - ) as progress: + # Recompute each object -- silence history capture while doing so: + # the underlying compute_* methods would otherwise re-register + # synthetic entries for every recomputed object. + with ( + self.mainwindow.historypanel.replaying(), + create_progress_bar( + self, _("Recomputing objects"), max_=len(recomputable_objects) + ) as progress, + ): for index, obj in enumerate(recomputable_objects): progress.setValue(index + 1) QW.QApplication.processEvents() diff --git a/datalab/gui/panel/history.py b/datalab/gui/panel/history.py index 326d6324b..57ee3a598 100644 --- a/datalab/gui/panel/history.py +++ b/datalab/gui/panel/history.py @@ -12,6 +12,7 @@ import html import inspect import os +from contextlib import contextmanager from typing import TYPE_CHECKING, Any, Callable, Generator from uuid import uuid4 @@ -25,7 +26,7 @@ from datalab.config import _ from datalab.gui import ObjItf from datalab.gui.panel.base import AbstractPanel -from datalab.objectmodel import get_number +from datalab.objectmodel import get_uuid if TYPE_CHECKING: from datalab.gui.main import DLMainWindow @@ -281,24 +282,21 @@ def deserialize(self, reader: NativeH5Reader) -> None: class WorkspaceState: """Object representing the workspace state at a given time. - The workspace state is the state of the workspace at a given time. It contains - the list of objects in the workspace and the selection of objects. Instead of - storing the objects themselves, the workspace state only stores what is relevant - to the history panel, i.e. the object data shape and the object title (even - if the latter is purely informative). + The workspace state stores the per-panel selection of objects by **UUID** + (robust against reordering, renaming or interleaved insertions). For + informative display, it also retains the data shape and title of each + selected object at the time of capture. """ def __init__(self) -> None: """Create a new workspace state""" # The selection is stored as a dictionary where the key is the panel name - # and the value is the list of selected object numbers (1 to N). - self.selection: dict[str, list[int]] = {} + # and the value is the list of UUIDs of selected objects. + self.selection: dict[str, list[str]] = {} # The states are stored as a dictionary where the key is the panel name # and the value is the list of states (str) of the objects in the panel. The - # state is a string containing the object data shape (for now, only the shape, - # but we could add more information if needed). The idea is that two objects - # have the same state, we can apply the same action (processing, operation, ...) - # to both objects. + # state is a string containing the object data shape (kept for informative + # display only -- not used for selection matching anymore). self.states: dict[str, list[str]] = {} # The titles are stored as a dictionary where the key is the panel name and the # value is the list of titles of the objects in the panel. The title is only @@ -331,19 +329,20 @@ def deserialize(self, reader: NativeH5Reader) -> None: with reader.group("titles"): self.titles = reader.read_dict() - def get_current_selection(self, mainwindow: DLMainWindow) -> dict[str, list[int]]: - """Get the current selection in the workspace + def get_current_selection(self, mainwindow: DLMainWindow) -> dict[str, list[str]]: + """Get the current selection in the workspace, keyed by panel name and + valued by the list of selected object UUIDs. Args: mainwindow: DataLab's main window Returns: - dict[str, list[int]]: Current selection in the workspace + Current selection in the workspace, by panel name → list of UUIDs. """ - selection: dict[str, list[int]] = {} + selection: dict[str, list[str]] = {} for panel in (mainwindow.signalpanel, mainwindow.imagepanel): selection[panel.PANEL_STR] = [ - get_number(obj) + get_uuid(obj) for obj in panel.objview.get_sel_objects(include_groups=True) ] return selection @@ -356,73 +355,65 @@ def save(self, mainwindow: DLMainWindow) -> None: """ self.selection = self.get_current_selection(mainwindow) for panel in (mainwindow.signalpanel, mainwindow.imagepanel): - selection = self.selection[panel.PANEL_STR] + sel_uuids = self.selection[panel.PANEL_STR] self.states[panel.PANEL_STR] = [ str(obj.data.shape) for obj in panel.objmodel - if get_number(obj) in selection + if get_uuid(obj) in sel_uuids ] self.titles[panel.PANEL_STR] = [ - obj.title for obj in panel.objmodel if get_number(obj) in selection + obj.title for obj in panel.objmodel if get_uuid(obj) in sel_uuids ] def is_current_state_compatible( self, mainwindow: DLMainWindow, restore_selection: bool ) -> bool: - """Check if the current workspace state is compatible with the saved state + """Check if the current workspace state is compatible with the saved state. + + Compatibility means that **every** UUID recorded in the saved selection + still exists in the corresponding panel. The data shape is no longer + used to discriminate (it is informative only): a missing UUID is the + only failure mode. Args: mainwindow: DataLab's main window - restore_selection: True to restore the selection before checking the state + restore_selection: Unused (kept for API symmetry). With UUID-based + identity, the compatibility check no longer depends on the current + selection -- it only depends on object existence. Returns: - bool: True if the current workspace state is compatible with the saved state + True if every saved UUID still exists in its panel, False otherwise. """ - # A compatible state is a state where the selected objects are the same as the - # saved selected objects in terms of position in the list of objects and of - # data shape (title is not relevant). - # To check this, we have to try to restore the selection (without restoring it) - # and compare the current selection with the saved selection in terms of - # position in the list of objects and of data shape. - if self.states == {}: + if not self.selection: return True - current_states: dict[str, list[str]] = {} - selection = self.selection - if not restore_selection: - selection = self.get_current_selection(mainwindow) for panel in (mainwindow.signalpanel, mainwindow.imagepanel): - numbers = selection[panel.PANEL_STR] - current_states[panel.PANEL_STR] = [ - str(obj.data.shape) - for obj in panel.objmodel - if get_number(obj) in numbers - ] - return current_states == self.states + saved_uuids = self.selection.get(panel.PANEL_STR, []) + existing_uuids = set(panel.objmodel.get_object_ids()) + for uuid in saved_uuids: + if uuid not in existing_uuids: + return False + return True def restore(self, mainwindow: DLMainWindow) -> None: - """Restore the workspace state - - Only the selection is restored, not the objects themselves because they are - not stored in the workspace state. Before restoring the selection, we may - check if the current workspace objects are compatible with the saved - workspace state. If not, we raise a `ValueError`. + """Restore the workspace state by selecting the recorded UUIDs. Args: mainwindow: DataLab's main window Raises: - ValueError: If the current workspace state is not compatible with the - saved state + ValueError: If at least one of the saved UUIDs no longer exists in + its panel. """ - if self.selection == {}: + if not self.selection: return if not self.is_current_state_compatible(mainwindow, False): raise ValueError( "Current workspace state is not compatible with saved state" ) for panel in (mainwindow.signalpanel, mainwindow.imagepanel): - numbers = self.selection[panel.PANEL_STR] - panel.objview.select_objects(numbers) + uuids = self.selection.get(panel.PANEL_STR, []) + if uuids: + panel.objview.select_objects(uuids) class HistorySession: @@ -795,7 +786,7 @@ class HistoryPanel(AbstractPanel, DockableWidgetMixin): SIG_OBJECT_MODIFIED = QC.Signal() - FILE_FILTERS = f"{_('History files')} (*.cdlhist)" + FILE_FILTERS = f"{_('History files')} (*.dlhist)" def __init__(self, parent: DLMainWindow) -> None: super().__init__(parent) @@ -805,6 +796,11 @@ def __init__(self, parent: DLMainWindow) -> None: self.__record_mode = False self.__edit_mode = False + # When `__replaying` is True, calls to `add_entry` are silently + # ignored. This prevents replay/recompute paths from polluting the + # history with synthetic entries triggered by their own internal + # `compute_*` calls. Use `replaying()` as a context manager. + self.__replaying = False self.__delete_action: QW.QAction | None = None self.__menu_actions: list[QW.QAction] = self.__create_menu_actions() @@ -903,6 +899,26 @@ def toggle_record_mode(self, checked: bool) -> None: """ self.__record_mode = checked + @contextmanager + def replaying(self) -> Generator[None, None, None]: + """Context manager suppressing history capture during its scope. + + Used by replay / recompute paths to avoid double-capture: the + generic ``compute_*`` methods of the processor would otherwise + register synthetic entries every time recompute or replay + triggers them. + """ + previous = self.__replaying + self.__replaying = True + try: + yield + finally: + self.__replaying = previous + + def is_replaying(self) -> bool: + """Return True when an external replay/recompute is in progress.""" + return self.__replaying + def show_context_menu(self, pos: QC.QPoint) -> None: """Show the context menu @@ -945,11 +961,12 @@ def replay_restore_actions( ) return if replay: - session_or_action.replay( - self.mainwindow, - restore_selection=restore_selection, - edit=self.__edit_mode, - ) + with self.replaying(): + session_or_action.replay( + self.mainwindow, + restore_selection=restore_selection, + edit=self.__edit_mode, + ) elif restore_selection: session_or_action.restore(self.mainwindow) @@ -1051,7 +1068,7 @@ def add_entry( assert isinstance(action_title, str), "action_title must be a string" assert isinstance(save_state, bool), "save_state must be a boolean" assert callable(func), "func must be callable" - if not self.__record_mode: + if not self.__record_mode or self.__replaying: return if save_state: state = WorkspaceState() diff --git a/datalab/gui/processor/base.py b/datalab/gui/processor/base.py index e1618b618..e8d12ea88 100644 --- a/datalab/gui/processor/base.py +++ b/datalab/gui/processor/base.py @@ -993,8 +993,12 @@ def auto_recompute_analysis( feature = self.get_feature(proc_params.func_name) # Recompute the analysis operation silently, only for this specific object - # (not all selected objects, to avoid O(n²) behavior when called in a loop) - with Conf.proc.show_result_dialog.temp(False): + # (not all selected objects, to avoid O(n²) behavior when called in a loop). + # The history-panel ``replaying()`` guard suppresses the synthetic entry + # that ``compute_1_to_0`` would otherwise add for this internally-triggered + # recomputation. + historypanel = self.panel.mainwindow.historypanel + with historypanel.replaying(), Conf.proc.show_result_dialog.temp(False): self.compute_1_to_0(feature.function, param, edit=False, target_objs=[obj]) # Update the view diff --git a/datalab/tests/features/common/history_app_test.py b/datalab/tests/features/common/history_app_test.py index 32b6047d0..98089055e 100644 --- a/datalab/tests/features/common/history_app_test.py +++ b/datalab/tests/features/common/history_app_test.py @@ -25,6 +25,7 @@ from datalab.env import execenv from datalab.gui.panel.history import HistoryAction, HistorySession, WorkspaceState +from datalab.objectmodel import get_uuid from datalab.tests import datalab_test_app_context @@ -78,12 +79,13 @@ def test_history_app(): # 2) 1-to-1 processing (compute_1_to_1) on signal #1: save_state=True panel.objview.select_objects([1]) + obj1_uuid = get_uuid(panel.objmodel.get_object_from_number(1)) panel.processor.run_feature(sips.derivative) assert len(history) == 2 deriv_entry = history[2] assert deriv_entry.title # title must be non-empty - # Workspace state must remember the single-object selection - assert deriv_entry.state.selection.get(panel.PANEL_STR) == [1] + # Workspace state must remember the single-object selection (by UUID) + assert deriv_entry.state.selection.get(panel.PANEL_STR) == [obj1_uuid] assert len(deriv_entry.state.states.get(panel.PANEL_STR, [])) == 1 # 3) 1-to-1 with parameters (compute_1_to_1 + DataSet param) @@ -101,22 +103,25 @@ def test_history_app(): panel.processor.run_feature(sips.fwhm, sigima.params.FWHMParam()) assert len(history) == 4 fwhm_entry = history[4] - assert fwhm_entry.state.selection.get(panel.PANEL_STR) == [1] + assert fwhm_entry.state.selection.get(panel.PANEL_STR) == [obj1_uuid] # 5) n-to-1 aggregation (compute_n_to_1) on signals #1 and #2 + obj2 = panel.objmodel.get_object_from_number(2) + obj2_uuid = get_uuid(obj2) panel.objview.select_objects([1, 2]) panel.processor.run_feature(sips.average) assert len(history) == 5 avg_entry = history[5] - assert sorted(avg_entry.state.selection.get(panel.PANEL_STR, [])) == [1, 2] + assert sorted(avg_entry.state.selection.get(panel.PANEL_STR, [])) == sorted( + [obj1_uuid, obj2_uuid] + ) # 6) 2-to-1 binary operation (compute_2_to_1) - obj2 = panel.objmodel.get_object_from_number(2) panel.objview.select_objects([1]) panel.processor.run_feature(sips.difference, obj2) assert len(history) == 6 diff_entry = history[6] - assert diff_entry.state.selection.get(panel.PANEL_STR) == [1] + assert diff_entry.state.selection.get(panel.PANEL_STR) == [obj1_uuid] # --- Iteration / indexing API ------------------------------------------ all_titles = _entry_titles(history) From 568f6425d2411f62683a5d73e015e348c24d26b8 Mon Sep 17 00:00:00 2001 From: Pierre Raybaut Date: Fri, 15 May 2026 18:59:26 +0200 Subject: [PATCH 009/108] refactor(history): drop pickled Callable, type entries by kind --- datalab/gui/main.py | 15 +- datalab/gui/panel/base.py | 79 +++-- datalab/gui/panel/history.py | 530 ++++++++++++++++++++++++++-------- datalab/gui/panel/image.py | 7 +- datalab/gui/panel/signal.py | 7 +- datalab/gui/processor/base.py | 87 +++--- 6 files changed, 509 insertions(+), 216 deletions(-) diff --git a/datalab/gui/main.py b/datalab/gui/main.py index c798a4e7d..cb579a769 100644 --- a/datalab/gui/main.py +++ b/datalab/gui/main.py @@ -2062,8 +2062,12 @@ def save_to_h5_file(self, filename=None) -> None: ) if not filename: return - self.historypanel.add_entry( - _("Save to HDF5 file"), False, self.save_to_h5_file, filename=filename + self.historypanel.add_ui_entry( + _("Save to HDF5 file"), + target="mainwindow", + method_name="save_to_h5_file", + save_state=False, + filename=filename, ) with qth.qt_try_loadsave_file(self, filename, "save"): self.save_h5_workspace(filename) @@ -2141,10 +2145,11 @@ def open_h5_files( entry_title = _("Open %d HDF5 files") % len(h5files) else: entry_title = _("Open HDF5 file") - self.historypanel.add_entry( + self.historypanel.add_ui_entry( entry_title, - False, - self.open_h5_files, + target="mainwindow", + method_name="open_h5_files", + save_state=False, h5files=h5files, import_all=import_all, reset_all=reset_all, diff --git a/datalab/gui/panel/base.py b/datalab/gui/panel/base.py index 665e778e2..4e960467a 100644 --- a/datalab/gui/panel/base.py +++ b/datalab/gui/panel/base.py @@ -1718,8 +1718,11 @@ def duplicate_object(self) -> None: """Duplication signal/image object""" if not self.mainwindow.confirm_memory_state(): return - self.mainwindow.historypanel.add_entry( - _("Duplicate object or group"), False, self.duplicate_object + self.mainwindow.historypanel.add_ui_entry( + _("Duplicate object or group"), + target=self.PANEL_STR_ID + "panel", + method_name="duplicate_object", + save_state=False, ) # Duplicate individual objects (exclusive with respect to groups) for oid in self.objview.get_sel_object_uuids(): @@ -1735,8 +1738,11 @@ def duplicate_object(self) -> None: def copy_metadata(self) -> None: """Copy object metadata""" - self.mainwindow.historypanel.add_entry( - _("Copy metadata"), False, self.copy_metadata + self.mainwindow.historypanel.add_ui_entry( + _("Copy metadata"), + target=self.PANEL_STR_ID + "panel", + method_name="copy_metadata", + save_state=False, ) obj = self.objview.get_sel_objects()[0] self.metadata_clipboard = obj.metadata.copy() @@ -1794,8 +1800,12 @@ def paste_metadata(self, param: PasteMetadataParam | None = None) -> None: ) if not param.edit(parent=self.parentWidget()): return - self.mainwindow.historypanel.add_entry( - _("Paste metadata"), False, self.paste_metadata, param=param + self.mainwindow.historypanel.add_ui_entry( + _("Paste metadata"), + target=self.PANEL_STR_ID + "panel", + method_name="paste_metadata", + save_state=False, + param=param, ) metadata = {} if param.keep_roi and ROI_KEY in self.metadata_clipboard: @@ -1895,10 +1905,11 @@ def remove_object(self, force: bool = False) -> None: ) if answer == QW.QMessageBox.No: return - self.mainwindow.historypanel.add_entry( + self.mainwindow.historypanel.add_ui_entry( _("Remove selected objects"), - False, - self.remove_object, + target=self.PANEL_STR_ID + "panel", + method_name="remove_object", + save_state=False, force=force, ) sel_objects = self.objview.get_sel_objects(include_groups=True) @@ -2026,10 +2037,11 @@ def new_group(self) -> None: # Open a message box to enter the group name group_name, ok = QW.QInputDialog.getText(self, _("New group"), _("Group name:")) if ok: - self.mainwindow.historypanel.add_entry( + self.mainwindow.historypanel.add_ui_entry( _('New group "%s"') % group_name, - False, - self.add_group, + target=self.PANEL_STR_ID + "panel", + method_name="add_group", + save_state=False, title=group_name, select=False, ) @@ -2041,10 +2053,11 @@ def rename_selected_object_or_group(self, new_name: str | None = None) -> None: Args: new_name: new name (default: None, i.e. ask user) """ - self.mainwindow.historypanel.add_entry( + self.mainwindow.historypanel.add_ui_entry( _("Rename selected object or group"), - False, - self.rename_selected_object_or_group, + target=self.PANEL_STR_ID + "panel", + method_name="rename_selected_object_or_group", + save_state=False, new_name=new_name, ) sel_objects = self.objview.get_sel_objects(include_groups=False) @@ -2123,10 +2136,11 @@ def set_current_object_title(self, title: str) -> None: obj = self.objview.get_current_object() obj.title = title self.objview.update_item(get_uuid(obj)) - self.mainwindow.historypanel.add_entry( + self.mainwindow.historypanel.add_ui_entry( _('Set current object title to "%s"') % title, - False, - self.set_current_object_title, + target=self.PANEL_STR_ID + "panel", + method_name="set_current_object_title", + save_state=False, title=title, ) @@ -2265,10 +2279,11 @@ def load_from_files( entry_title = _("Load from %d files") % nbf else: entry_title = _('Load "%s"') % osp.basename(filenames[0]) - self.mainwindow.historypanel.add_entry( + self.mainwindow.historypanel.add_ui_entry( entry_title, - False, - self.load_from_files, + target=self.PANEL_STR_ID + "panel", + method_name="load_from_files", + save_state=False, filenames=filenames, create_group=create_group, add_objects=add_objects, @@ -2307,8 +2322,12 @@ def save_to_files(self, filenames: list[str] | str | None = None) -> None: entry_title = _("Save to %d different files") % nbf else: entry_title = _('Save to "%s"') % osp.basename(filenames[0]) - self.mainwindow.historypanel.add_entry( - entry_title, False, self.save_to_files, filenames=filenames + self.mainwindow.historypanel.add_ui_entry( + entry_title, + target=self.PANEL_STR_ID + "panel", + method_name="save_to_files", + save_state=False, + filenames=filenames, ) for index, obj in enumerate(objs): filename = filenames[index] @@ -3372,8 +3391,11 @@ def plot_results( def delete_results(self) -> None: """Delete results""" - self.mainwindow.historypanel.add_entry( - _("Delete results"), False, self.delete_results + self.mainwindow.historypanel.add_ui_entry( + _("Delete results"), + target=self.PANEL_STR_ID + "panel", + method_name="delete_results", + save_state=False, ) objs = self.objview.get_sel_objects(include_groups=True) rdatadict = create_resultdata_dict(objs) @@ -3426,10 +3448,11 @@ def add_label_with_title( action_title = _("Add object title to plot") else: action_title = _("Add label with title") - self.mainwindow.historypanel.add_entry( + self.mainwindow.historypanel.add_ui_entry( action_title, - False, - self.add_label_with_title, + target=self.PANEL_STR_ID + "panel", + method_name="add_label_with_title", + save_state=False, title=title, ) objs = self.objview.get_sel_objects(include_groups=True) diff --git a/datalab/gui/panel/history.py b/datalab/gui/panel/history.py index 57ee3a598..1ded034e2 100644 --- a/datalab/gui/panel/history.py +++ b/datalab/gui/panel/history.py @@ -10,13 +10,14 @@ import functools import html -import inspect import os +import warnings from contextlib import contextmanager from typing import TYPE_CHECKING, Any, Callable, Generator from uuid import uuid4 from guidata.configtools import get_icon +from guidata.dataset.conv import dataset_to_json, json_to_dataset from guidata.dataset.datatypes import DataSet from guidata.qthelpers import add_actions, create_action from guidata.widgets.dockable import DockableWidgetMixin @@ -35,13 +36,79 @@ from datalab.h5.native import NativeH5Reader, NativeH5Writer +# Keys used in the kwargs dict to mark DataSet payloads, so that the +# serialization layer can round-trip them as JSON strings instead of pickling +# arbitrary Python objects. +_DATASET_MARKER = "__dataset_json__" +_DATASET_LIST_MARKER = "__dataset_list_json__" + + +def _encode_kwargs(kwargs: dict[str, Any]) -> dict[str, Any]: + """Encode kwargs for HDF5 storage: replace ``DataSet`` and ``list[DataSet]`` + values with marker dicts holding their JSON representation. + + All other values must already be HDF5-friendly primitives (str, int, float, + bool, list/tuple of the same). + + Args: + kwargs: Raw kwargs dict (may contain ``DataSet`` instances). + + Returns: + A new dict with ``DataSet`` values wrapped in marker dicts. + """ + encoded: dict[str, Any] = {} + for key, value in kwargs.items(): + if value is None: + continue + if isinstance(value, DataSet): + encoded[key] = {_DATASET_MARKER: dataset_to_json(value)} + elif ( + isinstance(value, list) + and value + and all(isinstance(item, DataSet) for item in value) + ): + encoded[key] = { + _DATASET_LIST_MARKER: [dataset_to_json(item) for item in value] + } + else: + encoded[key] = value + return encoded + + +def _decode_kwargs(kwargs: dict[str, Any]) -> dict[str, Any]: + """Inverse of :func:`_encode_kwargs`.""" + decoded: dict[str, Any] = {} + for key, value in kwargs.items(): + if isinstance(value, dict) and _DATASET_MARKER in value: + try: + decoded[key] = json_to_dataset(value[_DATASET_MARKER]) + except Exception: # pylint: disable=broad-except + warnings.warn( + _("Failed to deserialize history DataSet kwarg %r.") % key + ) + decoded[key] = None + elif isinstance(value, dict) and _DATASET_LIST_MARKER in value: + try: + decoded[key] = [ + json_to_dataset(item) for item in value[_DATASET_LIST_MARKER] + ] + except Exception: # pylint: disable=broad-except + warnings.warn( + _("Failed to deserialize history DataSet-list kwarg %r.") % key + ) + decoded[key] = [] + else: + decoded[key] = value + return decoded + + def get_datetime_str() -> str: """Return current date and time as a string""" return QC.QDateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss") def add_to_history(kwargs_names: list[str] = [], title: str | None = None): - """Method decorator to add the method call to the history panel + """Method decorator to add the method call to the history panel as a UI entry. Args: kwargs_names: List of keyword arguments to add to the history action. @@ -58,13 +125,15 @@ def method_wrapper(*args, **kwargs): self: BaseDataPanel | BaseProcessor = args[0] history: HistoryPanel = self.mainwindow.historypanel histkwargs = {k: kwargs[k] for k in kwargs_names if k in kwargs} - history.add_entry( - kwargs.get("title", title), - kwargs.get("save_state", True), - func, - *args, - **histkwargs, - ) + target = _resolve_self_target(self) + if target is not None: + history.add_ui_entry( + kwargs.get("title", title) or func.__name__, + target=target, + method_name=func.__name__, + save_state=kwargs.get("save_state", True), + **histkwargs, + ) return func(*args, **kwargs) return method_wrapper @@ -72,74 +141,93 @@ def method_wrapper(*args, **kwargs): return add_to_history_decorator +def _resolve_self_target(self_obj: Any) -> str | None: + """Resolve a 'self' instance to a string target understood by replay. + + Used by the legacy ``@add_to_history`` decorator. Returns None when no + safe routing is possible (in which case the entry is skipped). + """ + panel_str = getattr(self_obj, "PANEL_STR_ID", None) + if panel_str == "signal": + return "signalpanel" + if panel_str == "image": + return "imagepanel" + return None + + +# --------------------------------------------------------------------------- +# HistoryAction +# --------------------------------------------------------------------------- + + class HistoryAction(ObjItf): """Object representing an action in the history panel. - An action is basically a function that can be called in the same conditions as - when it was added to the history panel. Replay an action is done by calling the - function with the same parameters. + An action is a serialisable description of either a *compute* call (resolved + via the panel processor's feature registry) or a *UI* call (resolved as a + method on a known target -- ``mainwindow``/``signalpanel``/``imagepanel``). - Args: - title: Title of the history action - func: Function to call - args: Function arguments - kwargs: Function keyword arguments - state: State of the workspace before the action + No Python ``Callable`` is ever pickled: a compute action is identified by + ``(panel_str, func_name, pattern)`` and a UI action by ``(target, + method_name)``. ``DataSet`` payloads inside ``kwargs`` are serialised with + :func:`guidata.dataset.conv.dataset_to_json`. """ + KIND_COMPUTE = "compute" + KIND_UI = "ui" + FUNC_EDIT_MODE = "edit" # Name of the function parameter to enable edit mode def __init__( self, - title: str | None = None, - func: Callable | None = None, - args: tuple | None = None, + title: str = "", + kind: str = KIND_UI, + # --- compute-only -------------------------------------------------- + panel_str: str | None = None, + func_name: str | None = None, + pattern: str | None = None, + # --- ui-only ------------------------------------------------------- + target: str | None = None, + method_name: str | None = None, + # --- common -------------------------------------------------------- kwargs: dict[str, Any] | None = None, state: WorkspaceState | None = None, ) -> None: - """Create a new action""" super().__init__() - self.__title = "" if title is None else title - if func is None: - - def default_func(): - """Default function""" - # This function is used to create a default action when the - # function is not provided. - pass - - func = default_func - else: - if not callable(func): - raise TypeError("func must be callable") - self.func = func - self.args = () if args is None else args - kwargs = {} if kwargs is None else kwargs - self.kwargs = {k: v for k, v in kwargs.items() if v is not None} + self.__title = title or "" + self.kind = kind + # Compute kind: + self.panel_str = panel_str + self.func_name = func_name + self.pattern = pattern + # UI kind: + self.target = target + self.method_name = method_name + # Common: + self.kwargs: dict[str, Any] = ( + {} if kwargs is None else {k: v for k, v in kwargs.items() if v is not None} + ) self.state = WorkspaceState() if state is None else state self.dtstr: str = get_datetime_str() self.uuid: str = str(uuid4()) def regenerate_uuid(self): - """Regenerate UUID - - This method is used to regenerate UUID after loading the object from a file. - This is required to avoid UUID conflicts when loading objects from file - without clearing the workspace first. - """ - # No UUID to regenerate for history action + """Regenerate UUID after loading from a file (no-op: per-action UUID).""" @property def title(self) -> str: """Return object title""" return self.__title + # ------------------------------------------------------------------ + # Description rendering (used by the tree view) + # ------------------------------------------------------------------ + def __iter_param_kwargs(self) -> Generator[Any, None, None]: """Yield kwargs values whose name ends with ``param`` (typically DataSets).""" - for kwname in self.kwargs: - if kwname.endswith("param"): - # Note: value can't be None (None values were filtered in __init__) - yield self.kwargs[kwname] + for kwname, value in self.kwargs.items(): + if kwname.endswith("param") and value is not None: + yield value @property def description(self) -> str: @@ -152,11 +240,19 @@ def description(self) -> str: desc += str(param) no_parameters = False if desc or no_parameters: - return desc - if len(self.args) >= 2 and isinstance(self.args[1], Callable): - doc: str = self.args[1].__doc__ - return doc.splitlines()[0] if doc else "" - return self.func.__doc__ or "" + if desc: + return desc + # Fall back to a textual hint of the resolved callable + return self.__fallback_doc() + + def __fallback_doc(self) -> str: + """Return a single-line docstring for the underlying call, if available.""" + try: + func = self._resolve_callable() + except Exception: # pylint: disable=broad-except + return "" + doc = getattr(func, "__doc__", None) or "" + return doc.splitlines()[0] if doc else "" @property def description_summary(self) -> str: @@ -181,12 +277,7 @@ def description_summary(self) -> str: @property def description_html(self) -> str: - """Return rich-text (HTML) description used for the expanded view. - - For DataSet parameters, delegates to :meth:`DataSet.to_html` to mirror - the *Properties* tab rendering; otherwise returns the plain description - wrapped in HTML-safe ``
``-separated lines. - """ + """Return rich-text (HTML) description used for the expanded view.""" parts: list[str] = [] no_parameters = True for param in self.__iter_param_kwargs(): @@ -204,75 +295,188 @@ def description_html(self) -> str: return html.escape(text).replace("\n", "
") return "" + # ------------------------------------------------------------------ + # Workspace-state delegation + # ------------------------------------------------------------------ + def is_current_state_compatible( self, mainwindow: DLMainWindow, restore_selection: bool ) -> bool: - """Check if the current workspace state is compatible with the saved state - - Args: - mainwindow: DataLab's main window - restore_selection: True to restore the selection before checking the state - - Returns: - bool: True if the current workspace state is compatible with the saved state - """ + """Check if the current workspace state is compatible with the saved state.""" return self.state.is_current_state_compatible(mainwindow, restore_selection) def restore(self, mainwindow: DLMainWindow) -> None: - """Restore the associated workspace state - - Args: - mainwindow: DataLab's main window - """ + """Restore the associated workspace state.""" self.state.restore(mainwindow) + # ------------------------------------------------------------------ + # Replay + # ------------------------------------------------------------------ + + def _resolve_target(self, mainwindow: DLMainWindow) -> Any: + """Resolve the target object (UI kind) from the mainwindow.""" + attr = self.target or "mainwindow" + if attr == "mainwindow": + return mainwindow + return getattr(mainwindow, attr) + + def _resolve_panel(self, mainwindow: DLMainWindow): + """Resolve the data panel for a compute action.""" + if self.panel_str == "signal": + return mainwindow.signalpanel + if self.panel_str == "image": + return mainwindow.imagepanel + raise ValueError( + f"Unknown panel_str {self.panel_str!r} for compute history action" + ) + + def _resolve_callable(self) -> Callable | None: + """Best-effort lookup of the underlying callable, for description only.""" + if self.kind == self.KIND_COMPUTE and self.func_name: + try: + # Lazy import to avoid cycles at module import time. + import sigima.proc.image as sigimg # noqa: F401 + import sigima.proc.signal as sigsig # noqa: F401 + except Exception: # pylint: disable=broad-except + return None + for module in (sigsig, sigimg): + func = getattr(module, self.func_name, None) + if callable(func): + return func + return None + + def _resolve_obj_by_uuid(self, mainwindow: DLMainWindow, uuid: str) -> Any | None: + """Look up an object by UUID across both data panels.""" + for panel in (mainwindow.signalpanel, mainwindow.imagepanel): + try: + return panel.objmodel[uuid] + except KeyError: + continue + return None + def replay( self, mainwindow: DLMainWindow, restore_selection: bool, edit: bool ) -> None: - """Replay the action + """Replay the action. Args: mainwindow: DataLab's main window restore_selection: True to restore the workspace selection before replaying - edit: if True, always open the dialog boxes to edit parameters, if False, - use the parameters passed when creating the action + edit: if True, always open the dialog boxes to edit parameters; if False, + use the parameters captured when the action was recorded """ if restore_selection: self.state.restore(mainwindow) - sig = inspect.signature(self.func) - if self.FUNC_EDIT_MODE in sig.parameters: - self.kwargs[self.FUNC_EDIT_MODE] = edit - self.func(*self.args, **self.kwargs) + if self.kind == self.KIND_COMPUTE: + self._replay_compute(mainwindow, edit) + else: + self._replay_ui(mainwindow, edit) - def serialize(self, writer: NativeH5Writer) -> None: - """Serialize this action + def _replay_compute(self, mainwindow: DLMainWindow, edit: bool) -> None: + """Replay a compute-kind action via ``processor.run_feature``.""" + if self.pattern == "multiple_1_to_1": + raise NotImplementedError( + _("Replaying compound 'multiple_1_to_1' actions is not supported yet.") + ) + panel = self._resolve_panel(mainwindow) + processor = panel.processor + feature = processor.get_feature(self.func_name) + run_kwargs: dict[str, Any] = {self.FUNC_EDIT_MODE: edit} + param = self.kwargs.get("param") + if self.pattern in {"1_to_1", "1_to_0", "n_to_1"}: + if param is not None: + run_kwargs["param"] = param + elif self.pattern == "2_to_1": + uuids = self.kwargs.get("obj2_uuids") or [] + if isinstance(uuids, str): + uuids = [uuids] + objs2 = [ + obj + for obj in (self._resolve_obj_by_uuid(mainwindow, u) for u in uuids) + if obj is not None + ] + if not objs2: + raise ValueError( + _("Cannot replay 2-to-1 action: source object(s) missing.") + ) + run_kwargs["obj2"] = objs2[0] if len(objs2) == 1 else objs2 + if param is not None: + run_kwargs["param"] = param + elif self.pattern == "1_to_n": + params = self.kwargs.get("params") or [] + run_kwargs["params"] = params + else: + raise ValueError(f"Unknown compute pattern: {self.pattern!r}") + processor.run_feature(feature, **run_kwargs) + + def _replay_ui(self, mainwindow: DLMainWindow, edit: bool) -> None: + """Replay a UI-kind action by calling ``target.method_name(**kwargs)``.""" + target = self._resolve_target(mainwindow) + method = getattr(target, self.method_name) + call_kwargs = dict(self.kwargs) + # Inject edit mode if the method supports it + try: + import inspect - Args: - writer: Writer - """ - with writer.group("func"): - writer.write(self.func) - with writer.group("args"): - writer.write(self.args) - with writer.group("kwargs"): - writer.write_dict(self.kwargs) + sig = inspect.signature(method) + if self.FUNC_EDIT_MODE in sig.parameters: + call_kwargs[self.FUNC_EDIT_MODE] = edit + except (TypeError, ValueError): + pass + method(**call_kwargs) + + # ------------------------------------------------------------------ + # Serialisation -- no Callable is ever pickled + # ------------------------------------------------------------------ + + def serialize(self, writer: NativeH5Writer) -> None: + """Serialize this action.""" + with writer.group("kind"): + writer.write(self.kind) + with writer.group("title"): + writer.write(self.__title) + if self.panel_str is not None: + with writer.group("panel_str"): + writer.write(self.panel_str) + if self.func_name is not None: + with writer.group("func_name"): + writer.write(self.func_name) + if self.pattern is not None: + with writer.group("pattern"): + writer.write(self.pattern) + if self.target is not None: + with writer.group("target"): + writer.write(self.target) + if self.method_name is not None: + with writer.group("method_name"): + writer.write(self.method_name) + encoded = _encode_kwargs(self.kwargs) + if encoded: + with writer.group("kwargs"): + writer.write_dict(encoded) with writer.group("state"): self.state.serialize(writer) with writer.group("dtstr"): writer.write(self.dtstr) def deserialize(self, reader: NativeH5Reader) -> None: - """Deserialize this action - - Args: - reader: Reader - """ - with reader.group("func"): - self.func = reader.read_any() - with reader.group("args"): - self.args = reader.read_any() - with reader.group("kwargs"): - self.kwargs = reader.read_dict() + """Deserialize this action.""" + with reader.group("kind"): + self.kind = reader.read_any() + with reader.group("title"): + self.__title = reader.read_any() + for attr in ("panel_str", "func_name", "pattern", "target", "method_name"): + try: + with reader.group(attr): + setattr(self, attr, reader.read_any()) + except (KeyError, ValueError): + setattr(self, attr, None) + try: + with reader.group("kwargs"): + raw = reader.read_dict() + self.kwargs = _decode_kwargs(raw) + except (KeyError, ValueError): + self.kwargs = {} with reader.group("state"): self.state.deserialize(reader) with reader.group("dtstr"): @@ -1041,6 +1245,81 @@ def create_new_session(self) -> None: self.__history_sessions.append(session) self.tree.populate_tree(self.__history_sessions) + def add_compute_entry( + self, + action_title: str, + panel_str: str, + func_name: str, + pattern: str, + save_state: bool = True, + **kwargs: Any, + ) -> None: + """Record a *compute* action in the current history session. + + Args: + action_title: Title shown in the history tree. + panel_str: ``"signal"`` or ``"image"``. + func_name: Sigima feature name (resolvable via + :meth:`BaseProcessor.get_feature`). + pattern: One of ``"1_to_1"``, ``"1_to_0"``, ``"n_to_1"``, ``"2_to_1"``, + ``"1_to_n"``, ``"multiple_1_to_1"`` (the latter is recorded for + traceability but not replayable). + save_state: If True, capture the workspace state for replay. + **kwargs: Extra primitive kwargs (``param``, ``obj2_uuids``, + ``obj2_name``, ``pairwise``, ``params`` (list of DataSet), + ``func_names`` (list of str), ...). ``DataSet`` instances are + serialised as JSON. + """ + if not self.__record_mode or self.__replaying: + return + state = WorkspaceState() + if save_state: + state.save(self.mainwindow) + action = HistoryAction( + title=action_title, + kind=HistoryAction.KIND_COMPUTE, + panel_str=panel_str, + func_name=func_name, + pattern=pattern, + kwargs=kwargs, + state=state, + ) + self.add_object(action) + + def add_ui_entry( + self, + action_title: str, + target: str, + method_name: str, + save_state: bool = True, + **kwargs: Any, + ) -> None: + """Record a *UI* action in the current history session. + + Args: + action_title: Title shown in the history tree. + target: One of ``"mainwindow"``, ``"signalpanel"``, ``"imagepanel"``, + ``"historypanel"`` -- attribute path on the main window. + method_name: Method name to call on ``target`` at replay time. + save_state: If True, capture the workspace state for replay. + **kwargs: Method keyword arguments. ``DataSet`` instances are + serialised as JSON; other values must be HDF5-friendly primitives. + """ + if not self.__record_mode or self.__replaying: + return + state = WorkspaceState() + if save_state: + state.save(self.mainwindow) + action = HistoryAction( + title=action_title, + kind=HistoryAction.KIND_UI, + target=target, + method_name=method_name, + kwargs=kwargs, + state=state, + ) + self.add_object(action) + def add_entry( self, action_title: str, @@ -1049,34 +1328,29 @@ def add_entry( *args, **kwargs, ) -> None: - """Add an entry to the current history list + """Legacy entry-point kept as a compatibility shim. - Args: - action_title: Title of the history action - save_state: If True, the current workspace state is saved before adding the - action (this is the most common case). If False, the action is added - without saving the state: this may be useful when the action is not - related to the current workspace state (e.g. when creating a new object). - func: Function to call - args: Function arguments - kwargs: Function keyword arguments - - .. warning:: - - Action will **not** be added to history if *record mode* is disabled. + Most call sites have been migrated to :meth:`add_compute_entry` or + :meth:`add_ui_entry`. The remaining paths -- and the + :func:`add_to_history` decorator -- still call ``add_entry`` with a + bound method; we infer the ``(target, method_name)`` from the bound + ``func.__self__`` and route to :meth:`add_ui_entry`. """ - assert isinstance(action_title, str), "action_title must be a string" - assert isinstance(save_state, bool), "save_state must be a boolean" - assert callable(func), "func must be callable" if not self.__record_mode or self.__replaying: return - if save_state: - state = WorkspaceState() - state.save(self.mainwindow) - else: - state = None - obj = HistoryAction(action_title, func, args, kwargs, state) - self.add_object(obj) + target = None + if hasattr(func, "__self__"): + target = _resolve_self_target(func.__self__) + if target is None: + # Cannot route safely -- skip rather than pickle a Callable. + return + self.add_ui_entry( + action_title, + target=target, + method_name=func.__name__, + save_state=save_state, + **kwargs, + ) # ------ AbstractPanel interface --------------------------------------------------- def create_object(self) -> HistoryAction: diff --git a/datalab/gui/panel/image.py b/datalab/gui/panel/image.py index 4fa20f99d..75c727fec 100644 --- a/datalab/gui/panel/image.py +++ b/datalab/gui/panel/image.py @@ -255,10 +255,11 @@ def new_object( image = create_image_gui(param, edit=edit, parent=self.parentWidget()) if image is None: return None - self.mainwindow.historypanel.add_entry( + self.mainwindow.historypanel.add_ui_entry( _("New image"), - False, - self.new_object, + target="imagepanel", + method_name="new_object", + save_state=False, param=param, add_to_panel=add_to_panel, ) diff --git a/datalab/gui/panel/signal.py b/datalab/gui/panel/signal.py index eedaf0115..d147f363a 100644 --- a/datalab/gui/panel/signal.py +++ b/datalab/gui/panel/signal.py @@ -146,10 +146,11 @@ def new_object( signal = create_signal_gui(param, edit=edit, parent=self.parentWidget()) if signal is None: return None - self.mainwindow.historypanel.add_entry( + self.mainwindow.historypanel.add_ui_entry( _("New signal"), - False, - self.new_object, + target="signalpanel", + method_name="new_object", + save_state=False, param=param, add_to_panel=add_to_panel, ) diff --git a/datalab/gui/processor/base.py b/datalab/gui/processor/base.py index e8d12ea88..63f916a34 100644 --- a/datalab/gui/processor/base.py +++ b/datalab/gui/processor/base.py @@ -45,7 +45,7 @@ from datalab.adapters_plotpy import coordutils from datalab.config import Conf, _ from datalab.gui.processor.catcher import CompOut, wng_err_func -from datalab.objectmodel import get_number, get_short_id, get_uuid, patch_title_with_ids +from datalab.objectmodel import get_short_id, get_uuid, patch_title_with_ids from datalab.utils.qthelpers import create_progress_bar, qt_try_except from datalab.widgets.warningerror import show_warning_error @@ -1272,14 +1272,12 @@ def compute_1_to_1( if param is not None: if edit and not param.edit(parent=self.mainwindow): return - self.mainwindow.historypanel.add_entry( + self.mainwindow.historypanel.add_compute_entry( title or func.__name__, - True, - self.compute_1_to_1, - func, + panel_str=self.panel.PANEL_STR_ID, + func_name=func.__name__, + pattern="1_to_1", param=param, - title=title, - comment=comment, ) self._compute_1_to_1_subroutine([func], [param], title) @@ -1319,13 +1317,13 @@ def compute_multiple_1_to_1( return if len(funcs) != len(params): raise ValueError("Number of functions must match number of parameters") - self.mainwindow.historypanel.add_entry( + self.mainwindow.historypanel.add_compute_entry( title or "compute_multiple_1_to_1", - True, - self.compute_multiple_1_to_1, - funcs, - params=params, - title=title, + panel_str=self.panel.PANEL_STR_ID, + func_name=funcs[0].__name__ if funcs else "", + pattern="multiple_1_to_1", + func_names=[f.__name__ for f in funcs], + params=params if any(p is not None for p in params) else None, ) self._compute_1_to_1_subroutine(funcs, params, title) @@ -1363,13 +1361,12 @@ def compute_1_to_n( group = gds.DataSetGroup(params, title=_("Parameters")) if not group.edit(parent=self.mainwindow): return - self.mainwindow.historypanel.add_entry( - title, - True, - self.compute_1_to_n, - func, + self.mainwindow.historypanel.add_compute_entry( + title or func.__name__, + panel_str=self.panel.PANEL_STR_ID, + func_name=func.__name__, + pattern="1_to_n", params=params, - title=title, ) self._compute_1_to_1_subroutine([func] * len(params), params, title) @@ -1425,14 +1422,12 @@ def compute_1_to_0( ) current_obj = self.panel.objview.get_current_object() title = func.__name__ if title is None else title - self.mainwindow.historypanel.add_entry( + self.mainwindow.historypanel.add_compute_entry( title, - True, - self.compute_1_to_0, - func, + panel_str=self.panel.PANEL_STR_ID, + func_name=func.__name__, + pattern="1_to_0", param=param, - title=title, - comment=comment, ) refresh_needed = False with create_progress_bar(self.panel, title, max_=len(objs)) as progress: @@ -1545,14 +1540,12 @@ def compute_n_to_1( pairwise = is_pairwise_mode() if pairwise is None else pairwise name = func.__name__ - self.mainwindow.historypanel.add_entry( + self.mainwindow.historypanel.add_compute_entry( name, - True, - self.compute_n_to_1, - func, + panel_str=self.panel.PANEL_STR_ID, + func_name=name, + pattern="n_to_1", param=param, - title=title, - comment=comment, pairwise=pairwise, ) @@ -1838,16 +1831,14 @@ def compute_2_to_1( if objs2 is None: return - self.mainwindow.historypanel.add_entry( - title, - True, - self.compute_2_to_1, - [get_number(obj) for obj in objs2], - obj2_name, - func, + self.mainwindow.historypanel.add_compute_entry( + title or func.__name__, + panel_str=self.panel.PANEL_STR_ID, + func_name=func.__name__, + pattern="2_to_1", param=param, - title=title, - comment=comment, + obj2_uuids=[get_uuid(obj) for obj in objs2], + obj2_name=obj2_name, pairwise=True, ) @@ -1976,16 +1967,14 @@ def compute_2_to_1( return obj2 = objs2[0] - self.mainwindow.historypanel.add_entry( - title, - True, - self.compute_2_to_1, - get_number(obj2), - obj2_name, - func, + self.mainwindow.historypanel.add_compute_entry( + title or func.__name__, + panel_str=self.panel.PANEL_STR_ID, + func_name=func.__name__, + pattern="2_to_1", param=param, - title=title, - comment=comment, + obj2_uuids=[get_uuid(obj2)], + obj2_name=obj2_name, pairwise=False, ) From 26fb20cf92fc1126b8fd210bfeeb737087d3524b Mon Sep 17 00:00:00 2001 From: Pierre Raybaut Date: Fri, 15 May 2026 20:36:46 +0200 Subject: [PATCH 010/108] refactor(history): share ProcessingParameters between metadata and history --- datalab/gui/panel/history.py | 52 ++++- datalab/gui/processor/base.py | 94 +++++--- .../features/common/history_wave2_test.py | 214 ++++++++++++++++++ doc/release_notes/release_1.03.md | 7 + 4 files changed, 333 insertions(+), 34 deletions(-) create mode 100644 datalab/tests/features/common/history_wave2_test.py diff --git a/datalab/gui/panel/history.py b/datalab/gui/panel/history.py index 1ded034e2..ac9b054f9 100644 --- a/datalab/gui/panel/history.py +++ b/datalab/gui/panel/history.py @@ -465,17 +465,23 @@ def deserialize(self, reader: NativeH5Reader) -> None: self.kind = reader.read_any() with reader.group("title"): self.__title = reader.read_any() + # Optional descriptors are written conditionally; check existence in + # the underlying HDF5 group before reading to avoid leaking ``__seq`` + # frames on the option stack via guidata's read_any fallback path. + current = reader.h5 + for option in reader.option: + current = current.require_group(option) for attr in ("panel_str", "func_name", "pattern", "target", "method_name"): - try: + if attr in current.attrs or attr in current: with reader.group(attr): setattr(self, attr, reader.read_any()) - except (KeyError, ValueError): + else: setattr(self, attr, None) - try: + if "kwargs" in current.attrs or "kwargs" in current: with reader.group("kwargs"): raw = reader.read_dict() self.kwargs = _decode_kwargs(raw) - except (KeyError, ValueError): + else: self.kwargs = {} with reader.group("state"): self.state.deserialize(reader) @@ -1286,6 +1292,44 @@ def add_compute_entry( ) self.add_object(action) + def add_compute_entry_from_pp( + self, + action_title: str, + pp: Any, # ProcessingParameters (avoid circular import) + panel_str: str, + save_state: bool = True, + **extras: Any, + ) -> None: + """Record a *compute* action derived from a ``ProcessingParameters``. + + Bridges the dash-form pattern used in object metadata + (``"1-to-1"`` …) with the underscore form expected by + :class:`HistoryAction` (``"1_to_1"`` …) so that both sides share + a single identity (``func_name`` / ``pattern`` / ``param``). + + Args: + action_title: Title shown in the history tree. + pp: :class:`~datalab.gui.processor.base.ProcessingParameters` + instance describing the operation. + panel_str: ``"signal"`` or ``"image"``. + save_state: If True, capture the workspace state for replay. + **extras: Additional history-only kwargs (``obj2_uuids``, + ``obj2_name``, ``pairwise``, ``params``, ``func_names``…). + """ + hist_pattern = pp.pattern.replace("-", "_") + kwargs: dict[str, Any] = {} + if pp.param is not None and "param" not in extras and "params" not in extras: + kwargs["param"] = pp.param + kwargs.update(extras) + self.add_compute_entry( + action_title, + panel_str=panel_str, + func_name=pp.func_name, + pattern=hist_pattern, + save_state=save_state, + **kwargs, + ) + def add_ui_entry( self, action_title: str, diff --git a/datalab/gui/processor/base.py b/datalab/gui/processor/base.py index 63f916a34..5507ad00d 100644 --- a/datalab/gui/processor/base.py +++ b/datalab/gui/processor/base.py @@ -195,6 +195,43 @@ def insert_processing_parameters( obj.set_metadata_option(PROCESSING_PARAMETERS_OPTION, pp.to_dict()) +def build_processing_parameters( + func_name: str, + pattern: str, + *, + param: gds.DataSet | list[gds.DataSet] | None = None, + source_uuid: str | None = None, + source_uuids: list[str] | None = None, +) -> ProcessingParameters: + """Single factory for :class:`ProcessingParameters`. + + Centralises construction so that history-panel entries and per-object + metadata always share the same identity (``func_name``, ``pattern``, + ``param``). + + Args: + func_name: Sigima feature name. + pattern: Dash-form pattern (``"1-to-1"``, ``"1-to-0"``, + ``"n-to-1"``, ``"2-to-1"``, ``"1-to-n"``). + param: Optional parameter dataset (or list of datasets for + multi-parameter patterns). + source_uuid: Source object UUID for ``"1-to-1"`` / ``"1-to-0"`` / + ``"1-to-n"`` patterns. + source_uuids: Source object UUIDs for ``"n-to-1"`` / ``"2-to-1"`` + patterns. + + Returns: + Newly constructed :class:`ProcessingParameters`. + """ + return ProcessingParameters( + func_name=func_name, + pattern=pattern, + param=param, + source_uuid=source_uuid, + source_uuids=source_uuids, + ) + + def clear_analysis_parameters(obj: SignalObj | ImageObj) -> None: """Clear analysis parameters from object metadata. @@ -1272,12 +1309,9 @@ def compute_1_to_1( if param is not None: if edit and not param.edit(parent=self.mainwindow): return - self.mainwindow.historypanel.add_compute_entry( - title or func.__name__, - panel_str=self.panel.PANEL_STR_ID, - func_name=func.__name__, - pattern="1_to_1", - param=param, + pp = build_processing_parameters(func.__name__, "1-to-1", param=param) + self.mainwindow.historypanel.add_compute_entry_from_pp( + title or func.__name__, pp, panel_str=self.panel.PANEL_STR_ID ) self._compute_1_to_1_subroutine([func], [param], title) @@ -1317,11 +1351,13 @@ def compute_multiple_1_to_1( return if len(funcs) != len(params): raise ValueError("Number of functions must match number of parameters") - self.mainwindow.historypanel.add_compute_entry( + pp = build_processing_parameters( + funcs[0].__name__ if funcs else "", "multiple-1-to-1" + ) + self.mainwindow.historypanel.add_compute_entry_from_pp( title or "compute_multiple_1_to_1", + pp, panel_str=self.panel.PANEL_STR_ID, - func_name=funcs[0].__name__ if funcs else "", - pattern="multiple_1_to_1", func_names=[f.__name__ for f in funcs], params=params if any(p is not None for p in params) else None, ) @@ -1361,11 +1397,11 @@ def compute_1_to_n( group = gds.DataSetGroup(params, title=_("Parameters")) if not group.edit(parent=self.mainwindow): return - self.mainwindow.historypanel.add_compute_entry( + pp = build_processing_parameters(func.__name__, "1-to-n") + self.mainwindow.historypanel.add_compute_entry_from_pp( title or func.__name__, + pp, panel_str=self.panel.PANEL_STR_ID, - func_name=func.__name__, - pattern="1_to_n", params=params, ) self._compute_1_to_1_subroutine([func] * len(params), params, title) @@ -1422,12 +1458,9 @@ def compute_1_to_0( ) current_obj = self.panel.objview.get_current_object() title = func.__name__ if title is None else title - self.mainwindow.historypanel.add_compute_entry( - title, - panel_str=self.panel.PANEL_STR_ID, - func_name=func.__name__, - pattern="1_to_0", - param=param, + pp_history = build_processing_parameters(func.__name__, "1-to-0", param=param) + self.mainwindow.historypanel.add_compute_entry_from_pp( + title, pp_history, panel_str=self.panel.PANEL_STR_ID ) refresh_needed = False with create_progress_bar(self.panel, title, max_=len(objs)) as progress: @@ -1540,12 +1573,11 @@ def compute_n_to_1( pairwise = is_pairwise_mode() if pairwise is None else pairwise name = func.__name__ - self.mainwindow.historypanel.add_compute_entry( + pp_history = build_processing_parameters(name, "n-to-1", param=param) + self.mainwindow.historypanel.add_compute_entry_from_pp( name, + pp_history, panel_str=self.panel.PANEL_STR_ID, - func_name=name, - pattern="n_to_1", - param=param, pairwise=pairwise, ) @@ -1831,12 +1863,13 @@ def compute_2_to_1( if objs2 is None: return - self.mainwindow.historypanel.add_compute_entry( + pp_history = build_processing_parameters( + func.__name__, "2-to-1", param=param + ) + self.mainwindow.historypanel.add_compute_entry_from_pp( title or func.__name__, + pp_history, panel_str=self.panel.PANEL_STR_ID, - func_name=func.__name__, - pattern="2_to_1", - param=param, obj2_uuids=[get_uuid(obj) for obj in objs2], obj2_name=obj2_name, pairwise=True, @@ -1967,12 +2000,13 @@ def compute_2_to_1( return obj2 = objs2[0] - self.mainwindow.historypanel.add_compute_entry( + pp_history = build_processing_parameters( + func.__name__, "2-to-1", param=param + ) + self.mainwindow.historypanel.add_compute_entry_from_pp( title or func.__name__, + pp_history, panel_str=self.panel.PANEL_STR_ID, - func_name=func.__name__, - pattern="2_to_1", - param=param, obj2_uuids=[get_uuid(obj2)], obj2_name=obj2_name, pairwise=False, diff --git a/datalab/tests/features/common/history_wave2_test.py b/datalab/tests/features/common/history_wave2_test.py new file mode 100644 index 000000000..964bb5ceb --- /dev/null +++ b/datalab/tests/features/common/history_wave2_test.py @@ -0,0 +1,214 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +""" +History panel — Wave 2 invariants + +Validates the post-Wave-2 history-panel contract: + +1. ``compute_1_to_1`` produces a coherent ``ProcessingParameters`` *and* + history entry (same ``func_name``, same source UUID). +2. ``HistoryAction.replay`` finds its target by UUID even after the panel + has been reordered by inserting/deleting siblings. +3. ``recompute_processing`` does not add a history entry (anti-loop guard). +4. ``HistoryAction`` round-trips through HDF5 without pickling any + ``Callable`` and remains replayable after deserialisation. +5. A UI action (rename via ``set_current_object_title``) is captured and + replayable. +""" + +# pylint: disable=invalid-name + +# guitest: skip + +import os +import tempfile + +import sigima.params +import sigima.proc.signal as sips +from sigima.tests.data import create_paracetamol_signal + +from datalab.gui.panel.history import ( + HistoryAction, + HistorySession, + WorkspaceState, +) +from datalab.gui.processor.base import extract_processing_parameters +from datalab.h5.native import NativeH5Reader, NativeH5Writer +from datalab.objectmodel import get_uuid +from datalab.tests import datalab_test_app_context + + +def test_compute_1_to_1_history_matches_processing_parameters(): + """History entry and ProcessingParameters share func_name + source UUID.""" + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) + src_uuid = get_uuid(panel.objmodel.get_object_from_number(1)) + + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.derivative) + + # Latest object holds ProcessingParameters. + result_obj = panel.objmodel.get_object_from_number(2) + pp = extract_processing_parameters(result_obj) + assert pp is not None + assert pp.func_name == "derivative" + assert pp.source_uuid == src_uuid + + # Latest history entry mirrors the same identity. + entry = history[len(history)] + assert entry.kind == HistoryAction.KIND_COMPUTE + assert entry.func_name == "derivative" + assert entry.pattern == "1_to_1" + assert entry.state.selection.get(panel.PANEL_STR) == [src_uuid] + + +def test_replay_finds_target_by_uuid_after_reorder(): + """Replay locates source object by UUID even after reordering.""" + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + + panel.add_object(create_paracetamol_signal()) + target_uuid = get_uuid(panel.objmodel.get_object_from_number(1)) + + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.derivative) + deriv_entry = history[len(history)] + + # Reorder the panel: insert a new sibling before the original source. + panel.add_object(create_paracetamol_signal()) + # Sanity: the original object now lives at a different index but its + # UUID is unchanged. + assert get_uuid(panel.objmodel[target_uuid]) == target_uuid + + n_before = len(panel.objmodel) + deriv_entry.replay(win, restore_selection=True, edit=False) + assert len(panel.objmodel) == n_before + 1 + + # The replayed result must be derived from the same source UUID. + new_obj = panel.objmodel.get_object_from_number(len(panel.objmodel)) + new_pp = extract_processing_parameters(new_obj) + assert new_pp is not None + assert new_pp.source_uuid == target_uuid + + +def test_recompute_processing_does_not_add_history_entry(): + """``recompute_processing`` is silent on the history panel (anti-loop).""" + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) + + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.derivative) + n_before = len(history) + + # Select the derived object and recompute it: no new entry expected. + derived = panel.objmodel.get_object_from_number(2) + panel.objview.set_current_object(derived) + panel.recompute_processing() + + assert len(history) == n_before, ( + "recompute_processing must not register a history entry" + ) + + +def test_history_action_hdf5_roundtrip_without_pickle(): + """Serialise+deserialise a HistoryAction; replay still works.""" + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) + src_uuid = get_uuid(panel.objmodel.get_object_from_number(1)) + + norm_param = sigima.params.NormalizeParam.create(method="maximum") + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.normalize, norm_param) + original = history[len(history)] + + # Wrap into a session so we exercise the full HDF5 path used by + # the panel (write_object_list / read_object_list). + session = HistorySession(number=1) + session.actions.append(original) + + with tempfile.TemporaryDirectory() as tmpdir: + path = os.path.join(tmpdir, "wave2.dlhist") + with NativeH5Writer(path) as writer: + writer.write_object_list([session], "wave2_history") + with NativeH5Reader(path) as reader: + restored_sessions = reader.read_object_list( + "wave2_history", HistorySession + ) + + assert len(restored_sessions) == 1 + restored = restored_sessions[0].actions[0] + + # No pickled Callable: the rebuilt HistoryAction has no ``func`` attr. + assert not hasattr(restored, "func") + assert restored.kind == HistoryAction.KIND_COMPUTE + assert restored.func_name == "normalize" + assert restored.pattern == "1_to_1" + assert restored.panel_str == panel.PANEL_STR_ID + # DataSet kwarg survived the JSON round-trip. + restored_param = restored.kwargs.get("param") + assert restored_param is not None + assert type(restored_param).__name__ == type(norm_param).__name__ + + # Replay the restored entry against the live workspace. + n_before = len(panel.objmodel) + restored.replay(win, restore_selection=True, edit=False) + assert len(panel.objmodel) == n_before + 1 + new_obj = panel.objmodel.get_object_from_number(len(panel.objmodel)) + new_pp = extract_processing_parameters(new_obj) + assert new_pp is not None + assert new_pp.source_uuid == src_uuid + assert new_pp.func_name == "normalize" + + +def test_ui_action_rename_capture_and_replay(): + """A UI rename is captured and can be replayed.""" + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) + + obj = panel.objmodel.get_object_from_number(1) + original_title = obj.title + + new_title = "wave2-renamed" + panel.objview.set_current_object(obj) + panel.set_current_object_title(new_title) + assert obj.title == new_title + + rename_entry = history[len(history)] + assert rename_entry.kind == HistoryAction.KIND_UI + assert rename_entry.target == "signalpanel" + assert rename_entry.method_name == "set_current_object_title" + assert rename_entry.kwargs.get("title") == new_title + + # Mutate the title to something else, then replay: the entry must + # restore the recorded value. + panel.set_current_object_title("transient-title") + assert obj.title == "transient-title" + + rename_entry.replay(win, restore_selection=False, edit=False) + assert obj.title == new_title + assert obj.title != original_title + + # WorkspaceState type check (Wave-2 invariant). + assert isinstance(rename_entry.state, WorkspaceState) + + +if __name__ == "__main__": + test_compute_1_to_1_history_matches_processing_parameters() + test_replay_finds_target_by_uuid_after_reorder() + test_recompute_processing_does_not_add_history_entry() + test_history_action_hdf5_roundtrip_without_pickle() + test_ui_action_rename_capture_and_replay() diff --git a/doc/release_notes/release_1.03.md b/doc/release_notes/release_1.03.md index 87c809b1b..1206355d1 100644 --- a/doc/release_notes/release_1.03.md +++ b/doc/release_notes/release_1.03.md @@ -10,3 +10,10 @@ * Multiple directories can be listed using the OS path separator (`;` on Windows, `:` on Linux/macOS), following the same convention as `PYTHONPATH` * Listed directories are appended to the existing plugin search paths at startup and are picked up automatically by the plugin discovery mechanism * Non-existent directories are silently skipped (a warning is recorded in the log file), so a stale environment variable on another machine will not prevent DataLab from starting + +### 🛠️ Internal changes ### + +**History panel:** + +* Reworked how processing actions are recorded so that history entries no longer rely on serialised Python callables — sessions saved to disk are now portable across DataLab versions and immune to function refactorings +* Replay now resolves processing functions by name (via the Sigima feature catalog), making history sessions robust to internal code reorganisations as long as the public function names remain stable From 6813f639979dd1469a27372aa4bec41bce8d61fc Mon Sep 17 00:00:00 2001 From: Pierre Raybaut Date: Fri, 15 May 2026 20:49:27 +0200 Subject: [PATCH 011/108] feat(history): add French translations for history-related error messages and replay actions --- datalab/locale/fr/LC_MESSAGES/datalab.po | 14 ++++++++++++++ doc/release_notes/release_1.03.md | 7 ------- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/datalab/locale/fr/LC_MESSAGES/datalab.po b/datalab/locale/fr/LC_MESSAGES/datalab.po index 374dd39f5..96b2095b0 100644 --- a/datalab/locale/fr/LC_MESSAGES/datalab.po +++ b/datalab/locale/fr/LC_MESSAGES/datalab.po @@ -1634,6 +1634,20 @@ msgstr "Annotation ajoutée" msgid "The label has been added as an annotation. You can edit or remove it using the annotation editing window.

Choosing to ignore this message will prevent it from being displayed again." msgstr "L'étiquette a été ajoutée comme annotation. Vous pouvez la modifier ou la supprimer en utilisant la fenêtre d'édition des annotations.

Ignorer ce message empêchera son affichage ultérieur." +#, python-format +msgid "Failed to deserialize history DataSet kwarg %r." +msgstr "Échec de la désérialisation de l'argument DataSet de l'historique %r." + +#, python-format +msgid "Failed to deserialize history DataSet-list kwarg %r." +msgstr "Échec de la désérialisation de l'argument DataSet-list de l'historique %r." + +msgid "Replaying compound 'multiple_1_to_1' actions is not supported yet." +msgstr "La relecture des actions composées 'multiple_1_to_1' n'est pas encore prise en charge." + +msgid "Cannot replay 2-to-1 action: source object(s) missing." +msgstr "Impossible de rejouer une action 2-à-1 : objet(s) source manquant(s)." + msgid "Session" msgstr "Session" diff --git a/doc/release_notes/release_1.03.md b/doc/release_notes/release_1.03.md index 1206355d1..87c809b1b 100644 --- a/doc/release_notes/release_1.03.md +++ b/doc/release_notes/release_1.03.md @@ -10,10 +10,3 @@ * Multiple directories can be listed using the OS path separator (`;` on Windows, `:` on Linux/macOS), following the same convention as `PYTHONPATH` * Listed directories are appended to the existing plugin search paths at startup and are picked up automatically by the plugin discovery mechanism * Non-existent directories are silently skipped (a warning is recorded in the log file), so a stale environment variable on another machine will not prevent DataLab from starting - -### 🛠️ Internal changes ### - -**History panel:** - -* Reworked how processing actions are recorded so that history entries no longer rely on serialised Python callables — sessions saved to disk are now portable across DataLab versions and immune to function refactorings -* Replay now resolves processing functions by name (via the Sigima feature catalog), making history sessions robust to internal code reorganisations as long as the public function names remain stable From ad9352750fd03fafee2f932086ac452b379d3249 Mon Sep 17 00:00:00 2001 From: Pierre Raybaut Date: Fri, 15 May 2026 21:18:47 +0200 Subject: [PATCH 012/108] test(history): cover workspace .h5 roundtrip and replay edge cases --- ..._test.py => history_contract_unit_test.py} | 14 +- .../common/history_replay_app_test.py | 283 ++++++++++++++++++ 2 files changed, 290 insertions(+), 7 deletions(-) rename datalab/tests/features/common/{history_wave2_test.py => history_contract_unit_test.py} (95%) create mode 100644 datalab/tests/features/common/history_replay_app_test.py diff --git a/datalab/tests/features/common/history_wave2_test.py b/datalab/tests/features/common/history_contract_unit_test.py similarity index 95% rename from datalab/tests/features/common/history_wave2_test.py rename to datalab/tests/features/common/history_contract_unit_test.py index 964bb5ceb..d0731ccb6 100644 --- a/datalab/tests/features/common/history_wave2_test.py +++ b/datalab/tests/features/common/history_contract_unit_test.py @@ -1,9 +1,9 @@ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. """ -History panel — Wave 2 invariants +History panel contract tests -Validates the post-Wave-2 history-panel contract: +Validates the core history-panel contract: 1. ``compute_1_to_1`` produces a coherent ``ProcessingParameters`` *and* history entry (same ``func_name``, same source UUID). @@ -138,12 +138,12 @@ def test_history_action_hdf5_roundtrip_without_pickle(): session.actions.append(original) with tempfile.TemporaryDirectory() as tmpdir: - path = os.path.join(tmpdir, "wave2.dlhist") + path = os.path.join(tmpdir, "history.dlhist") with NativeH5Writer(path) as writer: - writer.write_object_list([session], "wave2_history") + writer.write_object_list([session], "history_session") with NativeH5Reader(path) as reader: restored_sessions = reader.read_object_list( - "wave2_history", HistorySession + "history_session", HistorySession ) assert len(restored_sessions) == 1 @@ -182,7 +182,7 @@ def test_ui_action_rename_capture_and_replay(): obj = panel.objmodel.get_object_from_number(1) original_title = obj.title - new_title = "wave2-renamed" + new_title = "renamed-by-test" panel.objview.set_current_object(obj) panel.set_current_object_title(new_title) assert obj.title == new_title @@ -202,7 +202,7 @@ def test_ui_action_rename_capture_and_replay(): assert obj.title == new_title assert obj.title != original_title - # WorkspaceState type check (Wave-2 invariant). + # WorkspaceState type check. assert isinstance(rename_entry.state, WorkspaceState) diff --git a/datalab/tests/features/common/history_replay_app_test.py b/datalab/tests/features/common/history_replay_app_test.py new file mode 100644 index 000000000..2f6957fdd --- /dev/null +++ b/datalab/tests/features/common/history_replay_app_test.py @@ -0,0 +1,283 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +""" +History panel replay & persistence tests + +Covers replay/restore edge cases and HDF5 persistence paths: + +1. Workspace ``.h5`` round-trip embeds the history panel and survives + save → reset → reload (``MainWindow.save_h5_workspace`` / + ``load_h5_workspace``). +2. Standalone ``HistoryPanel.serialize_to_hdf5`` / + ``deserialize_from_hdf5`` round-trip on a populated panel (mirrors + the ``.dlhist`` save/open menu paths). +3. ``1_to_n`` replay (extract ROI) reproduces the same number of + children and same source UUID. +4. ``multiple_1_to_1`` replay surfaces a clear ``NotImplementedError``. +5. Replay of a ``2_to_1`` action whose secondary source UUID has been + deleted raises ``ValueError`` instead of silently failing. +6. Public panel API ``replay_restore_actions(replay=True)`` produces + a new object when a tree item is selected. +7. Public panel API ``replay_restore_actions(replay=False)`` only + restores the workspace selection (no new object). +""" + +# pylint: disable=invalid-name + +# guitest: skip + +import os + +import pytest +import sigima.objects +import sigima.params +import sigima.proc.signal as sips +from qtpy import QtCore as QC +from sigima.tests import helpers +from sigima.tests.data import create_paracetamol_signal + +from datalab.gui.panel.history import HistoryAction, WorkspaceState +from datalab.h5.native import NativeH5Reader, NativeH5Writer +from datalab.objectmodel import get_uuid +from datalab.tests import datalab_test_app_context + + +def _select_tree_item_for(history, entry: HistoryAction) -> None: + """Select the tree item matching ``entry`` in the history tree.""" + tree = history.tree + for i in range(tree.topLevelItemCount()): + sess_item = tree.topLevelItem(i) + for j in range(sess_item.childCount()): + child = sess_item.child(j) + if child.data(0, QC.Qt.UserRole) == entry.uuid: + tree.clearSelection() + tree.setCurrentItem(child) + child.setSelected(True) + return + raise AssertionError(f"No tree item found for entry {entry.uuid}") + + +# --- 1) Workspace .h5 round-trip ------------------------------------------ + + +def test_workspace_h5_roundtrip_with_history(): + """Saving + reloading the workspace ``.h5`` preserves the history panel.""" + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) + + norm_param = sigima.params.NormalizeParam.create(method="maximum") + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.normalize, norm_param) + + recorded_titles = [a.title for a in history] + recorded_func_names = [a.func_name for a in history] + recorded_kinds = [a.kind for a in history] + n_recorded = len(history) + assert n_recorded >= 1 + + with helpers.WorkdirRestoringTempDir() as tmpdir: + path = os.path.join(tmpdir, "workspace.h5") + win.save_h5_workspace(path) + + # Wipe everything (objects + history) then reload. + win.reset_all() + assert len(panel.objmodel) == 0 + + win.load_h5_workspace([path], reset_all=True) + + # Note: ``save_h5_workspace`` itself records a UI history entry + # ("Save to HDF5 file") *before* writing — that entry is part of + # what gets saved. The reloaded history must therefore contain + # at least the originally-recorded actions. + reloaded = win.historypanel + reloaded_titles = [a.title for a in reloaded] + for title in recorded_titles: + assert title in reloaded_titles, ( + f"Title {title!r} missing from reloaded history" + ) + for func_name in recorded_func_names: + if func_name is not None: + assert func_name in [a.func_name for a in reloaded] + for kind in recorded_kinds: + assert kind in [a.kind for a in reloaded] + + +# --- 2) Standalone .dlhist round-trip on full panel ----------------------- + + +def test_history_panel_dlhist_roundtrip(): + """``HistoryPanel.serialize_to_hdf5`` / ``deserialize_from_hdf5`` round-trip.""" + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.derivative) + panel.objview.select_objects([1]) + panel.processor.run_feature( + sips.normalize, sigima.params.NormalizeParam.create(method="maximum") + ) + + original_titles = [a.title for a in history] + original_func_names = [a.func_name for a in history] + assert len(original_titles) >= 2 + + with helpers.WorkdirRestoringTempDir() as tmpdir: + path = os.path.join(tmpdir, "history_panel.dlhist") + with NativeH5Writer(path) as writer: + history.serialize_to_hdf5(writer) + with NativeH5Reader(path) as reader: + history.deserialize_from_hdf5(reader) + + assert [a.title for a in history] == original_titles + assert [a.func_name for a in history] == original_func_names + + +# --- 3) 1-to-n replay (extract ROI) --------------------------------------- + + +def test_replay_1_to_n_extract_roi(): + """``extract_roi`` (1-to-n) is recorded and replayable.""" + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + + sig = create_paracetamol_signal() + sig.roi = sigima.objects.create_signal_roi([[26, 41], [125, 146]], indices=True) + panel.add_object(sig) + src_uuid = get_uuid(panel.objmodel.get_object_from_number(1)) + + n_objects_before = len(panel.objmodel) + panel.objview.select_objects([1]) + panel.processor.run_feature("extract_roi", params=sig.roi.to_params(sig)) + n_added_first = len(panel.objmodel) - n_objects_before + assert n_added_first >= 1 + + entry = history[len(history)] + assert entry.kind == HistoryAction.KIND_COMPUTE + assert entry.pattern == "1_to_n" + assert entry.func_name == "extract_roi" + assert entry.state.selection.get(panel.PANEL_STR) == [src_uuid] + + # Replay against the original source. + n_before_replay = len(panel.objmodel) + entry.replay(win, restore_selection=True, edit=False) + n_added_replay = len(panel.objmodel) - n_before_replay + assert n_added_replay == n_added_first, ( + "Replay must produce the same number of children as the original" + ) + + +# --- 4) multiple_1_to_1 NotImplementedError -------------------------------- + + +def test_multiple_1_to_1_replay_raises_not_implemented(): + """``multiple_1_to_1`` replay raises a clear ``NotImplementedError``.""" + with datalab_test_app_context() as win: + action = HistoryAction( + title="dummy multiple_1_to_1", + kind=HistoryAction.KIND_COMPUTE, + panel_str="signal", + func_name="some_compound_op", + pattern="multiple_1_to_1", + state=WorkspaceState(), + ) + with pytest.raises(NotImplementedError): + action.replay(win, restore_selection=False, edit=False) + + +# --- 5) 2-to-1 replay with vanished secondary source ----------------------- + + +def test_replay_2_to_1_with_vanished_obj2_raises(): + """Replaying a 2-to-1 action whose obj2 was deleted raises ``ValueError``.""" + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + + panel.add_object(create_paracetamol_signal()) + panel.add_object(create_paracetamol_signal()) + obj2 = panel.objmodel.get_object_from_number(2) + + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.difference, obj2) + diff_entry = history[len(history)] + assert diff_entry.pattern == "2_to_1" + + # Delete obj2 so its UUID is no longer resolvable. + panel.objview.set_current_object(obj2) + panel.remove_object(force=True) + + with pytest.raises(ValueError): + # restore_selection=False so we hit the obj2 lookup path, + # not the WorkspaceState compatibility check. + diff_entry.replay(win, restore_selection=False, edit=False) + + +# --- 6) Public API replay_restore_actions(replay=True) --------------------- + + +def test_replay_via_panel_api_creates_new_object(): + """``HistoryPanel.replay_restore_actions`` replays the selected entry.""" + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.derivative) + deriv_entry = history[len(history)] + + _select_tree_item_for(history, deriv_entry) + + n_before = len(panel.objmodel) + history.replay_restore_actions(replay=True, restore_selection=True) + assert len(panel.objmodel) == n_before + 1 + + +# --- 7) Public API replay_restore_actions(replay=False) ------------------- + + +def test_restore_selection_only_via_panel_api(): + """``replay_restore_actions(replay=False)`` only restores selection.""" + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) + src_uuid = get_uuid(panel.objmodel.get_object_from_number(1)) + + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.derivative) + deriv_entry = history[len(history)] + + # Move selection elsewhere (the freshly-added derivative). + derived = panel.objmodel.get_object_from_number(2) + panel.objview.set_current_object(derived) + derived_uuid = get_uuid(derived) + assert panel.objview.get_sel_object_uuids() == [derived_uuid] + + _select_tree_item_for(history, deriv_entry) + + n_before = len(panel.objmodel) + history.replay_restore_actions(replay=False, restore_selection=True) + # No new object created. + assert len(panel.objmodel) == n_before + # Selection restored to the originally-recorded source. + assert panel.objview.get_sel_object_uuids() == [src_uuid] + + +if __name__ == "__main__": + test_workspace_h5_roundtrip_with_history() + test_history_panel_dlhist_roundtrip() + test_replay_1_to_n_extract_roi() + test_multiple_1_to_1_replay_raises_not_implemented() + test_replay_2_to_1_with_vanished_obj2_raises() + test_replay_via_panel_api_creates_new_object() + test_restore_selection_only_via_panel_api() From 88985e0e753bf1b5e9e180ca3c42b03fbcd5fc23 Mon Sep 17 00:00:00 2001 From: Pierre Raybaut Date: Sat, 16 May 2026 10:33:01 +0200 Subject: [PATCH 013/108] fix(history): force selection restore for compute actions on replay --- datalab/gui/panel/history.py | 14 ++++++- .../common/history_replay_app_test.py | 37 +++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/datalab/gui/panel/history.py b/datalab/gui/panel/history.py index ac9b054f9..87b2d901b 100644 --- a/datalab/gui/panel/history.py +++ b/datalab/gui/panel/history.py @@ -362,14 +362,24 @@ def replay( Args: mainwindow: DataLab's main window restore_selection: True to restore the workspace selection before replaying + a UI-kind action. Ignored for compute-kind actions: their semantics + depends on which objects are selected (e.g. ``n_to_1`` aggregators + such as ``average`` require their captured multi-object selection), + so the captured selection is always restored before running the + computation. edit: if True, always open the dialog boxes to edit parameters; if False, use the parameters captured when the action was recorded """ - if restore_selection: - self.state.restore(mainwindow) if self.kind == self.KIND_COMPUTE: + # Compute actions are selection-driven: always restore the captured + # selection so chained replays (especially ``n_to_1`` / ``2_to_1`` + # / ``1_to_n`` patterns) operate on the original input objects + # rather than on whatever the previous action left selected. + self.state.restore(mainwindow) self._replay_compute(mainwindow, edit) else: + if restore_selection: + self.state.restore(mainwindow) self._replay_ui(mainwindow, edit) def _replay_compute(self, mainwindow: DLMainWindow, edit: bool) -> None: diff --git a/datalab/tests/features/common/history_replay_app_test.py b/datalab/tests/features/common/history_replay_app_test.py index 2f6957fdd..8d1fafa18 100644 --- a/datalab/tests/features/common/history_replay_app_test.py +++ b/datalab/tests/features/common/history_replay_app_test.py @@ -273,6 +273,42 @@ def test_restore_selection_only_via_panel_api(): assert panel.objview.get_sel_object_uuids() == [src_uuid] +# --- 8) n_to_1 replay ignores restore_selection=False -------------------- + + +def test_replay_n_to_1_forces_captured_selection(): + """``n_to_1`` replay must restore the captured multi-object selection + even when ``restore_selection=False`` (otherwise an aggregator such as + ``average`` would be applied to the single object the previous action + left selected and fail with ``src_list must be a list of at least 2 + objects``).""" + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + + panel.add_object(create_paracetamol_signal()) + panel.add_object(create_paracetamol_signal()) + panel.add_object(create_paracetamol_signal()) + + # Average over the three signals (n_to_1 aggregator). + panel.objview.select_objects([1, 2, 3]) + panel.processor.run_feature(sips.average) + avg_entry = history[len(history)] + assert avg_entry.pattern == "n_to_1" + + # Drift selection to a single object (mimics the state left by a + # preceding "New signal" UI action in a chained session replay). + panel.objview.select_objects([1]) + assert len(panel.objview.get_sel_object_uuids()) == 1 + + n_before = len(panel.objmodel) + # restore_selection=False on purpose: compute actions must still + # restore their captured selection internally. + avg_entry.replay(win, restore_selection=False, edit=False) + assert len(panel.objmodel) == n_before + 1 + + if __name__ == "__main__": test_workspace_h5_roundtrip_with_history() test_history_panel_dlhist_roundtrip() @@ -281,3 +317,4 @@ def test_restore_selection_only_via_panel_api(): test_replay_2_to_1_with_vanished_obj2_raises() test_replay_via_panel_api_creates_new_object() test_restore_selection_only_via_panel_api() + test_replay_n_to_1_forces_captured_selection() From 1c101afd41e0bedb9c484be200243c047057b66f Mon Sep 17 00:00:00 2001 From: Pierre Raybaut Date: Sat, 16 May 2026 11:10:20 +0200 Subject: [PATCH 014/108] fix(history): remap UUIDs across actions during session replay --- datalab/gui/panel/history.py | 146 ++++++++++++++++-- .../common/history_replay_app_test.py | 126 +++++++++++++++ 2 files changed, 263 insertions(+), 9 deletions(-) diff --git a/datalab/gui/panel/history.py b/datalab/gui/panel/history.py index 87b2d901b..b7d764a64 100644 --- a/datalab/gui/panel/history.py +++ b/datalab/gui/panel/history.py @@ -355,7 +355,11 @@ def _resolve_obj_by_uuid(self, mainwindow: DLMainWindow, uuid: str) -> Any | Non return None def replay( - self, mainwindow: DLMainWindow, restore_selection: bool, edit: bool + self, + mainwindow: DLMainWindow, + restore_selection: bool, + edit: bool, + uuid_remap: dict[str, dict[str, str]] | None = None, ) -> None: """Replay the action. @@ -369,20 +373,51 @@ def replay( computation. edit: if True, always open the dialog boxes to edit parameters; if False, use the parameters captured when the action was recorded + uuid_remap: optional per-panel mapping ``{panel_str: {old_uuid: new_uuid}}`` + used during full-session replay to translate captured UUIDs to the + freshly-created ones. Defaults to an empty (identity) mapping. """ + if uuid_remap is None: + uuid_remap = {} if self.kind == self.KIND_COMPUTE: - # Compute actions are selection-driven: always restore the captured - # selection so chained replays (especially ``n_to_1`` / ``2_to_1`` - # / ``1_to_n`` patterns) operate on the original input objects - # rather than on whatever the previous action left selected. - self.state.restore(mainwindow) - self._replay_compute(mainwindow, edit) + # Compute actions are selection-driven: restore the captured + # selection (translated through ``uuid_remap`` for session + # replays) whenever it is still resolvable so chained replays + # (especially ``n_to_1`` / ``2_to_1`` / ``1_to_n`` patterns) + # operate on the original input objects rather than on whatever + # the previous action left selected. When the captured UUIDs no + # longer exist (e.g. heuristic remap missed an object), fall + # back to the current selection -- replay may still fail + # downstream, but with the native processor error rather than + # an opaque ``WorkspaceState`` incompatibility. + translated = self._translate_state(uuid_remap) + if translated.is_current_state_compatible(mainwindow, False): + translated.restore(mainwindow) + self._replay_compute(mainwindow, edit, uuid_remap) else: if restore_selection: self.state.restore(mainwindow) self._replay_ui(mainwindow, edit) - def _replay_compute(self, mainwindow: DLMainWindow, edit: bool) -> None: + def _translate_state(self, uuid_remap: dict[str, dict[str, str]]) -> WorkspaceState: + """Return a copy of ``self.state`` whose captured UUIDs have been + translated through ``uuid_remap`` (identity when no mapping).""" + if not uuid_remap: + return self.state + translated = WorkspaceState() + for panel_str, uuids in self.state.selection.items(): + panel_map = uuid_remap.get(panel_str, {}) + translated.selection[panel_str] = [panel_map.get(u, u) for u in uuids] + translated.states = dict(self.state.states) + translated.titles = dict(self.state.titles) + return translated + + def _replay_compute( + self, + mainwindow: DLMainWindow, + edit: bool, + uuid_remap: dict[str, dict[str, str]] | None = None, + ) -> None: """Replay a compute-kind action via ``processor.run_feature``.""" if self.pattern == "multiple_1_to_1": raise NotImplementedError( @@ -400,6 +435,12 @@ def _replay_compute(self, mainwindow: DLMainWindow, edit: bool) -> None: uuids = self.kwargs.get("obj2_uuids") or [] if isinstance(uuids, str): uuids = [uuids] + # Translate captured UUIDs through ``uuid_remap`` (session replay). + # ``uuid_remap`` keys are ``panel.PANEL_STR`` (matches + # ``WorkspaceState.selection`` keys), not the + # ``HistoryAction.panel_str`` (PANEL_STR_ID). + panel_map = (uuid_remap or {}).get(panel.PANEL_STR, {}) + uuids = [panel_map.get(u, u) for u in uuids] objs2 = [ obj for obj in (self._resolve_obj_by_uuid(mainwindow, u) for u in uuids) @@ -702,8 +743,95 @@ def replay( edit: if True, always open the dialog boxes to edit parameters, if False, use the parameters passed when creating the action """ + # Per-panel ``{old_uuid: new_uuid}`` mapping, populated as UI actions + # create new objects. Used by compute actions to translate their + # captured selection (and ``obj2_uuids``) into the freshly-created + # UUIDs of the current replay, so chained ``n_to_1`` / ``2_to_1`` / + # ``1_to_n`` actions operate on the correct inputs. Keys are + # ``panel.PANEL_STR`` (matches ``WorkspaceState.selection`` keys). + panels = (mainwindow.signalpanel, mainwindow.imagepanel) + # Map ``HistoryAction.panel_str`` (PANEL_STR_ID, e.g. ``"signal"``) + # to the corresponding ``panel.PANEL_STR`` used in remap keys. + id_to_pstr = { + mainwindow.signalpanel.PANEL_STR_ID: mainwindow.signalpanel.PANEL_STR, + mainwindow.imagepanel.PANEL_STR_ID: mainwindow.imagepanel.PANEL_STR, + } + uuid_remap: dict[str, dict[str, str]] = {p.PANEL_STR: {} for p in panels} + # FIFO of newly-created UUIDs not yet claimed by a remap entry -- + # required because most creation UI actions (e.g. ``new_signal``) + # are recorded with ``save_state=False`` (empty captured selection), + # so we cannot pair captured-vs-new UUIDs by position at UI time. + # Subsequent compute actions claim from this queue on demand. + unclaimed: dict[str, list[str]] = {p.PANEL_STR: [] for p in panels} for action in self.actions[:]: - action.replay(mainwindow, restore_selection=restore_selection, edit=edit) + before = {p.PANEL_STR: set(p.objmodel.get_object_ids()) for p in panels} + if action.kind == HistoryAction.KIND_COMPUTE: + # Lazy-resolve any captured UUIDs missing from the remap by + # claiming from ``unclaimed`` (FIFO, panel-local). + pstr = id_to_pstr.get(action.panel_str or "", "") + captured = action.state.selection.get(pstr, []) + for old_uuid in captured: + if old_uuid in uuid_remap.get(pstr, {}): + continue + queue = unclaimed.get(pstr) or [] + if queue: + uuid_remap.setdefault(pstr, {})[old_uuid] = queue.pop(0) + # 2_to_1: also claim ``obj2_uuids`` from the queue if unknown. + if action.pattern == "2_to_1": + obj2 = action.kwargs.get("obj2_uuids") or [] + if isinstance(obj2, str): + obj2 = [obj2] + for old_uuid in obj2: + if old_uuid in uuid_remap.get(pstr, {}): + continue + queue = unclaimed.get(pstr) or [] + if queue: + uuid_remap.setdefault(pstr, {})[old_uuid] = queue.pop(0) + action.replay( + mainwindow, + restore_selection=restore_selection, + edit=edit, + uuid_remap=uuid_remap, + ) + if action.kind == HistoryAction.KIND_UI: + for panel in panels: + pstr = panel.PANEL_STR + current_ids = set(panel.objmodel.get_object_ids()) + new_uuids = [ + u + for u in panel.objmodel.get_object_ids() + if u not in before[pstr] + ] + # Drop vanished UUIDs from the unclaimed queue and the + # reverse remap entries (e.g. ``Remove selected objects``): + # this keeps the FIFO claim in sync with the live panel + # contents during chained creation/removal replays. + removed_uuids = before[pstr] - current_ids + if removed_uuids: + unclaimed[pstr] = [ + u for u in unclaimed.get(pstr, []) if u not in removed_uuids + ] + panel_map = uuid_remap.get(pstr, {}) + for old_key in [ + k for k, v in panel_map.items() if v in removed_uuids + ]: + panel_map.pop(old_key, None) + if not new_uuids: + continue + captured = action.state.selection.get(pstr, []) + if captured: + # Captured post-action selection available: pair + # captured UUIDs with new UUIDs by position. + for old_uuid, new_uuid in zip(captured, new_uuids): + uuid_remap.setdefault(pstr, {})[old_uuid] = new_uuid + # Any extra newly-created UUIDs go to the queue. + unclaimed.setdefault(pstr, []).extend( + new_uuids[len(captured) :] + ) + else: + # No captured selection (typical of ``new_signal``): + # queue all new UUIDs for lazy claiming. + unclaimed.setdefault(pstr, []).extend(new_uuids) def serialize(self, writer: NativeH5Writer) -> None: """Serialize this history session diff --git a/datalab/tests/features/common/history_replay_app_test.py b/datalab/tests/features/common/history_replay_app_test.py index 8d1fafa18..a900d5982 100644 --- a/datalab/tests/features/common/history_replay_app_test.py +++ b/datalab/tests/features/common/history_replay_app_test.py @@ -20,6 +20,22 @@ a new object when a tree item is selected. 7. Public panel API ``replay_restore_actions(replay=False)`` only restores the workspace selection (no new object). +8. ``n_to_1`` replay forces the captured selection so a chained + ``[New, ..., New, average]`` session does not aggregate over a + stale single-object selection. +9. ``n_to_1`` replay falls back to the current selection when the + captured UUIDs no longer exist (typical of a full-session replay + in a fresh workspace), so the failure surfaces as the native + processor error rather than an opaque ``WorkspaceState`` + incompatibility. +10. Full ``HistorySession`` replay on an empty workspace correctly + re-runs ``[New, New, New, average]`` end-to-end: the per-session + UUID remap translates the captured ``n_to_1`` selection to the + freshly-created signals. +11. Full ``HistorySession`` replay with an intermediate + ``[New, New, New, Remove, average]`` correctly drops the + vanished UUID from the remap queue so ``average`` aggregates + over the right two surviving signals. """ # pylint: disable=invalid-name @@ -33,6 +49,7 @@ import sigima.params import sigima.proc.signal as sips from qtpy import QtCore as QC +from sigima.objects.signal.creation import NewSignalParam from sigima.tests import helpers from sigima.tests.data import create_paracetamol_signal @@ -309,6 +326,112 @@ def test_replay_n_to_1_forces_captured_selection(): assert len(panel.objmodel) == n_before + 1 +# --- 9) n_to_1 replay tolerates vanished captured UUIDs ------------------- + + +def test_replay_n_to_1_falls_back_when_captured_uuids_gone(): + """When the captured selection refers to UUIDs that no longer exist + (full-session replay creates fresh objects with new UUIDs), the + compute replay must fall back to the current selection rather than + raising the opaque ``WorkspaceState`` incompatibility error.""" + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + + panel.add_object(create_paracetamol_signal()) + panel.add_object(create_paracetamol_signal()) + panel.add_object(create_paracetamol_signal()) + panel.objview.select_objects([1, 2, 3]) + panel.processor.run_feature(sips.average) + avg_entry = history[len(history)] + assert avg_entry.pattern == "n_to_1" + + # Wipe the workspace and recreate three signals: same shape, + # different UUIDs (mimics the state mid-way through a full + # session replay). The captured selection is now stale. + win.reset_all() + panel.add_object(create_paracetamol_signal()) + panel.add_object(create_paracetamol_signal()) + panel.add_object(create_paracetamol_signal()) + panel.objview.select_objects([1, 2, 3]) + assert not avg_entry.state.is_current_state_compatible(win, False) + + n_before = len(panel.objmodel) + # Must not raise ValueError("... not compatible with saved state"); + # falls back to the current selection (the 3 freshly-added signals). + avg_entry.replay(win, restore_selection=False, edit=False) + assert len(panel.objmodel) == n_before + 1 + + +# --- 10) Full session replay with UUID remap ------------------------------ + + +def test_full_session_replay_remaps_uuids_for_n_to_1(): + """A full ``HistorySession.replay`` on an empty workspace correctly + re-runs ``[New signal, New signal, New signal, average]``: the + per-session UUID remap translates ``average``'s captured selection + to the freshly-created signals, instead of aggregating over the + single object the last ``New signal`` left selected.""" + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + + # Record [New, New, New, average]. + for _i in range(3): + panel.new_object(param=NewSignalParam(), edit=False) + n_after_creations = len(panel.objmodel) + assert n_after_creations == 3 + panel.objview.select_objects([1, 2, 3]) + panel.processor.run_feature(sips.average) + assert len(panel.objmodel) == 4 + + session = history._HistoryPanel__history_sessions[-1] # noqa: SLF001 + + # Reset to an empty workspace, then replay the whole session. + win.reset_all() + assert len(panel.objmodel) == 0 + session.replay(win, restore_selection=False, edit=False) + # 3 fresh signals + 1 average = 4 objects. + assert len(panel.objmodel) == 4 + + +# --- 11) Full session replay with intermediate removal -------------------- + + +def test_full_session_replay_with_intermediate_removal(): + """A full ``HistorySession.replay`` with ``[New, New, New, Remove, + average]`` correctly drops the removed UUID from the unclaimed + queue and the reverse remap, so ``average`` aggregates over the + two surviving signals (and not, e.g., over a stale single-object + selection or a removed one).""" + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + + # Record [New, New, New, Remove #3, average of remaining 2]. + for _i in range(3): + panel.new_object(param=NewSignalParam(), edit=False) + assert len(panel.objmodel) == 3 + panel.objview.select_objects([3]) + panel.remove_object(force=True) + assert len(panel.objmodel) == 2 + panel.objview.select_objects([1, 2]) + panel.processor.run_feature(sips.average) + assert len(panel.objmodel) == 3 + + session = history._HistoryPanel__history_sessions[-1] # noqa: SLF001 + + # Reset to an empty workspace, then replay the whole session. + win.reset_all() + assert len(panel.objmodel) == 0 + session.replay(win, restore_selection=False, edit=False) + # 3 created − 1 removed + 1 average = 3 objects. + assert len(panel.objmodel) == 3 + + if __name__ == "__main__": test_workspace_h5_roundtrip_with_history() test_history_panel_dlhist_roundtrip() @@ -318,3 +441,6 @@ def test_replay_n_to_1_forces_captured_selection(): test_replay_via_panel_api_creates_new_object() test_restore_selection_only_via_panel_api() test_replay_n_to_1_forces_captured_selection() + test_replay_n_to_1_falls_back_when_captured_uuids_gone() + test_full_session_replay_remaps_uuids_for_n_to_1() + test_full_session_replay_with_intermediate_removal() From 13f9450ecd0419fd20a88695bd49e7e7af0173db Mon Sep 17 00:00:00 2001 From: Pierre Raybaut Date: Sat, 16 May 2026 11:37:50 +0200 Subject: [PATCH 015/108] feat(history): add tests and documentation for History Panel functionality --- .../features/common/history_panel_app_test.py | 64 ++++ doc/features/common/historypanel.rst | 146 +++++++++ doc/features/index.rst | 1 + doc/images/shots/history_panel.png | Bin 0 -> 24773 bytes .../features/common/historypanel.po | 301 ++++++++++++++++++ doc/update_screenshots.py | 2 + 6 files changed, 514 insertions(+) create mode 100644 datalab/tests/features/common/history_panel_app_test.py create mode 100644 doc/features/common/historypanel.rst create mode 100644 doc/images/shots/history_panel.png create mode 100644 doc/locale/fr/LC_MESSAGES/features/common/historypanel.po diff --git a/datalab/tests/features/common/history_panel_app_test.py b/datalab/tests/features/common/history_panel_app_test.py new file mode 100644 index 000000000..49786d513 --- /dev/null +++ b/datalab/tests/features/common/history_panel_app_test.py @@ -0,0 +1,64 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +""" +History Panel application test +(essentially for the screenshot...) + +Records a representative sequence of UI and computation actions and grabs +a screenshot of the history panel, used in the documentation +(:ref:`historypanel`). +""" + +# guitest: show + +import sigima.objects +import sigima.proc.signal as sips + +from datalab import config +from datalab.tests import datalab_test_app_context +from datalab.utils import qthelpers as qth + + +def test_history_panel(screenshots: bool = False) -> None: + """Record a representative session and grab the History Panel screenshot.""" + config.reset() # Reset configuration (remove configuration file and initialize it) + with datalab_test_app_context(console=False, exec_loop=not screenshots) as win: + history = win.historypanel + history.toggle_record_mode(True) + + panel = win.signalpanel + + # [New Voigt, New Lorentzian, New Lorentzian] + panel.new_object(param=sigima.objects.VoigtParam(), edit=False) + panel.new_object(param=sigima.objects.LorentzParam(), edit=False) + panel.new_object(param=sigima.objects.LorentzParam(), edit=False) + + # Remove the third signal + panel.objview.select_objects([3]) + panel.remove_object(force=True) + + # New Gaussian + panel.new_object(param=sigima.objects.GaussParam(), edit=False) + + # Average of the 3 remaining signals + panel.objview.select_objects([1, 2, 3]) + panel.processor.run_feature(sips.average) + + # Add Gaussian noise to the average + noise_param = sigima.objects.NormalDistributionParam() + noise_param.sigma = 0.05 + panel.objview.select_objects([4]) + panel.processor.run_feature(sips.add_gaussian_noise, noise_param) + + # Gaussian fit + panel.processor.run_feature(sips.gaussian_fit) + + # Make sure the History Panel dock is raised over the Macro Panel + win.docks[history].raise_() + + if screenshots: + qth.grab_save_window(history, "history_panel", add_timestamp=False) + + +if __name__ == "__main__": + test_history_panel() diff --git a/doc/features/common/historypanel.rst b/doc/features/common/historypanel.rst new file mode 100644 index 000000000..0400d7136 --- /dev/null +++ b/doc/features/common/historypanel.rst @@ -0,0 +1,146 @@ +.. _historypanel: + +History Panel +============= + +.. meta:: + :description: History Panel in DataLab, the open-source scientific data analysis and visualization platform + :keywords: DataLab, history, record, replay, session, scientific, data, analysis, visualization, platform + +Overview +-------- + +The "History Panel" records the sequence of actions performed by the user on +signals and images, organized into **sessions**. Each session is a chronological +list of either: + +- **UI actions** (creating a new signal, removing selected objects, saving the + workspace to HDF5, ...), or +- **computations** (FFT, average, Gaussian fit, ...) dispatched through the + Sigima processor. + +A recorded session can be: + +- **Replayed**, either entirely or starting from a selected action, to + reproduce the exact same sequence on the current workspace; +- **Restored to a given selection state** without re-executing anything, to + quickly jump back to a previous working context; +- **Saved to a standalone history file** (``.dlhist``) or **embedded in the + workspace** when saving to HDF5, so that the full processing chain travels + with the data. + +.. figure:: ../../images/shots/history_panel.png + :align: center + :alt: History Panel + + The History Panel after recording a representative session: create three + signals (Voigt, Lorentzian, Lorentzian), remove one of them, create a + Gaussian signal, compute the average, add Gaussian noise to the result + and run a Gaussian fit. + +Toolbar +------- + +The toolbar at the top of the panel exposes the following actions: + +.. |record| image:: ../../../datalab/data/icons/record.svg + :width: 24px + :height: 24px + :class: dark-light no-scaled-link + +.. |replay| image:: ../../../datalab/data/icons/replay.svg + :width: 24px + :height: 24px + :class: dark-light no-scaled-link + +.. |restore_selection| image:: ../../../datalab/data/icons/restore_selection.svg + :width: 24px + :height: 24px + :class: dark-light no-scaled-link + +.. |restore_and_replay| image:: ../../../datalab/data/icons/restore_and_replay.svg + :width: 24px + :height: 24px + :class: dark-light no-scaled-link + +.. |edit_mode| image:: ../../../datalab/data/icons/edit_mode.svg + :width: 24px + :height: 24px + :class: dark-light no-scaled-link + +.. |delete| image:: ../../../datalab/data/icons/edit/delete.svg + :width: 24px + :height: 24px + :class: dark-light no-scaled-link + +- |record| **Record mode**: toggle the recording of new actions. When off, no + new entry is added to the history (existing sessions are preserved). +- |replay| **Replay**: replay the selected action (or the whole session if a + session row is selected) without changing the current workspace selection + beforehand. +- |restore_selection| **Restore selection**: only re-select the objects that + were selected when the action was originally executed; no computation is + re-run. +- |restore_and_replay| **Restore selection and replay**: combine the two + previous actions -- restore the selection first, then replay. +- |edit_mode| **Edit mode**: when on, replaying a computation opens the + parameters dialog so the user can tweak the parameters before re-running. +- |delete| **Delete**: remove the selected actions or sessions from the + history. + +.. note:: + + Double-clicking on an action row in the tree is equivalent to "Restore + selection and replay". + +Tree view +--------- + +The tree view organizes recorded actions into expandable sessions: + +- Each top-level row is a **session**, automatically created when recording is + enabled and a new application context is started. +- Each child row is an **action**, with its title, date/time and a description + summarising the parameters (for computations) or the call (for UI actions). + +The selection of one or several rows drives which actions are targeted by the +toolbar buttons. + +Session replay across workspaces +-------------------------------- + +A full session can be replayed on a workspace that no longer contains the +objects originally referenced by the recorded actions -- typically after +loading a saved session into a fresh workspace. In that case, the panel +**remaps the recorded object identifiers** to the newly-created ones on the +fly: + +- UI actions creating new objects (e.g. *New signal*) enqueue the freshly + created identifiers; +- subsequent computations claim the identifiers they need from that queue, + in the same order as the original recording; +- UI actions removing objects keep the queue in sync with the live workspace + contents, so chained creation/removal sequences replay correctly. + +This makes it possible, for instance, to record a full processing chain on +one dataset, save it, then re-apply the exact same chain on a different but +structurally identical input. + +Persistence +----------- + +The history can be persisted in two complementary ways: + +- **Embedded in the workspace**: when the workspace is saved to HDF5 + (``File > Save to HDF5 file``), the History Panel content is automatically + saved alongside the signals and images. Reloading the workspace restores + the recorded sessions. +- **Standalone history file**: the panel can also be serialised to a + dedicated ``.dlhist`` file, which is convenient to share or version a + processing chain independently of the data it was applied to. + +.. warning:: + + Replaying a session that depends on external files (e.g. opening a + dataset from disk) will only succeed if those files are still available at + the same locations as when the session was recorded. diff --git a/doc/features/index.rst b/doc/features/index.rst index b05605bf2..09254926d 100644 --- a/doc/features/index.rst +++ b/doc/features/index.rst @@ -35,6 +35,7 @@ Overview & Common features common/overview common/settings common/h5browser + common/historypanel .. raw:: latex diff --git a/doc/images/shots/history_panel.png b/doc/images/shots/history_panel.png new file mode 100644 index 0000000000000000000000000000000000000000..0ebd0e32778b6cb2dcdf580b1b14015c50cbf3cc GIT binary patch literal 24773 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 literal 0 HcmV?d00001 diff --git a/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po b/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po new file mode 100644 index 000000000..afcb4a95e --- /dev/null +++ b/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po @@ -0,0 +1,301 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2023, DataLab Platform Developers +# This file is distributed under the same license as the DataLab package. +# FIRST AUTHOR , 2026. +# +msgid "" +msgstr "" +"Project-Id-Version: DataLab \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-05-16 11:30+0200\n" +"PO-Revision-Date: 2026-05-16 11:35+0200\n" +"Last-Translator: DataLab Platform Developers\n" +"Language: fr\n" +"Language-Team: fr \n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.18.0\n" + +msgid "" +"History Panel in DataLab, the open-source scientific data analysis and " +"visualization platform" +msgstr "" +"Panneau historique de DataLab, la plateforme open-source d'analyse et de " +"visualisation de données scientifiques" + +msgid "" +"DataLab, history, record, replay, session, scientific, data, analysis, " +"visualization, platform" +msgstr "" +"DataLab, historique, enregistrement, rejeu, session, scientifique, données, " +"analyse, visualisation, plateforme" + +msgid "History Panel" +msgstr "Panneau historique" + +msgid "Overview" +msgstr "Vue d'ensemble" + +msgid "" +"The \"History Panel\" records the sequence of actions performed by the " +"user on signals and images, organized into **sessions**. Each session is " +"a chronological list of either:" +msgstr "" +"Le « Panneau historique » enregistre la séquence des actions effectuées " +"par l'utilisateur sur les signaux et les images, organisée en " +"**sessions**. Chaque session est une liste chronologique constituée " +"soit :" + +msgid "" +"**UI actions** (creating a new signal, removing selected objects, saving " +"the workspace to HDF5, ...), or" +msgstr "" +"d'**actions de l'interface** (création d'un nouveau signal, suppression " +"des objets sélectionnés, enregistrement de l'espace de travail au format " +"HDF5, ...), soit" + +msgid "" +"**computations** (FFT, average, Gaussian fit, ...) dispatched through the" +" Sigima processor." +msgstr "" +"de **calculs** (FFT, moyenne, ajustement gaussien, ...) exécutés via le " +"processeur Sigima." + +msgid "A recorded session can be:" +msgstr "Une session enregistrée peut être :" + +msgid "" +"**Replayed**, either entirely or starting from a selected action, to " +"reproduce the exact same sequence on the current workspace;" +msgstr "" +"**rejouée**, soit intégralement, soit à partir d'une action sélectionnée, " +"afin de reproduire exactement la même séquence sur l'espace de travail " +"courant ;" + +msgid "" +"**Restored to a given selection state** without re-executing anything, to" +" quickly jump back to a previous working context;" +msgstr "" +"**restaurée dans un état de sélection donné** sans rien réexécuter, afin " +"de revenir rapidement à un contexte de travail antérieur ;" + +msgid "" +"**Saved to a standalone history file** (``.dlhist``) or **embedded in the" +" workspace** when saving to HDF5, so that the full processing chain " +"travels with the data." +msgstr "" +"**sauvegardée dans un fichier d'historique autonome** (``.dlhist``) ou " +"**intégrée à l'espace de travail** lors de l'enregistrement au format " +"HDF5, de sorte que toute la chaîne de traitement accompagne les données." + +msgid "" +"The History Panel after recording a representative session: create three " +"signals (Voigt, Lorentzian, Lorentzian), remove one of them, create a " +"Gaussian signal, compute the average, add Gaussian noise to the result " +"and run a Gaussian fit." +msgstr "" +"Le Panneau historique après l'enregistrement d'une session représentative :" +" création de trois signaux (Voigt, lorentzien, lorentzien), suppression " +"de l'un d'eux, création d'un signal gaussien, calcul de la moyenne, " +"ajout d'un bruit gaussien au résultat et ajustement par une gaussienne." + +msgid "Toolbar" +msgstr "Barre d'outils" + +msgid "The toolbar at the top of the panel exposes the following actions:" +msgstr "La barre d'outils en haut du panneau expose les actions suivantes :" + +msgid "" +"|record| **Record mode**: toggle the recording of new actions. When off, " +"no new entry is added to the history (existing sessions are preserved)." +msgstr "" +"|record| **Mode enregistrement** : active ou désactive l'enregistrement " +"des nouvelles actions. Lorsqu'il est désactivé, aucune nouvelle entrée " +"n'est ajoutée à l'historique (les sessions existantes sont conservées)." + +msgid "record" +msgstr "record" + +msgid "" +"|replay| **Replay**: replay the selected action (or the whole session if " +"a session row is selected) without changing the current workspace " +"selection beforehand." +msgstr "" +"|replay| **Rejouer** : rejoue l'action sélectionnée (ou la session " +"entière si une ligne de session est sélectionnée) sans modifier au " +"préalable la sélection courante de l'espace de travail." + +msgid "replay" +msgstr "replay" + +msgid "" +"|restore_selection| **Restore selection**: only re-select the objects " +"that were selected when the action was originally executed; no " +"computation is re-run." +msgstr "" +"|restore_selection| **Restaurer la sélection** : ré-sélectionne " +"uniquement les objets qui étaient sélectionnés lors de l'exécution " +"initiale de l'action ; aucun calcul n'est ré-exécuté." + +msgid "restore_selection" +msgstr "restore_selection" + +msgid "" +"|restore_and_replay| **Restore selection and replay**: combine the two " +"previous actions -- restore the selection first, then replay." +msgstr "" +"|restore_and_replay| **Restaurer la sélection et rejouer** : combine les " +"deux actions précédentes -- restaure d'abord la sélection, puis rejoue." + +msgid "restore_and_replay" +msgstr "restore_and_replay" + +msgid "" +"|edit_mode| **Edit mode**: when on, replaying a computation opens the " +"parameters dialog so the user can tweak the parameters before re-running." +msgstr "" +"|edit_mode| **Mode édition** : lorsqu'il est activé, rejouer un calcul " +"ouvre la boîte de dialogue des paramètres afin que l'utilisateur puisse " +"les ajuster avant de relancer l'exécution." + +msgid "edit_mode" +msgstr "edit_mode" + +msgid "" +"|delete| **Delete**: remove the selected actions or sessions from the " +"history." +msgstr "" +"|delete| **Supprimer** : retire de l'historique les actions ou sessions " +"sélectionnées." + +msgid "delete" +msgstr "delete" + +msgid "" +"Double-clicking on an action row in the tree is equivalent to \"Restore " +"selection and replay\"." +msgstr "" +"Un double-clic sur la ligne d'une action dans l'arborescence équivaut à " +"« Restaurer la sélection et rejouer »." + +msgid "Tree view" +msgstr "Arborescence" + +msgid "The tree view organizes recorded actions into expandable sessions:" +msgstr "" +"L'arborescence organise les actions enregistrées dans des sessions " +"dépliables :" + +msgid "" +"Each top-level row is a **session**, automatically created when recording" +" is enabled and a new application context is started." +msgstr "" +"Chaque ligne de premier niveau est une **session**, créée automatiquement " +"lorsque l'enregistrement est activé et qu'un nouveau contexte " +"d'application est démarré." + +msgid "" +"Each child row is an **action**, with its title, date/time and a " +"description summarising the parameters (for computations) or the call " +"(for UI actions)." +msgstr "" +"Chaque ligne enfant est une **action**, accompagnée de son titre, de sa " +"date et de son heure, ainsi que d'une description résumant les " +"paramètres (pour les calculs) ou l'appel (pour les actions de l'interface)." + +msgid "" +"The selection of one or several rows drives which actions are targeted by" +" the toolbar buttons." +msgstr "" +"La sélection d'une ou de plusieurs lignes détermine les actions ciblées " +"par les boutons de la barre d'outils." + +msgid "Session replay across workspaces" +msgstr "Rejeu d'une session entre espaces de travail" + +msgid "" +"A full session can be replayed on a workspace that no longer contains the" +" objects originally referenced by the recorded actions -- typically after" +" loading a saved session into a fresh workspace. In that case, the panel " +"**remaps the recorded object identifiers** to the newly-created ones on " +"the fly:" +msgstr "" +"Une session complète peut être rejouée sur un espace de travail qui ne " +"contient plus les objets référencés à l'origine par les actions " +"enregistrées -- typiquement après le chargement d'une session sauvegardée " +"dans un espace de travail vierge. Dans ce cas, le panneau **réassocie à " +"la volée les identifiants d'objets enregistrés** aux nouveaux " +"identifiants créés :" + +msgid "" +"UI actions creating new objects (e.g. *New signal*) enqueue the freshly " +"created identifiers;" +msgstr "" +"les actions de l'interface qui créent de nouveaux objets (par exemple " +"*Nouveau signal*) empilent les identifiants fraîchement créés ;" + +msgid "" +"subsequent computations claim the identifiers they need from that queue, " +"in the same order as the original recording;" +msgstr "" +"les calculs ultérieurs récupèrent dans cette file les identifiants dont " +"ils ont besoin, dans l'ordre de l'enregistrement initial ;" + +msgid "" +"UI actions removing objects keep the queue in sync with the live " +"workspace contents, so chained creation/removal sequences replay " +"correctly." +msgstr "" +"les actions de l'interface qui suppriment des objets maintiennent la " +"file synchronisée avec le contenu réel de l'espace de travail, de sorte " +"que les séquences enchaînées de création et de suppression se rejouent " +"correctement." + +msgid "" +"This makes it possible, for instance, to record a full processing chain " +"on one dataset, save it, then re-apply the exact same chain on a " +"different but structurally identical input." +msgstr "" +"Cela permet par exemple d'enregistrer une chaîne de traitement complète " +"sur un jeu de données, de la sauvegarder, puis de la ré-appliquer " +"telle quelle à une entrée différente mais structurellement identique." + +msgid "Persistence" +msgstr "Persistance" + +msgid "The history can be persisted in two complementary ways:" +msgstr "L'historique peut être persisté de deux manières complémentaires :" + +msgid "" +"**Embedded in the workspace**: when the workspace is saved to HDF5 " +"(``File > Save to HDF5 file``), the History Panel content is " +"automatically saved alongside the signals and images. Reloading the " +"workspace restores the recorded sessions." +msgstr "" +"**Intégré à l'espace de travail** : lorsque l'espace de travail est " +"enregistré au format HDF5 (``Fichier > Enregistrer dans un fichier " +"HDF5``), le contenu du Panneau historique est automatiquement sauvegardé " +"aux côtés des signaux et des images. Le rechargement de l'espace de " +"travail restaure les sessions enregistrées." + +msgid "" +"**Standalone history file**: the panel can also be serialised to a " +"dedicated ``.dlhist`` file, which is convenient to share or version a " +"processing chain independently of the data it was applied to." +msgstr "" +"**Fichier d'historique autonome** : le panneau peut également être " +"sérialisé dans un fichier ``.dlhist`` dédié, ce qui est pratique pour " +"partager ou versionner une chaîne de traitement indépendamment des " +"données auxquelles elle a été appliquée." + +msgid "" +"Replaying a session that depends on external files (e.g. opening a " +"dataset from disk) will only succeed if those files are still available " +"at the same locations as when the session was recorded." +msgstr "" +"Le rejeu d'une session qui dépend de fichiers externes (par exemple " +"l'ouverture d'un jeu de données depuis le disque) ne réussira que si " +"ces fichiers sont toujours disponibles aux mêmes emplacements qu'au " +"moment de l'enregistrement de la session." diff --git a/doc/update_screenshots.py b/doc/update_screenshots.py index 2ae380d1e..8858bb1ce 100644 --- a/doc/update_screenshots.py +++ b/doc/update_screenshots.py @@ -6,6 +6,7 @@ from datalab import config from datalab.tests.features.applauncher import launcher1_app_test +from datalab.tests.features.common import history_panel_app_test from datalab.tests.features.utilities import settings_unit_test from datalab.tests.scenarios import beautiful_app @@ -17,4 +18,5 @@ beautiful_app.run_beautiful_scenario(screenshots=True) beautiful_app.run_blob_detection_on_flower_image(screenshots=True) settings_unit_test.capture_settings_screenshots() + history_panel_app_test.test_history_panel(screenshots=True) print("done.") From 389613beb36da05fdce01eea210cf88592ed63e0 Mon Sep 17 00:00:00 2001 From: Pierre Raybaut Date: Sat, 16 May 2026 12:19:12 +0200 Subject: [PATCH 016/108] feat(short-id): implement clickable short ID links in object titles (cherry picked from commit 680786176ea1176fa26153ae05ae852ec6a91b84) --- datalab/gui/objectview.py | 159 ++++++++++++- datalab/objectmodel.py | 40 ++++ .../common/title_short_id_unit_test.py | 62 ++++++ datalab/widgets/titledelegate.py | 209 ++++++++++++++++++ 4 files changed, 465 insertions(+), 5 deletions(-) create mode 100644 datalab/tests/features/common/title_short_id_unit_test.py create mode 100644 datalab/widgets/titledelegate.py diff --git a/datalab/gui/objectview.py b/datalab/gui/objectview.py index 1fd4891a5..ecb4c0ff9 100644 --- a/datalab/gui/objectview.py +++ b/datalab/gui/objectview.py @@ -46,8 +46,14 @@ from sigima.objects import ImageObj, SignalObj from datalab.config import _ -from datalab.objectmodel import ObjectGroup, get_short_id, get_uuid +from datalab.objectmodel import ( + ObjectGroup, + find_short_ids_in_title, + get_short_id, + get_uuid, +) from datalab.utils.qthelpers import block_signals +from datalab.widgets.titledelegate import ClickableTitleDelegate if TYPE_CHECKING: from typing import Any @@ -97,6 +103,9 @@ def __init__(self, parent: QW.QWidget, objmodel: ObjectModel) -> None: self.itemDoubleClicked.connect(self.item_double_clicked) self.header().setSectionResizeMode(QW.QHeaderView.Interactive) self.itemChanged.connect(lambda item: self.resizeColumnToContents(0)) + self._title_delegate = ClickableTitleDelegate(self) + self.setItemDelegateForColumn(0, self._title_delegate) + self.viewport().setMouseTracking(True) def __str__(self) -> str: """Return string representation""" @@ -201,16 +210,114 @@ def get_sel_groups(self) -> list[ObjectGroup]: """Return selected groups""" return self.objmodel.get_groups(self.get_sel_group_uuids()) - @staticmethod + def _resolve_short_id( + self, short_id: str + ) -> tuple[str, SignalObj | ImageObj | ObjectGroup] | None: + """Resolve a short ID embedded in a title to ``(panel_str, obj)``. + + Default implementation only looks up the tree's own model and returns + an empty ``panel_str``. Subclasses with access to several panels + should override this method. + """ + obj = self.objmodel.find_by_short_id(short_id) + if obj is None: + return None + return ("", obj) + + def _build_short_id_tooltip(self, text: str) -> str: + """Return an HTML tooltip fragment listing the source objects + referenced by short IDs embedded in ``text``, or an empty string when + no such reference is found.""" + matches = find_short_ids_in_title(text) + rows: list[str] = [] + seen: set[str] = set() + for idx, (start, _end, sid) in enumerate(matches): + if idx == 0 and start == 0: + # Skip the leading ":" prefix + continue + if sid in seen: + continue + seen.add(sid) + resolved = self._resolve_short_id(sid) + if resolved is None: + continue + panel_str, obj = resolved + kind = ( + _("group") + if isinstance(obj, ObjectGroup) + else _("signal") + if isinstance(obj, SignalObj) + else _("image") + ) + suffix = f" \u00b7 {panel_str}" if panel_str else "" + rows.append(f"{sid} \u2192 {obj.title} ({kind}{suffix})") + if not rows: + return "" + title = _("Source objects") + return ( + f"

{title}:
" + f"{'
'.join(rows)}

" + ) + def __update_item( - item: QW.QTreeWidgetItem, obj: SignalObj | ImageObj | ObjectGroup + self, item: QW.QTreeWidgetItem, obj: SignalObj | ImageObj | ObjectGroup ) -> None: """Update item""" - item.setText(0, f"{get_short_id(obj)}: {obj.title}") + text = f"{get_short_id(obj)}: {obj.title}" + item.setText(0, text) + tooltip_parts: list[str] = [] + sid_tooltip = self._build_short_id_tooltip(text) + if sid_tooltip: + tooltip_parts.append(sid_tooltip) if isinstance(obj, (SignalObj, ImageObj)): - item.setToolTip(0, metadata_to_html(obj.metadata)) + meta_tooltip = metadata_to_html(obj.metadata) + if meta_tooltip: + tooltip_parts.append(meta_tooltip) + item.setToolTip(0, "".join(tooltip_parts)) item.setData(0, QC.Qt.UserRole, get_uuid(obj)) + def _handle_short_id_click(self, short_id: str) -> None: + """Handle a click on a short-ID hyperlink. Default implementation + selects the matching object within the tree's own model.""" + resolved = self._resolve_short_id(short_id) + if resolved is None: + return + _panel_str, obj = resolved + self.set_current_item_id(get_uuid(obj)) + + def _short_id_at(self, pos: QC.QPoint) -> str | None: + """Return the short ID under viewport position ``pos``, or ``None`` + when the cursor is not over an anchor.""" + index = self.indexAt(pos) + if not index.isValid() or index.column() != 0: + return None + rect = self.visualRect(index) + option = self.viewOptions() + option.rect = rect + return self._title_delegate.anchor_at(index, rect, pos, option) + + # pylint: disable=invalid-name + def mousePressEvent(self, event: QG.QMouseEvent) -> None: + """Reimplement Qt method to handle short-ID hyperlink clicks.""" + if event.button() == QC.Qt.LeftButton: + short_id = self._short_id_at(event.pos()) + if short_id is not None: + event.accept() + self._handle_short_id_click(short_id) + return + super().mousePressEvent(event) + + # pylint: disable=invalid-name + def mouseMoveEvent(self, event: QG.QMouseEvent) -> None: + """Reimplement Qt method to update the cursor over short-ID anchors.""" + short_id = self._short_id_at(event.pos()) + viewport = self.viewport() + if short_id is not None: + viewport.setCursor(QC.Qt.PointingHandCursor) + else: + viewport.unsetCursor() + super().mouseMoveEvent(event) + def populate_tree(self) -> None: """Populate tree with objects""" uuid = self.get_current_item_id() @@ -387,6 +494,48 @@ def __init__(self, parent: BaseDataPanel, objmodel: ObjectModel) -> None: self.__dragged_groups: list[QW.QListWidgetItem] = [] self.__dragged_expanded_states: dict[QW.QListWidgetItem, bool] = {} + def _resolve_short_id( + self, short_id: str + ) -> tuple[str, SignalObj | ImageObj | ObjectGroup] | None: + """Resolve a short ID across the signal *and* image panels of the main + window, so titles can reference objects living in either panel. + """ + panel: BaseDataPanel = self.parent() + mainwindow = getattr(panel, "mainwindow", None) + candidates: list[tuple[str, ObjectModel]] = [] + if mainwindow is not None: + sigpanel = getattr(mainwindow, "signalpanel", None) + if sigpanel is not None: + candidates.append(("signal", sigpanel.objmodel)) + imgpanel = getattr(mainwindow, "imagepanel", None) + if imgpanel is not None: + candidates.append(("image", imgpanel.objmodel)) + else: + candidates.append((panel.PANEL_STR_ID, self.objmodel)) + # Prefer the panel that owns this view (so a self-reference resolves + # locally), then fall back to the other panel. + own = panel.PANEL_STR_ID + candidates.sort(key=lambda c: 0 if c[0] == own else 1) + for panel_str, model in candidates: + obj = model.find_by_short_id(short_id) + if obj is not None: + return (panel_str, obj) + return None + + def _handle_short_id_click(self, short_id: str) -> None: + """Select the referenced object, switching active panel if needed.""" + resolved = self._resolve_short_id(short_id) + if resolved is None: + return + panel_str, obj = resolved + panel: BaseDataPanel = self.parent() + mainwindow = getattr(panel, "mainwindow", None) + if mainwindow is not None and panel_str and panel_str != panel.PANEL_STR_ID: + mainwindow.set_current_panel(panel_str) + mainwindow.select_objects([get_uuid(obj)], panel=panel_str) + else: + self.set_current_item_id(get_uuid(obj)) + def paintEvent(self, event): # pylint: disable=C0103 """Reimplement Qt method""" super().paintEvent(event) diff --git a/datalab/objectmodel.py b/datalab/objectmodel.py index a7b8296d6..5976c3ae2 100644 --- a/datalab/objectmodel.py +++ b/datalab/objectmodel.py @@ -110,6 +110,24 @@ def patch_title_with_ids( ) from exc +#: Regex matching short IDs as embedded in computation titles +#: (e.g. ``s001``, ``i012``, ``gs003``, ``gi007``). +SHORT_ID_REGEX = re.compile(r"\b(g?[si])(\d{3})\b") + + +def find_short_ids_in_title(title: str) -> list[tuple[int, int, str]]: + """Return a list of ``(start, end, short_id)`` tuples for every short ID + occurrence found in ``title``. + + Args: + title: title string to scan + + Returns: + List of ``(start, end, short_id)`` tuples, sorted by ``start``. + """ + return [(m.start(), m.end(), m.group(0)) for m in SHORT_ID_REGEX.finditer(title)] + + class ObjectGroup: """Represents a DataLab object group @@ -292,6 +310,28 @@ def get_object_or_group(self, uuid: str) -> SignalObj | ImageObj | ObjectGroup: return group raise KeyError(f"Object or group with uuid {uuid} not found") + def find_by_short_id( + self, short_id: str + ) -> SignalObj | ImageObj | ObjectGroup | None: + """Return the object or group whose short ID matches ``short_id``, + or ``None`` if no match is found in this model. + + Args: + short_id: short ID to look up (e.g. ``"s001"``, ``"i012"``, + ``"gs003"`` or ``"gi007"``). + + Returns: + The matching :class:`sigima.SignalObj`, :class:`sigima.ImageObj` + or :class:`ObjectGroup` instance, or ``None``. + """ + for group in self._groups: + if get_short_id(group) == short_id: + return group + for obj in self._objects.values(): + if get_short_id(obj) == short_id: + return obj + return None + def get_group(self, uuid: str) -> ObjectGroup: """Return group with uuid""" for group in self._groups: diff --git a/datalab/tests/features/common/title_short_id_unit_test.py b/datalab/tests/features/common/title_short_id_unit_test.py new file mode 100644 index 000000000..23fe3e966 --- /dev/null +++ b/datalab/tests/features/common/title_short_id_unit_test.py @@ -0,0 +1,62 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +""" +Short ID title link unit test. + +Validates the helpers underpinning the clickable short-ID feature in +:mod:`datalab.gui.objectview`: + +- :func:`datalab.objectmodel.find_short_ids_in_title` +- :func:`datalab.widgets.titledelegate._build_html` +""" + +# pylint: disable=invalid-name # Allows short reference names like x, y, ... + +from __future__ import annotations + +from datalab.objectmodel import find_short_ids_in_title +from datalab.widgets.titledelegate import SHORT_ID_URL_SCHEME, _build_html + + +def test_find_short_ids_in_title_basic() -> None: + """``find_short_ids_in_title`` extracts every short ID with its bounds.""" + matches = find_short_ids_in_title("s003: average(s001, s002)") + assert [m[2] for m in matches] == ["s003", "s001", "s002"] + assert matches[0][0] == 0 # leading short ID starts at offset 0 + + +def test_find_short_ids_in_title_mixed_kinds() -> None: + """Image, group and signal short IDs are all detected.""" + matches = find_short_ids_in_title("i012: derived(s001, gi003)") + assert [m[2] for m in matches] == ["i012", "s001", "gi003"] + + +def test_find_short_ids_in_title_no_false_positives() -> None: + """Random ``letter+digits`` patterns are not mistaken for short IDs.""" + # `s12345` has too many digits; `s1` has too few. + assert find_short_ids_in_title("s12345 then s1") == [] + # Substrings inside a word must not match either. + assert find_short_ids_in_title("class s001abc") == [] + + +def test_build_html_skips_leading_short_id() -> None: + """The leading ``s001:`` part is rendered as plain text.""" + html = _build_html("s003: average(s001, s002)") + # Leading "s003" must NOT be wrapped in an anchor + assert html.startswith("s003") + assert f'href="{SHORT_ID_URL_SCHEME}:s003"' not in html + # But s001 and s002 inside the body must be anchors + assert f'href="{SHORT_ID_URL_SCHEME}:s001"' in html + assert f'href="{SHORT_ID_URL_SCHEME}:s002"' in html + + +def test_build_html_escapes_text() -> None: + """Surrounding text is HTML-escaped to avoid markup injection.""" + html = _build_html("s003: & friends") + assert "<not a tag>" in html + assert "&" in html + + +def test_build_html_no_short_ids_returns_plain_text() -> None: + """Without short IDs, the output is just the escaped text.""" + assert _build_html("Just a title") == "Just a title" diff --git a/datalab/widgets/titledelegate.py b/datalab/widgets/titledelegate.py new file mode 100644 index 000000000..7930d1525 --- /dev/null +++ b/datalab/widgets/titledelegate.py @@ -0,0 +1,209 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +""" +Title delegate +============== + +The :mod:`datalab.widgets.titledelegate` module provides a +:class:`QStyledItemDelegate` that renders object tree titles as rich text and +turns embedded short IDs (e.g. ``s001``, ``i012``) into clickable hyperlinks. + +.. autoclass:: ClickableTitleDelegate +""" + +# pylint: disable=invalid-name # Allows short reference names like x, y, ... + +from __future__ import annotations + +from html import escape +from typing import TYPE_CHECKING + +from qtpy import QtCore as QC +from qtpy import QtGui as QG +from qtpy import QtWidgets as QW + +from datalab.objectmodel import find_short_ids_in_title + +if TYPE_CHECKING: + pass + + +#: URL scheme used in anchors emitted by :class:`ClickableTitleDelegate`. +SHORT_ID_URL_SCHEME = "dlb-shortid" + + +def _build_html(text: str) -> str: + """Build the HTML representation of ``text`` with short IDs wrapped in + anchors. + + The first short ID occurrence is always rendered as plain text: object + titles in DataLab tree views are formatted as ``": "`` and + making the leading ``s001`` clickable would just re-select the current + item. + + Args: + text: raw item text (e.g. ``"s003: average(s001, s002)"``). + + Returns: + HTML string. + """ + matches = find_short_ids_in_title(text) + if not matches: + return escape(text) + out: list[str] = [] + cursor = 0 + for idx, (start, end, sid) in enumerate(matches): + out.append(escape(text[cursor:start])) + if idx == 0 and start == 0: + # Leading "s001:" — keep as plain text + out.append(escape(sid)) + else: + out.append(f'<a href="{SHORT_ID_URL_SCHEME}:{sid}">{escape(sid)}</a>') + cursor = end + out.append(escape(text[cursor:])) + return "".join(out) + + +def _make_text_document( + text: str, + option: QW.QStyleOptionViewItem, + link_color: QG.QColor, + text_color: QG.QColor | None = None, +) -> QG.QTextDocument: + """Return a :class:`QTextDocument` rendering ``text`` with the styling + inherited from ``option``. + + ``link_color`` (and optionally ``text_color``) are baked into the + document's default style sheet, because :class:`QTextDocument` resolves + anchor colors at parse time — the painting palette has no effect on + them. + """ + doc = QG.QTextDocument() + doc.setDefaultFont(option.font) + doc.setDocumentMargin(0) + css_parts = [f"a {{ color: {link_color.name()}; text-decoration: underline; }}"] + if text_color is not None: + css_parts.append(f"body, p, span {{ color: {text_color.name()}; }}") + doc.setDefaultStyleSheet(" ".join(css_parts)) + doc.setHtml(_build_html(text)) + return doc + + +class ClickableTitleDelegate(QW.QStyledItemDelegate): + """Item delegate that renders object titles with clickable short IDs. + + The delegate uses a :class:`QTextDocument` to render an HTML version of the + item's display text in which each embedded short ID — apart from the + leading one — is wrapped in an anchor pointing at ``dlb-shortid:<id>``. + + Hit-testing is performed by :meth:`anchor_at`, which is meant to be called + from the host view's ``mousePressEvent`` / ``mouseMoveEvent``. + """ + + def __init__(self, parent: QW.QAbstractItemView) -> None: + super().__init__(parent) + + # pylint: disable=invalid-name + def paint( + self, + painter: QG.QPainter, + option: QW.QStyleOptionViewItem, + index: QC.QModelIndex, + ) -> None: + """Reimplement Qt method to paint the item via a QTextDocument.""" + text = index.data(QC.Qt.DisplayRole) or "" + if not isinstance(text, str) or not find_short_ids_in_title(text): + super().paint(painter, option, index) + return + opt = QW.QStyleOptionViewItem(option) + self.initStyleOption(opt, index) + # Let the style draw the background, focus rect and decoration + # (icon), but not the text. + opt.text = "" + style = opt.widget.style() if opt.widget else QW.QApplication.style() + style.drawControl(QW.QStyle.CE_ItemViewItem, opt, painter, opt.widget) + + text_rect = style.subElementRect(QW.QStyle.SE_ItemViewItemText, opt, opt.widget) + palette = option.palette + selected = bool(option.state & QW.QStyle.State_Selected) + # ``QPalette.Highlight`` is the theme's accent color (vivid in both + # light and dark modes) — much more readable than the default + # ``QPalette.Link`` role, which many themes leave at Qt's hard-coded + # dark blue. + accent = palette.color(QG.QPalette.Active, QG.QPalette.Highlight) + if selected: + text_color = palette.color(QG.QPalette.Active, QG.QPalette.HighlightedText) + # On dark themes the selection background *is* the accent color, + # so a plain accent-colored link would vanish: blend it 50/50 + # with ``HighlightedText`` (typically white) to obtain a lighter + # tint that still reads as the same hue. On light themes the + # accent stays distinguishable on the highlight background, so + # we keep the unselected color for visual consistency. + base_is_light = ( + palette.color(QG.QPalette.Active, QG.QPalette.Base).lightness() > 128 + ) + if base_is_light: + link_color = accent + else: + link_color = QG.QColor( + (accent.red() + text_color.red()) // 2, + (accent.green() + text_color.green()) // 2, + (accent.blue() + text_color.blue()) // 2, + ) + else: + text_color = palette.color(QG.QPalette.Active, QG.QPalette.Text) + link_color = accent + doc = _make_text_document(text, option, link_color, text_color) + doc.setTextWidth(text_rect.width()) + painter.save() + painter.translate(text_rect.topLeft()) + ctx = QG.QAbstractTextDocumentLayout.PaintContext() + clip = QC.QRectF(0, 0, text_rect.width(), text_rect.height()) + ctx.clip = clip + painter.setClipRect(clip) + doc.documentLayout().draw(painter, ctx) + painter.restore() + + # pylint: disable=invalid-name + def sizeHint( + self, option: QW.QStyleOptionViewItem, index: QC.QModelIndex + ) -> QC.QSize: + """Reimplement Qt method to size items consistently with default text + rendering.""" + return super().sizeHint(option, index) + + def anchor_at( + self, + index: QC.QModelIndex, + item_rect: QC.QRect, + pos: QC.QPoint, + option: QW.QStyleOptionViewItem, + ) -> str | None: + """Return the short ID under cursor position ``pos`` (in viewport + coordinates) for ``index``, or ``None`` if the cursor is not over any + anchor. + + Args: + index: model index of the item under cursor + item_rect: visual rectangle of the item in the viewport + pos: cursor position in viewport coordinates + option: style option (already initialized for the item) + """ + text = index.data(QC.Qt.DisplayRole) or "" + if not isinstance(text, str) or not find_short_ids_in_title(text): + return None + opt = QW.QStyleOptionViewItem(option) + opt.rect = item_rect + self.initStyleOption(opt, index) + style = opt.widget.style() if opt.widget else QW.QApplication.style() + text_rect = style.subElementRect(QW.QStyle.SE_ItemViewItemText, opt, opt.widget) + if not text_rect.contains(pos): + return None + # Color does not influence hit-testing — pass any value. + doc = _make_text_document(text, option, QG.QColor("black")) + doc.setTextWidth(text_rect.width()) + local = QC.QPointF(pos - text_rect.topLeft()) + href = doc.documentLayout().anchorAt(local) + if href and href.startswith(f"{SHORT_ID_URL_SCHEME}:"): + return href[len(SHORT_ID_URL_SCHEME) + 1 :] + return None From 5100ee5fe0a61c11cd67c4e4743eb704fa6182d5 Mon Sep 17 00:00:00 2001 From: Pierre Raybaut <pierre.raybaut@gmail.com> Date: Sun, 17 May 2026 12:31:00 +0200 Subject: [PATCH 017/108] feat(translations): update French translations for various UI elements and add new history panel entries --- datalab/locale/fr/LC_MESSAGES/datalab.po | 116 ++++++++++++----------- 1 file changed, 62 insertions(+), 54 deletions(-) diff --git a/datalab/locale/fr/LC_MESSAGES/datalab.po b/datalab/locale/fr/LC_MESSAGES/datalab.po index 73cc817ff..7e49681a5 100644 --- a/datalab/locale/fr/LC_MESSAGES/datalab.po +++ b/datalab/locale/fr/LC_MESSAGES/datalab.po @@ -162,6 +162,7 @@ msgstr "Supprimer" msgid "Rename" msgstr "Renommer" + msgid "Rename the selected conversation (F2)." msgstr "Renommer la conversation sélectionnée (F2)." @@ -583,7 +584,7 @@ msgid "Show results" msgstr "Afficher les résultats" msgid "Results label" -msgstr "Etiquette des résultats" +msgstr "Étiquette des résultats" msgid "Show or hide the merged result label on the plot" msgstr "Afficher ou masquer l'étiquette de résultat fusionnée sur le graphique" @@ -1304,9 +1305,8 @@ msgstr "Métadonnées de l'objet" msgid "(click on Metadata button for more details)" msgstr "(cliquer sur le bouton Métadonnées pour plus de détails)" -#, fuzzy msgid "group" -msgstr "Groupe" +msgstr "groupe" msgid "Source objects" msgstr "Objets source" @@ -1472,7 +1472,7 @@ msgid "Conversion" msgstr "Conversion" msgid "Duplicate object or group" -msgstr "Dupliquer l'objet ou le groupe %s" +msgstr "Dupliquer l'objet ou le groupe" msgid "Select what to keep from the clipboard.<br><br>Result shapes and annotations, if kept, will be merged with existing ones. <u>All other metadata will be replaced</u>." msgstr "Sélectionnez ce que vous souhaitez conserver dans le presse-papier.<br><br>Les formes graphiques et les annotations, si conservées, seront fusionnées avec celles existantes. <u>Toutes les autres métadonnées seront remplacées</u>." @@ -1640,34 +1640,6 @@ msgstr "Annotation ajoutée" msgid "The label has been added as an annotation. You can edit or remove it using the annotation editing window.<br><br>Choosing to ignore this message will prevent it from being displayed again." msgstr "L'étiquette a été ajoutée comme annotation. Vous pouvez la modifier ou la supprimer en utilisant la fenêtre d'édition des annotations.<br><br>Ignorer ce message empêchera son affichage ultérieur." -msgid "Console toolbar" -msgstr "Barre d'outils de la console" - -msgid "Clear console" -msgstr "Effacer la console" - -msgid "Export console output to file..." -msgstr "Exporter la sortie console vers un fichier..." - -msgid "↓ Resume autoscroll" -msgstr "↓ Reprendre le défilement" - -msgid "Export console" -msgstr "Exporter la console" - -msgid "Recent macros" -msgstr "Macros récentes" - -msgid "Clear all" -msgstr "Tout effacer" - -#, fuzzy -msgid "Untitled" -msgstr "(sans titre)" - -msgid "Clear all recent macros?" -msgstr "Effacer toutes les macros récentes ?" - #, python-format msgid "Failed to deserialize history DataSet kwarg %r." msgstr "Échec de la désérialisation de l'argument DataSet de l'historique %r." @@ -1696,11 +1668,58 @@ msgstr "Date et heure" msgid "Description" msgstr "Description" + msgid "Title" msgstr "Titre" + +msgid "History panel" +msgstr "Panneau d'historique" + +msgid "Edit mode" +msgstr "Mode d'édition" + +msgid "Record mode" +msgstr "Mode d'enregistrement" + +msgid "Replay" +msgstr "Rejouer" + +msgid "Restore selection" +msgstr "Restaurer la sélection" + +msgid "Restore selection and replay" +msgstr "Restaurer la sélection et rejouer" + +msgid "The current workspace state is not compatible with the action." +msgstr "L'état actuel de l'espace de travail n'est pas compatible avec l'action." + +msgid "Delete actions" +msgstr "Supprimer les actions" + +msgid "Do you really want to delete the selected action and all the next ones?" +msgstr "Voulez-vous vraiment supprimer l'action sélectionnée et toutes les suivantes ?" + +msgid "New image" +msgstr "Nouvelle image" + +msgid "Recent macros" +msgstr "Macros récentes" + +msgid "Clear all" +msgstr "Tout effacer" + +msgid "Untitled" +msgstr "Sans titre" + +msgid "Clear all recent macros?" +msgstr "Effacer toutes les macros récentes ?" + msgid "Macro panel" msgstr "Panneau des macros" +msgid "Clear console" +msgstr "Effacer la console" + msgid "-***- Macro Console -***-" msgstr "-***- Console des macros -***-" @@ -1749,7 +1768,6 @@ msgstr "● Macro en cours d'exécution" msgid "○ Idle" msgstr "○ Inactif" -#, python-format msgid "Restore unsaved macros" msgstr "Restaurer les macros non enregistrées" @@ -2484,7 +2502,7 @@ msgid "Allan variance" msgstr "Variance d'Allan" msgid "Allan deviation" -msgstr "Ecart-type d'Allan" +msgstr "Écart-type d'Allan" msgid "Overlapping Allan variance" msgstr "Variance d’Allan avec recouvrement" @@ -2499,7 +2517,7 @@ msgid "Total variance" msgstr "Variance totale" msgid "Time deviation" -msgstr "Ecart-type temporel" +msgstr "Écart-type temporel" msgid "X-Y mode" msgstr "Mode X-Y" @@ -2983,31 +3001,31 @@ msgid "Maximum number of columns to display in merged result label." msgstr "Nombre maximum de colonnes à afficher dans l'étiquette de résultat fusionnée." msgid "Show the merged result label by default" -msgstr "Afficher le titre de résultat fusionné par défaut" +msgstr "Afficher l'étiquette de résultat fusionnée par défaut" msgid "Result label" msgstr "Étiquette des résultats" msgid "Show the merged result label on the plot by default. Can be toggled per-object using the checkbox in the Properties panel." -msgstr "Etiquette des résultats fusionnés sur le graphique par défaut. Peut être activée ou désactivée par objet à l'aide de la case à cocher dans le panneau des propriétés." +msgstr "Afficher l'étiquette des résultats fusionnés sur le graphique par défaut. Peut être activée ou désactivée par objet à l'aide de la case à cocher dans le panneau des propriétés." msgid "Show marker labels in result tables" -msgstr "" +msgstr "Afficher les étiquettes de marqueurs dans les tables de résultats" msgid "Marker labels" -msgstr "Etiquettes des marqueurs" +msgstr "Étiquettes des marqueurs" msgid "Prepend a marker-label column to result tables for marker results (XY/X/Y markers), so each row can be matched with the corresponding cross or dashed cursor drawn on the plot. XY markers use numeric labels (#1, #2, ...), axis markers use letters (a, b, c, ...)." msgstr "Ajouter une colonne d'étiquettes de marqueurs aux tables de résultats pour les résultats de marqueurs (marqueurs XY/X/Y), afin que chaque ligne puisse être associée au curseur croisé ou en pointillés correspondant dessiné sur le graphique. Les marqueurs XY utilisent des étiquettes numériques (#1, #2, ...), les marqueurs d'axe utilisent des lettres (a, b, c, ...)." msgid "Process isolation enable status" -msgstr "Etat d'activation de l'isolation de processus" +msgstr "État d'activation de l'isolation de processus" msgid "RPC server enable status" -msgstr "Etat d'activation du serveur XML-RPC" +msgstr "État d'activation du serveur XML-RPC" msgid "Console enable status" -msgstr "Etat d'activation de la console" +msgstr "État d'activation de la console" msgid "Third-party plugins path" msgstr "Chemin des plugins tiers" @@ -3453,7 +3471,7 @@ msgid "Base line" msgstr "Ligne de base" msgid "Std-dev" -msgstr "Ecart-type" +msgstr "Écart-type" msgid "Mean" msgstr "Moyenne" @@ -3560,9 +3578,6 @@ msgstr "Afficher le tableau" msgid "Path" msgstr "Chemin" -msgid "Description" -msgstr "Description" - msgid "Textual preview" msgstr "Aperçu textuel" @@ -3844,9 +3859,6 @@ msgstr "Tout sélectionner" msgid "Adding data to the plot" msgstr "Ajout des données au graphique" -msgid "Title" -msgstr "Titre" - msgid "X label" msgstr "Titre X" @@ -3872,7 +3884,7 @@ msgid "Set the labels and units for the imported data" msgstr "Définir les titres et unités pour les données importées" msgid "The following title, labels and units will be applied to the data.<br><br><i><u>Note</u>: Leave empty the labels and units to keep the default values (i.e. the values which were inferred from the data).</i>" -msgstr "Les titres, étiquettes et unités suivants seront appliqués aux données.<br><br><i><u>Note</u> : Laisser vide les étiquettes et unités pour conserver les valeurs par défaut (c'est-à-dire les valeurs qui ont été déduites des données)." +msgstr "Les titres, étiquettes et unités suivants seront appliqués aux données.<br><br><i><u>Note</u> : Laisser vide les étiquettes et unités pour conserver les valeurs par défaut (c'est-à-dire les valeurs qui ont été déduites des données).</i>" msgid "clipboard" msgstr "presse-papiers" @@ -3907,9 +3919,6 @@ msgstr "Merci de cliquer sur le bouton 'Ignorer' pour ignorer cet avertissement msgid "Back" msgstr "Précédent" -msgid "Next" -msgstr "Suivant" - msgid "Finish" msgstr "Terminer" @@ -3987,4 +3996,3 @@ msgstr "Aucun contour n'a été trouvé pour la plage de niveaux sélectionnée. msgid "Show contour plot..." msgstr "Afficher le tracé de contours..." - From 03c7bbc5d41eb0dc4f5b7ce1d271860075d5fcfc Mon Sep 17 00:00:00 2001 From: Pierre Raybaut <p.raybaut@codra.fr> Date: Tue, 19 May 2026 13:30:01 +0200 Subject: [PATCH 018/108] Fix pylint warnings --- datalab/gui/panel/history.py | 25 ++++++++----------- .../tests/features/common/history_app_test.py | 3 +++ .../common/history_replay_app_test.py | 2 ++ 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/datalab/gui/panel/history.py b/datalab/gui/panel/history.py index b7d764a64..ac043afb8 100644 --- a/datalab/gui/panel/history.py +++ b/datalab/gui/panel/history.py @@ -10,12 +10,15 @@ import functools import html +import inspect import os import warnings from contextlib import contextmanager from typing import TYPE_CHECKING, Any, Callable, Generator from uuid import uuid4 +import sigima.proc.image +import sigima.proc.signal from guidata.configtools import get_icon from guidata.dataset.conv import dataset_to_json, json_to_dataset from guidata.dataset.datatypes import DataSet @@ -107,14 +110,16 @@ def get_datetime_str() -> str: return QC.QDateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss") -def add_to_history(kwargs_names: list[str] = [], title: str | None = None): +def add_to_history(kwargs_names: list[str] | None = None, title: str | None = None): """Method decorator to add the method call to the history panel as a UI entry. Args: kwargs_names: List of keyword arguments to add to the history action. - Defaults to []. + Defaults to None. title: Title of the history action. Defaults to None. """ + if kwargs_names is None: + kwargs_names = [] def add_to_history_decorator(func): """Decorator function""" @@ -333,13 +338,7 @@ def _resolve_panel(self, mainwindow: DLMainWindow): def _resolve_callable(self) -> Callable | None: """Best-effort lookup of the underlying callable, for description only.""" if self.kind == self.KIND_COMPUTE and self.func_name: - try: - # Lazy import to avoid cycles at module import time. - import sigima.proc.image as sigimg # noqa: F401 - import sigima.proc.signal as sigsig # noqa: F401 - except Exception: # pylint: disable=broad-except - return None - for module in (sigsig, sigimg): + for module in (sigima.proc.signal, sigima.proc.image): func = getattr(module, self.func_name, None) if callable(func): return func @@ -467,8 +466,6 @@ def _replay_ui(self, mainwindow: DLMainWindow, edit: bool) -> None: call_kwargs = dict(self.kwargs) # Inject edit mode if the method supports it try: - import inspect - sig = inspect.signature(method) if self.FUNC_EDIT_MODE in sig.parameters: call_kwargs[self.FUNC_EDIT_MODE] = edit @@ -626,7 +623,7 @@ def save(self, mainwindow: DLMainWindow) -> None: obj.title for obj in panel.objmodel if get_uuid(obj) in sel_uuids ] - def is_current_state_compatible( + def is_current_state_compatible( # pylint: disable=unused-argument self, mainwindow: DLMainWindow, restore_selection: bool ) -> bool: """Check if the current workspace state is compatible with the saved state. @@ -1379,8 +1376,7 @@ def __getitem__(self, nb: int) -> HistoryAction: def __iter__(self) -> Generator[HistoryAction, None, None]: """Iterate over objects""" for session in self.__history_sessions: - for action in session.actions: - yield action + yield from session.actions def create_new_session(self) -> None: """Create a new history list""" @@ -1507,7 +1503,6 @@ def add_entry( action_title: str, save_state: bool, func: Callable, - *args, **kwargs, ) -> None: """Legacy entry-point kept as a compatibility shim. diff --git a/datalab/tests/features/common/history_app_test.py b/datalab/tests/features/common/history_app_test.py index 98089055e..bf50d08e3 100644 --- a/datalab/tests/features/common/history_app_test.py +++ b/datalab/tests/features/common/history_app_test.py @@ -170,11 +170,14 @@ def test_history_app(): # underlying ``HistorySession.remove_action`` path used by it. target = new_session_entry target_session: HistorySession | None = None + + # pylint: disable=protected-access for session in history._HistoryPanel__history_sessions: # noqa: SLF001 if target in session.actions: target_session = session break assert target_session is not None + n_before = len(history) target_session.remove_action(target) assert len(history) < n_before diff --git a/datalab/tests/features/common/history_replay_app_test.py b/datalab/tests/features/common/history_replay_app_test.py index a900d5982..6b349d43b 100644 --- a/datalab/tests/features/common/history_replay_app_test.py +++ b/datalab/tests/features/common/history_replay_app_test.py @@ -387,6 +387,7 @@ def test_full_session_replay_remaps_uuids_for_n_to_1(): panel.processor.run_feature(sips.average) assert len(panel.objmodel) == 4 + # pylint: disable=protected-access session = history._HistoryPanel__history_sessions[-1] # noqa: SLF001 # Reset to an empty workspace, then replay the whole session. @@ -422,6 +423,7 @@ def test_full_session_replay_with_intermediate_removal(): panel.processor.run_feature(sips.average) assert len(panel.objmodel) == 3 + # pylint: disable=protected-access session = history._HistoryPanel__history_sessions[-1] # noqa: SLF001 # Reset to an empty workspace, then replay the whole session. From d5eae1e834d2ad5b835ac0bc9aea11ad6d95e1be Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Wed, 3 Jun 2026 13:05:09 +0200 Subject: [PATCH 019/108] Update History Panel --- datalab/gui/main.py | 4 +- datalab/gui/panel/base.py | 288 ++- datalab/gui/panel/history.py | 3670 +++++++++++++++++++++++++++++++-- datalab/gui/processor/base.py | 1176 +++++++---- datalab/h5/native.py | 2 +- 5 files changed, 4569 insertions(+), 571 deletions(-) diff --git a/datalab/gui/main.py b/datalab/gui/main.py index cb579a769..709604cd7 100644 --- a/datalab/gui/main.py +++ b/datalab/gui/main.py @@ -2018,8 +2018,10 @@ def toggle_show_first_only(self, state: bool) -> None: def reset_all(self) -> None: """Reset all application data""" for panel in self.panels: - if panel is not None: + if panel is not None and panel is not self.historypanel: panel.remove_all_objects() + if self.historypanel is not None: + self.historypanel.start_new_session_after_workspace_reset() @remote_controlled def remove_object(self, force: bool = False) -> None: diff --git a/datalab/gui/panel/base.py b/datalab/gui/panel/base.py index 4e960467a..810d75d2e 100644 --- a/datalab/gui/panel/base.py +++ b/datalab/gui/panel/base.py @@ -9,6 +9,7 @@ from __future__ import annotations import abc +import copy import glob import os import os.path as osp @@ -90,6 +91,7 @@ get_number, get_short_id, get_uuid, + patch_title_with_ids, set_number, set_uuid, ) @@ -207,6 +209,13 @@ def __init__(self, panel: BaseDataPanel, objclass: SignalObj | ImageObj) -> None self.processing_param_editor: gdq.DataSetEditGroupBox | None = None self.current_processing_obj: SignalObj | ImageObj | None = None self.processing_scroll: QW.QScrollArea | None = None + # Auto-recompute toggle (session-only state, not persisted to Conf). + self.__auto_recompute_enabled: bool = False + self.__auto_recompute_timer = QC.QTimer(self) + self.__auto_recompute_timer.setSingleShot(True) + self.__auto_recompute_timer.timeout.connect( + self.__auto_recompute_trigger + ) # Properties tab self.properties = gdq.DataSetEditGroupBox("", objclass) @@ -725,6 +734,23 @@ def setup_processing_tab( editor.SIG_APPLY_BUTTON_CLICKED.connect(self.apply_processing_parameters) editor.set_apply_button_state(False) + # Hook into the per-edit change callback to support auto-recompute. + # ``DataSetEditLayout.change_callback`` is called whenever any widget + # value changes; wrap it so we can also (re)start the debounce timer. + try: + inner_layout = editor.edit # DataSetEditLayout instance + original_change_cb = inner_layout.change_callback + + def _wrapped_change_cb() -> None: + if original_change_cb is not None: + original_change_cb() + if self.__auto_recompute_enabled: + self.__auto_recompute_timer.start(300) + + inner_layout.change_callback = _wrapped_change_cb + except AttributeError: + pass + # Store reference to be able to retrieve it later self.processing_param_editor = editor @@ -751,7 +777,21 @@ def setup_processing_tab( QW.QSizePolicy.Expanding, QW.QSizePolicy.Preferred ) - self.processing_scroll.setWidget(editor) + # Build the tab content: editor + "Auto-recompute" checkbox. + container = QW.QWidget() + vbox = QW.QVBoxLayout(container) + vbox.setContentsMargins(0, 0, 0, 0) + vbox.addWidget(editor) + auto_cb = QW.QCheckBox(_("Auto-recompute on edit"), container) + auto_cb.setToolTip( + _("Automatically re-run processing when parameters are modified") + ) + auto_cb.setChecked(self.__auto_recompute_enabled) + auto_cb.toggled.connect(self.__set_auto_recompute_enabled) + vbox.addWidget(auto_cb) + vbox.addStretch(1) + + self.processing_scroll.setWidget(container) self.tabwidget.insertTab( insert_index, self.processing_scroll, @@ -781,6 +821,24 @@ def __get_processor_associated_to( return self.panel.mainwindow.signalpanel.processor return self.panel.mainwindow.imagepanel.processor + def __set_auto_recompute_enabled(self, enabled: bool) -> None: + """Toggle auto-recompute mode (session-only, not persisted).""" + self.__auto_recompute_enabled = bool(enabled) + if not self.__auto_recompute_enabled: + self.__auto_recompute_timer.stop() + + def __auto_recompute_trigger(self) -> None: + """Debounced callback: push widget values then re-run processing.""" + if not self.__auto_recompute_enabled: + return + editor = self.processing_param_editor + if editor is None: + return + # ``editor.set()`` synchronises widget values to the dataset and emits + # ``SIG_APPLY_BUTTON_CLICKED`` which is already wired to + # ``apply_processing_parameters``. + editor.set(check=False) + def apply_processing_parameters( self, obj: SignalObj | ImageObj | None = None, interactive: bool = True ) -> ProcessingReport: @@ -864,49 +922,116 @@ def apply_processing_parameters( else: report.success = True - # Update the current object in-place with data from new object - obj.title = new_obj.title - if isinstance(obj, SignalObj): - obj.xydata = new_obj.xydata - else: # ImageObj - obj.data = new_obj.data - # Invalidate ROI mask cache when image dimensions may have changed - # (the mask is computed based on image shape, so it must be recomputed) - obj.invalidate_maskdata_cache() - - # Update metadata with new processing parameters - updated_proc_params = ProcessingParameters( - func_name=proc_params.func_name, - pattern=proc_params.pattern, - param=param, - source_uuid=proc_params.source_uuid, - ) - insert_processing_parameters(obj, updated_proc_params) - - # Auto-recompute analysis if the object had analysis parameters - # Since the data has changed, any analysis results are now invalid - # Use the processor for the current object's type (not source object's type) - obj_processor = self.__get_processor_associated_to(obj) - obj_processor.auto_recompute_analysis(obj) - - # Update the tree view item and refresh plot - obj_uuid = get_uuid(obj) - self.panel.objview.update_item(obj_uuid) - self.panel.refresh_plot(obj_uuid, update_items=True, force=True) - - # Update the Properties tab to reflect the new object properties - # (e.g., data type, dimensions, etc.) - self.__update_properties_dataset(obj) - - # Refresh the Processing tab with the new parameters - # Don't reset parameters from source object - keep the user's values - # Set the Processing tab as current to keep it visible after refresh - QC.QTimer.singleShot( - 0, - lambda: self.setup_processing_tab( - obj, reset_params=False, set_current=True - ), - ) + hpanel = getattr(self.panel.mainwindow, "historypanel", None) + is_edit_mode = hpanel is not None and hpanel.is_edit_mode() + + if is_edit_mode: + # --- Edit mode: mutate obj in-place, cascade downstream --- + + # Update the current object in-place with data from new object + obj.title = new_obj.title + if isinstance(obj, SignalObj): + obj.xydata = new_obj.xydata + else: # ImageObj + obj.data = new_obj.data + # Invalidate ROI mask cache when image dimensions may + # have changed (mask depends on image shape) + obj.invalidate_maskdata_cache() + + # Update metadata with new processing parameters + updated_proc_params = ProcessingParameters( + func_name=proc_params.func_name, + pattern=proc_params.pattern, + param=param, + source_uuid=proc_params.source_uuid, + ) + insert_processing_parameters(obj, updated_proc_params) + + # Propagate the edited param to the History panel: + # Mutate the matching existing action (snapshot originals + # first), refresh its tree display, then cascade recompute + # to downstream actions so the chain stays consistent with + # the new parameters. + action = hpanel.find_action_for_output( + get_uuid(obj), proc_params.func_name + ) + if action is not None: + action.snapshot_kwargs() + action.kwargs["param"] = copy.deepcopy(param) + hpanel.refresh_action(action) + hpanel.recompute_cascade(action) + + # Auto-recompute analysis (data changed, results invalid) + obj_processor = self.__get_processor_associated_to(obj) + obj_processor.auto_recompute_analysis(obj) + + # Update the tree view item and refresh plot + obj_uuid = get_uuid(obj) + self.panel.objview.update_item(obj_uuid) + self.panel.refresh_plot(obj_uuid, update_items=True, force=True) + + # Update the Properties tab to reflect the new object + self.__update_properties_dataset(obj) + # Refresh the displayed processing history (Properties tab + # description) so the parameter change is visible immediately + self.display_processing_history(obj) + + # Refresh the Processing tab with the new parameters + QC.QTimer.singleShot( + 0, + lambda: self.setup_processing_tab( + obj, reset_params=False, set_current=True + ), + ) + else: + # --- Non-edit mode: create a new independent object --- + + # Patch title with source object IDs (like menu-driven compute) + patch_title_with_ids(new_obj, [obj], get_short_id) + + # Store processing metadata on the new object + # pylint: disable=import-outside-toplevel + from datalab.gui.processor.base import ( + build_processing_parameters, + ) + + new_pp = build_processing_parameters( + proc_params.func_name, + proc_params.pattern, + param=copy.deepcopy(param), + source_uuid=proc_params.source_uuid, + ) + insert_processing_parameters(new_obj, new_pp) + + # Mark as freshly processed so the Processing tab is shown + self.mark_as_freshly_processed(new_obj) + + # Add the new object to the same group as the source object + group_id = self.panel.objmodel.get_object_group_id(obj) + self.panel.add_object(new_obj, group_id=group_id, set_current=True) + + # Record a brand-new history entry with the new object UUID + if hpanel is not None: + # Retrieve plugin_origin so replay without the plugin + # produces a rich error message (C3) instead of generic. + plugin_origin = None + try: + processor = self.__get_processor_associated_to(new_obj) + feature = processor.get_feature(proc_params.func_name) + plugin_origin = feature.plugin_origin + except (ValueError, AttributeError): + pass + hpanel.add_compute_entry_from_pp( + new_obj.title, + new_pp, + panel_str=self.panel.PANEL_STR_ID, + output_uuids=[get_uuid(new_obj)], + plugin_origin=plugin_origin, + ) + + # Auto-recompute analysis on the new object + obj_processor = self.__get_processor_associated_to(new_obj) + obj_processor.auto_recompute_analysis(new_obj) if isinstance(obj, SignalObj): report.message = _("Signal was reprocessed.") @@ -932,6 +1057,7 @@ class AbstractPanel(QW.QSplitter, metaclass=AbstractPanelMeta): H5_PREFIX = "" SIG_OBJECT_ADDED = QC.Signal() SIG_OBJECT_REMOVED = QC.Signal() + SIG_OBJECT_MODIFIED = QC.Signal() @abc.abstractmethod def __init__(self, parent): @@ -1117,7 +1243,7 @@ def on_button_click( """, ] ) - NonModalInfoDialog(parent, "Pattern help", text).show() + NonModalInfoDialog(parent, _("Pattern help"), text).show() def get_extension_choices(self, _item=None, _value=None): """Return list of available extensions for choice item.""" @@ -1258,7 +1384,7 @@ def on_help_button_click( """, ] ) - NonModalInfoDialog(parent, "Pattern help", text).show() + NonModalInfoDialog(parent, _("Pattern help"), text).show() def get_conversion_choices(self, _item=None, _value=None): """Return list of available conversion choices.""" @@ -1592,6 +1718,7 @@ def set_object(self, obj: TypeObj) -> None: # immediately if the modified object is currently selected. self.objview.item_selection_changed() self.refresh_plot("selected", update_items=True, force=True) + self.SIG_OBJECT_MODIFIED.emit() def remove_all_objects(self) -> None: """Remove all objects""" @@ -1859,6 +1986,14 @@ def add_metadata(self, param: AddMetadataParam | None = None) -> None: # Save settings to config Conf.io.add_metadata_settings.set(param) + self.mainwindow.historypanel.add_ui_entry( + _("Add metadata"), + target=self.PANEL_STR_ID + "panel", + method_name="add_metadata", + save_state=True, + param=param, + ) + # Build values for all selected objects values = param.build_values(sel_objects) @@ -1871,19 +2006,49 @@ def add_metadata(self, param: AddMetadataParam | None = None) -> None: "selected", update_items=True, only_visible=False, only_existing=True ) - def copy_roi(self) -> None: - """Copy regions of interest""" - obj = self.objview.get_sel_objects()[0] - self.__roi_clipboard = obj.roi.copy() + def copy_roi(self, roi_data=None) -> None: + """Copy regions of interest - def paste_roi(self) -> None: - """Paste regions of interest""" + Args: + roi_data: ROI snapshot for replay. When ``None`` (interactive use), + the ROI is read from the currently selected object. + """ + if roi_data is None: + obj = self.objview.get_sel_objects()[0] + roi_data = obj.roi.copy() + self.__roi_clipboard = roi_data.copy() + self.mainwindow.historypanel.add_ui_entry( + _("Copy regions of interest from selected %s") + % (_("signal") if self.PANEL_STR_ID == "signal" else _("image")), + target=self.PANEL_STR_ID + "panel", + method_name="copy_roi", + save_state=True, + roi_data=roi_data, + ) + + def paste_roi(self, roi_data=None) -> None: + """Paste regions of interest + + Args: + roi_data: ROI snapshot for replay. When ``None`` (interactive use), + the clipboard populated by :meth:`copy_roi` is used. + """ + if roi_data is None: + roi_data = self.__roi_clipboard + self.mainwindow.historypanel.add_ui_entry( + _("Paste regions of interest into selected %s") + % (_("signal") if self.PANEL_STR_ID == "signal" else _("image")), + target=self.PANEL_STR_ID + "panel", + method_name="paste_roi", + save_state=True, + roi_data=roi_data, + ) sel_objects = self.objview.get_sel_objects(include_groups=True) for obj in sel_objects: if obj.roi is None: - obj.roi = self.__roi_clipboard.copy() + obj.roi = roi_data.copy() else: - obj.roi = obj.roi.combine_with(self.__roi_clipboard) + obj.roi = obj.roi.combine_with(roi_data) self.selection_changed(update_items=True) self.refresh_plot( "selected", update_items=True, only_visible=False, only_existing=True @@ -1905,11 +2070,15 @@ def remove_object(self, force: bool = False) -> None: ) if answer == QW.QMessageBox.No: return + # IMPORTANT: save_state=True is required so that the selection of objects + # being deleted is captured. On replay, the captured selection (translated + # through uuid_remap) is restored before remove_object runs, ensuring that + # the correct object is removed instead of whatever is currently selected. self.mainwindow.historypanel.add_ui_entry( _("Remove selected objects"), target=self.PANEL_STR_ID + "panel", method_name="remove_object", - save_state=False, + save_state=True, force=force, ) sel_objects = self.objview.get_sel_objects(include_groups=True) @@ -2382,6 +2551,14 @@ def save_to_directory(self, param: SaveToDirectoryParam | None = None) -> None: Conf.main.base_dir.set(param.directory) + self.mainwindow.historypanel.add_ui_entry( + _("Save to directory"), + target=self.PANEL_STR_ID + "panel", + method_name="save_to_directory", + save_state=True, + param=param, + ) + with create_progress_bar(self, _("Saving..."), max_=len(objs)) as progress: for i, (path, obj) in enumerate(param.generate_filepath_obj_pairs(objs)): progress.setValue(i + 1) @@ -2639,6 +2816,7 @@ def properties_changed(self) -> None: # Update the stored original values to reflect the new state # This ensures subsequent changes are compared against the current values self.objprop.update_original_values() + self.SIG_OBJECT_MODIFIED.emit() def recompute_processing(self) -> None: """Recompute/rerun selected objects or group with stored processing parameters. diff --git a/datalab/gui/panel/history.py b/datalab/gui/panel/history.py index ac043afb8..9d0f45715 100644 --- a/datalab/gui/panel/history.py +++ b/datalab/gui/panel/history.py @@ -1,4 +1,4 @@ -# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. """ .. History panel (see parent package :mod:`datalab.gui.panel`) @@ -11,12 +11,17 @@ import functools import html import inspect +import json +import logging import os +import os.path as osp import warnings from contextlib import contextmanager +from copy import deepcopy from typing import TYPE_CHECKING, Any, Callable, Generator from uuid import uuid4 +import numpy as np import sigima.proc.image import sigima.proc.signal from guidata.configtools import get_icon @@ -25,46 +30,139 @@ from guidata.qthelpers import add_actions, create_action from guidata.widgets.dockable import DockableWidgetMixin from qtpy import QtCore as QC +from qtpy import QtGui as QG from qtpy import QtWidgets as QW +from qtpy.compat import getopenfilename, getsavefilename +from sigima.objects import ImageObj, SignalObj -from datalab.config import _ +from datalab.config import Conf, _ from datalab.gui import ObjItf from datalab.gui.panel.base import AbstractPanel from datalab.objectmodel import get_uuid +from datalab.utils.qthelpers import qt_try_loadsave_file, save_restore_stds if TYPE_CHECKING: + import guidata.dataset as gds + from datalab.gui.main import DLMainWindow from datalab.gui.panel.base import BaseDataPanel - from datalab.gui.processor.base import BaseProcessor + from datalab.gui.processor.base import BaseProcessor, FeatureNotFoundError from datalab.h5.native import NativeH5Reader, NativeH5Writer # Keys used in the kwargs dict to mark DataSet payloads, so that the # serialization layer can round-trip them as JSON strings instead of pickling # arbitrary Python objects. +HISTORY_SCHEMA_VERSION = 1 +# Per-action schema. Bumped to 4 to persist the ``_saved_kwargs`` snapshot +# used by the Edit mode Restore feature: persisting it across save/reload +# lets the user revert edits even after closing and re-opening the session, +# as long as Edit mode has not been definitively committed (toggled off). +# Schema version 3 introduced the ``plugin_origin`` field used to track the +# originating plugin of a compute action (see ``BaseProcessor.add_feature``). +# Sessions/actions with ``schema_version <= 2`` are still supported: the +# loader leaves ``plugin_origin`` as ``None`` and missing-plugin replay +# simply produces a generic ``FeatureNotFoundError`` instead of a +# plugin-aware warning. Schema version 2 introduced the ``output_uuids`` +# field used by the bijective action ↔ output mapping (see +# ``HistoryPanel._output_to_action``). Sessions/actions with +# ``schema_version <= 3`` leave ``_saved_kwargs`` as ``None`` on load +# (no pending edits to restore). +HISTORY_ACTION_SCHEMA_VERSION = 4 _DATASET_MARKER = "__dataset_json__" _DATASET_LIST_MARKER = "__dataset_list_json__" +_ROI_MARKER = "__roi_json__" + +_logger = logging.getLogger(__name__) + + +def _numpy_to_json_safe(obj: Any) -> Any: + """Recursively convert numpy arrays to lists for JSON serialization.""" + if isinstance(obj, np.ndarray): + return obj.tolist() + if isinstance(obj, dict): + return {k: _numpy_to_json_safe(v) for k, v in obj.items()} + if isinstance(obj, list): + return [_numpy_to_json_safe(i) for i in obj] + return obj + + +def _encode_roi(roi: Any) -> str: + """Encode a sigima ROI object to a JSON string via ``to_dict()``.""" + from sigima.objects.base import BaseROI # local to avoid circular import + + if not isinstance(roi, BaseROI): + raise TypeError(f"Expected BaseROI instance, got {type(roi)!r}") + roi_dict = _numpy_to_json_safe(roi.to_dict()) + # Store the concrete class so we can reconstruct on decode. + payload = { + "module": type(roi).__module__, + "class": type(roi).__qualname__, + "data": roi_dict, + } + return json.dumps(payload) + + +def _decode_roi(encoded: str) -> Any: + """Decode a JSON string back to a sigima ROI object. + + Only classes from trusted ``sigima.`` modules that are actual + :class:`sigima.objects.base.BaseROI` subclasses are allowed. + + Raises: + ValueError: If the module is not a trusted sigima module or the + resolved class is not a BaseROI subclass. + """ + import importlib + + from sigima.objects.base import BaseROI # local to avoid circular import + + _TRUSTED_ROI_MODULE_PREFIX = "sigima." + + payload = json.loads(encoded) + module_name = payload["module"] + class_name = payload["class"] + + if not module_name.startswith(_TRUSTED_ROI_MODULE_PREFIX): + raise ValueError( + f"Untrusted ROI module {module_name!r}: " + f"only modules under {_TRUSTED_ROI_MODULE_PREFIX!r} are allowed" + ) + + mod = importlib.import_module(module_name) + cls = getattr(mod, class_name) + + if not (isinstance(cls, type) and issubclass(cls, BaseROI)): + raise ValueError( + f"{module_name}.{class_name} is not a BaseROI subclass" + ) + + return cls.from_dict(payload["data"]) def _encode_kwargs(kwargs: dict[str, Any]) -> dict[str, Any]: - """Encode kwargs for HDF5 storage: replace ``DataSet`` and ``list[DataSet]`` - values with marker dicts holding their JSON representation. + """Encode kwargs for HDF5 storage: replace ``DataSet``, ``list[DataSet]``, + and sigima ROI values with marker dicts holding their JSON representation. All other values must already be HDF5-friendly primitives (str, int, float, bool, list/tuple of the same). Args: - kwargs: Raw kwargs dict (may contain ``DataSet`` instances). + kwargs: Raw kwargs dict (may contain ``DataSet`` or ROI instances). Returns: - A new dict with ``DataSet`` values wrapped in marker dicts. + A new dict with special values wrapped in marker dicts. """ + from sigima.objects.base import BaseROI # local to avoid circular import + encoded: dict[str, Any] = {} for key, value in kwargs.items(): if value is None: continue if isinstance(value, DataSet): encoded[key] = {_DATASET_MARKER: dataset_to_json(value)} + elif isinstance(value, BaseROI): + encoded[key] = {_ROI_MARKER: _encode_roi(value)} elif ( isinstance(value, list) and value @@ -90,6 +188,13 @@ def _decode_kwargs(kwargs: dict[str, Any]) -> dict[str, Any]: _("Failed to deserialize history DataSet kwarg %r.") % key ) decoded[key] = None + elif isinstance(value, dict) and _ROI_MARKER in value: + try: + decoded[key] = _decode_roi(value[_ROI_MARKER]) + except Exception as exc: + raise ValueError( + f"Failed to deserialize history ROI kwarg {key!r}: {exc}" + ) from exc elif isinstance(value, dict) and _DATASET_LIST_MARKER in value: try: decoded[key] = [ @@ -105,6 +210,25 @@ def _decode_kwargs(kwargs: dict[str, Any]) -> dict[str, Any]: return decoded +def _copy_history_value(value: Any) -> Any: + """Return an independent copy of a history-serializable value.""" + from sigima.objects.base import BaseROI # local to avoid circular import + + if callable(value): + raise TypeError("History duplication does not support callable kwargs") + if isinstance(value, DataSet): + return json_to_dataset(dataset_to_json(value)) + if isinstance(value, BaseROI): + return _decode_roi(_encode_roi(value)) + if isinstance(value, dict): + return {key: _copy_history_value(item) for key, item in value.items()} + if isinstance(value, list): + return [_copy_history_value(item) for item in value] + if isinstance(value, tuple): + return tuple(_copy_history_value(item) for item in value) + return deepcopy(value) + + def get_datetime_str() -> str: """Return current date and time as a string""" return QC.QDateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss") @@ -182,6 +306,9 @@ class HistoryAction(ObjItf): KIND_UI = "ui" FUNC_EDIT_MODE = "edit" # Name of the function parameter to enable edit mode + # Methods that create new data objects. During non-persistent (output-suppressed) + # replay, these UI actions are skipped so the panel object count stays stable. + UI_CREATION_METHODS: frozenset[str] = frozenset({"new_object"}) def __init__( self, @@ -197,6 +324,7 @@ def __init__( # --- common -------------------------------------------------------- kwargs: dict[str, Any] | None = None, state: WorkspaceState | None = None, + plugin_origin: dict[str, Any] | None = None, ) -> None: super().__init__() self.__title = title or "" @@ -215,10 +343,131 @@ def __init__( self.state = WorkspaceState() if state is None else state self.dtstr: str = get_datetime_str() self.uuid: str = str(uuid4()) + self.schema_version: int = HISTORY_ACTION_SCHEMA_VERSION + # UUIDs of the data objects produced by this action (bijective mapping + # maintained by :class:`HistoryPanel`). Populated post-compute via + # :meth:`HistoryPanel.register_action_outputs`. Empty for ``1_to_0`` + # patterns, for UI actions, and for legacy (schema_version=1) sessions + # loaded from disk (the heuristic fallback then takes over). + self.output_uuids: list[str] = [] + # Plugin origin descriptor for compute actions (None for built-in + # Sigima/DataLab features). Populated at registration time by + # :meth:`BaseProcessor.add_feature` and propagated through + # ``add_compute_entry_from_pp``. See + # :func:`datalab.gui.processor.base._detect_plugin_origin` for shape. + # Persisted as a JSON string in HDF5 (schema_version >= 3). + self.plugin_origin: dict[str, Any] | None = plugin_origin + # Transient flag (NOT serialized): set during a cascade recompute to + # display a "stale" visual marker in the tree. Cleared once the + # action has been recomputed. + self.is_stale: bool = False + # Snapshot of original kwargs before edit-mode modification. + # Set lazily when the first edit-mode change touches this action. + # Persisted to HDF5 (schema_version >= 4) so that the Restore + # action still works after a save/reload cycle while Edit mode is + # active. Cleared by ``discard_snapshot`` (definitive commit when + # toggling Edit mode off) or ``restore_kwargs`` (Restore button). + self._saved_kwargs: dict[str, Any] | None = None + + def snapshot_kwargs(self) -> None: + """Save a copy of the current kwargs as the pre-edit baseline. + + No-op if a snapshot already exists (preserves the original baseline + across multiple edit-mode replays). + """ + if self._saved_kwargs is None: + self._saved_kwargs = { + key: _copy_history_value(value) + for key, value in self.kwargs.items() + } + + def restore_kwargs(self) -> None: + """Restore kwargs from the saved snapshot and clear the snapshot.""" + if self._saved_kwargs is not None: + self.kwargs = self._saved_kwargs + self._saved_kwargs = None + + def discard_snapshot(self) -> None: + """Discard the saved snapshot (accept current kwargs as definitive).""" + self._saved_kwargs = None + + @property + def has_pending_edits(self) -> bool: + """Return True if this action has unsaved edit-mode changes.""" + return self._saved_kwargs is not None def regenerate_uuid(self): """Regenerate UUID after loading from a file (no-op: per-action UUID).""" + def copy(self, title_suffix: str | None = None) -> HistoryAction: + """Return an independent copy of this history action.""" + state = self.state.copy() + title = self.title + if title_suffix: + title = f"{title} {title_suffix}" + new_action = HistoryAction( + title=title, + kind=self.kind, + panel_str=self.panel_str, + func_name=self.func_name, + pattern=self.pattern, + target=self.target, + method_name=self.method_name, + kwargs={ + key: _copy_history_value(value) + for key, value in self.kwargs.items() + }, + state=state, + ) + new_action.output_uuids = list(self.output_uuids) + # Note: _saved_kwargs is intentionally NOT propagated to the copy. + # Copying an action acts as an implicit commit (no pending edits). + return new_action + + def copy_with_uuid_remap( + self, uuid_remap: dict[str, dict[str, str]] + ) -> HistoryAction: + """Return a copy of this action with all captured UUIDs rewritten. + + Args: + uuid_remap: Per-panel mapping ``{panel_str: {old_uuid: new_uuid}}`` + used to translate captured UUIDs to the cloned objects created by + the Duplicate operation. + + Returns: + A new independent :class:`HistoryAction` with remapped UUIDs. + """ + new_action = self.copy() + # Rewrite state.selection + for pstr, uuids in new_action.state.selection.items(): + pmap = uuid_remap.get(pstr, {}) + new_action.state.selection[pstr] = [pmap.get(u, u) for u in uuids] + # Rewrite state.object_metadata keys + for pstr, metadata in new_action.state.object_metadata.items(): + pmap = uuid_remap.get(pstr, {}) + new_action.state.object_metadata[pstr] = { + pmap.get(uuid, uuid): val for uuid, val in metadata.items() + } + # Rewrite obj2_uuids in kwargs + obj2 = new_action.kwargs.get("obj2_uuids") + if obj2: + if isinstance(obj2, str): + obj2 = [obj2] + pstr = new_action.panel_str or "" + pmap = uuid_remap.get(pstr, {}) + rewritten = [pmap.get(u, u) for u in obj2] + new_action.kwargs["obj2_uuids"] = ( + rewritten[0] if len(rewritten) == 1 else rewritten + ) + # Rewrite output_uuids — they reference the target panel. + if new_action.output_uuids: + pstr = new_action.panel_str or "" + pmap = uuid_remap.get(pstr, {}) + new_action.output_uuids = [ + pmap.get(u, u) for u in new_action.output_uuids + ] + return new_action + @property def title(self) -> str: """Return object title""" @@ -263,17 +512,39 @@ def __fallback_doc(self) -> str: def description_summary(self) -> str: """Return a short, single-line summary of the description (collapsed view). - For DataSet parameters, uses the dataset titles; otherwise falls back to - the first non-empty line of the full description. + For DataSet parameters, uses the dataset title followed by a compact + representation of its public fields ("name=value, ..."). Falls back to + the first non-empty line of the full description when no DataSet is + present. """ - titles: list[str] = [] + summaries: list[str] = [] for param in self.__iter_param_kwargs(): if isinstance(param, DataSet): - title = param.get_title() - if title: - titles.append(title) - if titles: - return ", ".join(titles) + title = param.get_title() or "" + # Collect "name=value" for each non-private item of the DataSet. + pairs: list[str] = [] + for item in param.get_items(): + name = item.get_name() + if name.startswith("_"): + continue + try: + value = item.get_value(param) + except Exception: # pylint: disable=broad-except + continue + # Format floats compactly, leave other reprs as-is + if isinstance(value, float): + value_str = f"{value:g}" + else: + value_str = str(value) + pairs.append(f"{name}={value_str}") + if pairs: + summaries.append( + f"{title}: {', '.join(pairs)}" if title else ", ".join(pairs) + ) + elif title: + summaries.append(title) + if summaries: + return " | ".join(summaries) for line in self.description.splitlines(): stripped = line.strip() if stripped: @@ -283,6 +554,7 @@ def description_summary(self) -> str: @property def description_html(self) -> str: """Return rich-text (HTML) description used for the expanded view.""" + # Normal path parts: list[str] = [] no_parameters = True for param in self.__iter_param_kwargs(): @@ -300,6 +572,110 @@ def description_html(self) -> str: return html.escape(text).replace("\n", "<br>") return "" + def to_macro_code( + self, + step_index: int, + input_var: str, + imports: set[str], + obj2_var: str | None = None, + ) -> tuple[list[str], str | None]: + """Return Python source lines for this action as a standalone sigima call. + + Args: + step_index: Step number for variable naming. + input_var: Name of the input variable from the previous step. + imports: Mutable set of import statements accumulated by the caller. + obj2_var: Resolved variable name for the second operand (2-to-1 + pattern). When ``None``, the second operand is left as a + placeholder. + + Returns: + Tuple of (code_lines, output_var_name). ``output_var_name`` is + ``None`` for UI-kind actions (no data output). + """ + if self.kind != self.KIND_COMPUTE: + return [f"# (UI) {self.title} [skipped]"], None + + lines: list[str] = [] + output_var = f"result_{step_index}" + + # Determine the sigima module alias + if self.panel_str == "signal": + mod_alias = "sips" + imports.add("import sigima.proc.signal as sips") + elif self.panel_str == "image": + mod_alias = "sipi" + imports.add("import sigima.proc.image as sipi") + else: + lines.append( + f"# {self.title} [unknown panel: {self.panel_str}]" + ) + return lines, None + + lines.append(f"# Step {step_index}: {self.title}") + + param = self.kwargs.get("param") + param_var: str | None = None + + if param is not None and isinstance(param, DataSet): + param_var = f"param_{step_index}" + param_class = type(param).__qualname__ + param_module = type(param).__module__ + imports.add(f"from {param_module} import {param_class}") + lines.append(f"{param_var} = {param_class}()") + # Reconstruct each attribute + for item in param._items: # noqa: SLF001 + attr_name = item._name # noqa: SLF001 + value = getattr(param, attr_name, None) + if value is not None: + lines.append( + f"{param_var}.{attr_name} = {value!r}" + ) + + # Build the function call + func_call = f"{mod_alias}.{self.func_name}" + if self.pattern in ("1_to_1", "1_to_0"): + if param_var: + lines.append( + f"{output_var} = {func_call}" + f"({input_var}, {param_var})" + ) + else: + lines.append( + f"{output_var} = {func_call}({input_var})" + ) + elif self.pattern == "n_to_1": + if param_var: + lines.append( + f"{output_var} = {func_call}" + f"([{input_var}], {param_var})" + ) + else: + lines.append( + f"{output_var} = {func_call}([{input_var}])" + ) + elif self.pattern == "2_to_1": + second = obj2_var or "... # TODO: provide second operand" + if param_var: + lines.append( + f"{output_var} = {func_call}" + f"({input_var}, {second}, {param_var})" + ) + else: + lines.append( + f"{output_var} = {func_call}" + f"({input_var}, {second})" + ) + elif self.pattern == "1_to_n": + lines.append( + f"{output_var} = {func_call}({input_var})" + ) + else: + lines.append(f"# Unknown pattern {self.pattern!r}") + return lines, None + + return lines, output_var + # ------------------------------------------------------------------ # Workspace-state delegation # ------------------------------------------------------------------ @@ -378,6 +754,28 @@ def replay( """ if uuid_remap is None: uuid_remap = {} + # Suppress history capture during replay to avoid recording + # synthetic entries when the processor re-executes features. + # The context manager is reentrant, so nesting with + # HistoryPanel.replay_restore_actions() is safe. + hpanel = getattr(mainwindow, "historypanel", None) + if hpanel is not None: + ctx = hpanel.replaying() + else: + from contextlib import nullcontext + + ctx = nullcontext() + with ctx: + self._replay_inner(mainwindow, restore_selection, edit, uuid_remap) + + def _replay_inner( + self, + mainwindow: DLMainWindow, + restore_selection: bool, + edit: bool, + uuid_remap: dict[str, dict[str, str]], + ) -> None: + """Inner replay logic, always called under the replaying guard.""" if self.kind == self.KIND_COMPUTE: # Compute actions are selection-driven: restore the captured # selection (translated through ``uuid_remap`` for session @@ -409,6 +807,12 @@ def _translate_state(self, uuid_remap: dict[str, dict[str, str]]) -> WorkspaceSt translated.selection[panel_str] = [panel_map.get(u, u) for u in uuids] translated.states = dict(self.state.states) translated.titles = dict(self.state.titles) + for panel_str, metadata in self.state.object_metadata.items(): + panel_map = uuid_remap.get(panel_str, {}) + translated.object_metadata[panel_str] = { + panel_map.get(uuid, uuid): dict(signature) + for uuid, signature in metadata.items() + } return translated def _replay_compute( @@ -426,19 +830,22 @@ def _replay_compute( processor = panel.processor feature = processor.get_feature(self.func_name) run_kwargs: dict[str, Any] = {self.FUNC_EDIT_MODE: edit} + param = self.kwargs.get("param") if self.pattern in {"1_to_1", "1_to_0", "n_to_1"}: if param is not None: run_kwargs["param"] = param + if self.pattern == "n_to_1" and "pairwise" in self.kwargs: + run_kwargs["pairwise"] = self.kwargs["pairwise"] elif self.pattern == "2_to_1": uuids = self.kwargs.get("obj2_uuids") or [] if isinstance(uuids, str): uuids = [uuids] # Translate captured UUIDs through ``uuid_remap`` (session replay). - # ``uuid_remap`` keys are ``panel.PANEL_STR`` (matches - # ``WorkspaceState.selection`` keys), not the - # ``HistoryAction.panel_str`` (PANEL_STR_ID). - panel_map = (uuid_remap or {}).get(panel.PANEL_STR, {}) + # ``uuid_remap`` keys are ``panel.PANEL_STR_ID`` (matches + # ``WorkspaceState.selection`` keys and + # ``HistoryAction.panel_str``). + panel_map = (uuid_remap or {}).get(panel.PANEL_STR_ID, {}) uuids = [panel_map.get(u, u) for u in uuids] objs2 = [ obj @@ -452,6 +859,8 @@ def _replay_compute( run_kwargs["obj2"] = objs2[0] if len(objs2) == 1 else objs2 if param is not None: run_kwargs["param"] = param + if "pairwise" in self.kwargs: + run_kwargs["pairwise"] = self.kwargs["pairwise"] elif self.pattern == "1_to_n": params = self.kwargs.get("params") or [] run_kwargs["params"] = params @@ -461,7 +870,41 @@ def _replay_compute( def _replay_ui(self, mainwindow: DLMainWindow, edit: bool) -> None: """Replay a UI-kind action by calling ``target.method_name(**kwargs)``.""" + hpanel = mainwindow.historypanel + if ( + hpanel is not None + and hpanel.is_output_suppressed() + and self.method_name in self.UI_CREATION_METHODS + ): + return # Skip creation UI during non-persistent replay target = self._resolve_target(mainwindow) + # Safety guard for destructive UI actions: if the action would delete + # objects but the captured selection no longer resolves to existing + # UUIDs in the target panel, skip the call rather than delete whatever + # is currently selected (which would silently destroy unrelated data). + DESTRUCTIVE_METHODS = {"remove_object", "remove_group", "delete_all_objects"} + if self.method_name in DESTRUCTIVE_METHODS: + if target is None: + _logger.warning( + "Skipping destructive replay '%s': target '%s' not found", + self.method_name, self.target, + ) + return + panel_str = getattr(target, "PANEL_STR_ID", None) + if panel_str and self.state and self.state.selection.get(panel_str): + existing_uuids = { + get_uuid(o) + for o in getattr(target, "objmodel", []) + if o is not None + } + captured = set(self.state.selection.get(panel_str, [])) + if not (captured & existing_uuids): + _logger.warning( + "Skipping destructive replay '%s': none of the captured " + "UUIDs %s exist in panel '%s' anymore", + self.method_name, list(captured), panel_str, + ) + return method = getattr(target, self.method_name) call_kwargs = dict(self.kwargs) # Inject edit mode if the method supports it @@ -479,6 +922,8 @@ def _replay_ui(self, mainwindow: DLMainWindow, edit: bool) -> None: def serialize(self, writer: NativeH5Writer) -> None: """Serialize this action.""" + with writer.group("schema_version"): + writer.write(self.schema_version) with writer.group("kind"): writer.write(self.kind) with writer.group("title"): @@ -502,6 +947,29 @@ def serialize(self, writer: NativeH5Writer) -> None: if encoded: with writer.group("kwargs"): writer.write_dict(encoded) + # ``saved_kwargs`` (schema_version >= 4): persisted Edit mode + # snapshot so the Restore button keeps working after save/reload. + # Skipped (group omitted) when no pending edits exist, keeping the + # on-disk layout byte-identical to schema v3 in the common case. + if self._saved_kwargs is not None: + encoded_saved = _encode_kwargs(self._saved_kwargs) + # Write the group unconditionally (even when empty) so that the + # round-trip preserves the distinction between None (no pending + # edits) and {} (degenerate empty snapshot, keeps has_pending_edits). + with writer.group("saved_kwargs"): + writer.write_dict(encoded_saved) + # Only emit ``output_uuids`` when non-empty: the schema_version field + # already distinguishes v2 (with bijective mapping) from legacy v1. + # Empty lists are skipped to avoid h5py edge cases with empty arrays. + if self.output_uuids: + with writer.group("output_uuids"): + writer.write(list(self.output_uuids)) + # ``plugin_origin`` (schema_version >= 3): stored as a JSON string so + # the HDF5 schema stays trivially round-trippable. Skipped when None + # to keep built-in-only sessions byte-identical to schema v2. + if self.plugin_origin is not None: + with writer.group("plugin_origin"): + writer.write(json.dumps(self.plugin_origin)) with writer.group("state"): self.state.serialize(writer) with writer.group("dtstr"): @@ -509,6 +977,9 @@ def serialize(self, writer: NativeH5Writer) -> None: def deserialize(self, reader: NativeH5Reader) -> None: """Deserialize this action.""" + self.schema_version = reader.read( + "schema_version", default=HISTORY_SCHEMA_VERSION + ) with reader.group("kind"): self.kind = reader.read_any() with reader.group("title"): @@ -531,6 +1002,47 @@ def deserialize(self, reader: NativeH5Reader) -> None: self.kwargs = _decode_kwargs(raw) else: self.kwargs = {} + # ``saved_kwargs`` was introduced in schema_version=4. Legacy + # actions (v1, v2, v3) leave it as ``None`` — no Edit mode + # snapshot to restore. + if "saved_kwargs" in current.attrs or "saved_kwargs" in current: + with reader.group("saved_kwargs"): + raw_saved = reader.read_dict() + self._saved_kwargs = _decode_kwargs(raw_saved) + else: + self._saved_kwargs = None + # ``output_uuids`` was introduced in schema_version=2. Legacy actions + # leave it empty; consumers fall back to the heuristic matcher. + if "output_uuids" in current.attrs or "output_uuids" in current: + with reader.group("output_uuids"): + raw_outputs = reader.read_any() + if raw_outputs is None: + self.output_uuids = [] + else: + self.output_uuids = [str(u) for u in raw_outputs] + else: + self.output_uuids = [] + # ``plugin_origin`` was introduced in schema_version=3. Legacy actions + # (v1, v2) leave it as ``None``: a subsequent replay of a missing + # plugin function will then surface a generic ``FeatureNotFoundError`` + # instead of the richer plugin-aware warning. + if "plugin_origin" in current.attrs or "plugin_origin" in current: + with reader.group("plugin_origin"): + raw_origin = reader.read_any() + if raw_origin in (None, ""): + self.plugin_origin = None + else: + try: + self.plugin_origin = json.loads(raw_origin) + except (TypeError, ValueError): + _logger.warning( + "Failed to decode plugin_origin for action %s; " + "falling back to None.", + self.uuid, + ) + self.plugin_origin = None + else: + self.plugin_origin = None with reader.group("state"): self.state.deserialize(reader) with reader.group("dtstr"): @@ -560,6 +1072,19 @@ def __init__(self) -> None: # value is the list of titles of the objects in the panel. The title is only # informative and is not used to determine if two objects have the same state. self.titles: dict[str, list[str]] = {} + # Structured data signatures of selected objects, keyed by panel name and UUID. + # This is the current schema used for compatibility checks. Missing metadata + # means a pre-Gate-2 history and falls back to UUID-existence validation. + self.object_metadata: dict[str, dict[str, dict[str, Any]]] = {} + + def copy(self) -> WorkspaceState: + """Return an independent copy of this workspace state.""" + state = WorkspaceState() + state.selection = deepcopy(self.selection) + state.states = deepcopy(self.states) + state.titles = deepcopy(self.titles) + state.object_metadata = deepcopy(self.object_metadata) + return state def serialize(self, writer: NativeH5Writer) -> None: """Serialize this workspace state @@ -573,6 +1098,8 @@ def serialize(self, writer: NativeH5Writer) -> None: writer.write_dict(self.states) with writer.group("titles"): writer.write_dict(self.titles) + with writer.group("object_metadata"): + writer.write_dict(self.object_metadata) def deserialize(self, reader: NativeH5Reader) -> None: """Deserialize this workspace state @@ -586,6 +1113,19 @@ def deserialize(self, reader: NativeH5Reader) -> None: self.states = reader.read_dict() with reader.group("titles"): self.titles = reader.read_dict() + current = reader.h5 + for option in reader.option: + current = current[option] + if "object_metadata" in current.attrs or "object_metadata" in current: + with reader.group("object_metadata"): + self.object_metadata = reader.read_dict() + else: + self.object_metadata = {} + # Normalize legacy translated keys to stable panel identifiers. + self.selection = self._normalize_panel_keys(self.selection) + self.states = self._normalize_panel_keys(self.states) + self.titles = self._normalize_panel_keys(self.titles) + self.object_metadata = self._normalize_panel_keys(self.object_metadata) def get_current_selection(self, mainwindow: DLMainWindow) -> dict[str, list[str]]: """Get the current selection in the workspace, keyed by panel name and @@ -599,12 +1139,62 @@ def get_current_selection(self, mainwindow: DLMainWindow) -> dict[str, list[str] """ selection: dict[str, list[str]] = {} for panel in (mainwindow.signalpanel, mainwindow.imagepanel): - selection[panel.PANEL_STR] = [ + selection[panel.PANEL_STR_ID] = [ get_uuid(obj) for obj in panel.objview.get_sel_objects(include_groups=True) ] return selection + @staticmethod + def get_object_metadata(obj: Any) -> dict[str, Any]: + """Return a stable data signature for an object.""" + data = getattr(obj, "data", None) + shape = getattr(data, "shape", None) + if shape is None: + return {} + shape = [int(size) for size in shape] + ndim = getattr(data, "ndim", len(shape)) + return {"shape": shape, "ndim": int(ndim)} + + @staticmethod + def _normalize_object_metadata(metadata: dict[str, Any]) -> dict[str, Any]: + """Normalize object metadata loaded from HDF5 for comparison.""" + shape = metadata.get("shape") + if shape is None: + return {} + shape = [int(size) for size in shape] + ndim = metadata.get("ndim", len(shape)) + return {"shape": shape, "ndim": int(ndim)} + + # Mapping from legacy translated panel keys to stable identifiers. + # Covers the English translations; other locales are handled by the + # catch-all ``"signal"``/``"image"`` substring heuristic below. + _LEGACY_PANEL_KEY_MAP: dict[str, str] = { + "Signal Panel": "signal", + "Image Panel": "image", + } + + @classmethod + def _normalize_panel_key(cls, key: str) -> str: + """Map a potentially translated panel key to its stable identifier.""" + if key in ("signal", "image"): + return key + mapped = cls._LEGACY_PANEL_KEY_MAP.get(key) + if mapped is not None: + return mapped + # Heuristic for non-English translations: look for the stable ID + # substring in the key (e.g. "Panneau signal" → "signal"). + lowered = key.lower() + for stable_id in ("signal", "image"): + if stable_id in lowered: + return stable_id + return key + + @classmethod + def _normalize_panel_keys(cls, d: dict) -> dict: + """Return *d* with all top-level keys normalized to stable panel IDs.""" + return {cls._normalize_panel_key(k): v for k, v in d.items()} + def save(self, mainwindow: DLMainWindow) -> None: """Save the current workspace state @@ -612,16 +1202,28 @@ def save(self, mainwindow: DLMainWindow) -> None: mainwindow: DataLab's main window """ self.selection = self.get_current_selection(mainwindow) + self.object_metadata = {} for panel in (mainwindow.signalpanel, mainwindow.imagepanel): - sel_uuids = self.selection[panel.PANEL_STR] - self.states[panel.PANEL_STR] = [ + sel_uuids = self.selection[panel.PANEL_STR_ID] + self.states[panel.PANEL_STR_ID] = [ str(obj.data.shape) for obj in panel.objmodel if get_uuid(obj) in sel_uuids ] - self.titles[panel.PANEL_STR] = [ + self.titles[panel.PANEL_STR_ID] = [ obj.title for obj in panel.objmodel if get_uuid(obj) in sel_uuids ] + # Store metadata for ALL panel objects (not just selected) so that + # the dict key order captures the full panel ordering. During + # session replay the key order lets us sort old UUIDs by their + # original panel position, which prevents non-commutative 2_to_1 + # operand swaps in the positional-fallback code path. + # ``is_current_state_compatible`` only checks *selected* UUIDs, so + # the extra entries are harmless for compatibility validation. + self.object_metadata[panel.PANEL_STR_ID] = { + get_uuid(obj): self.get_object_metadata(obj) + for obj in panel.objmodel + } def is_current_state_compatible( # pylint: disable=unused-argument self, mainwindow: DLMainWindow, restore_selection: bool @@ -629,9 +1231,10 @@ def is_current_state_compatible( # pylint: disable=unused-argument """Check if the current workspace state is compatible with the saved state. Compatibility means that **every** UUID recorded in the saved selection - still exists in the corresponding panel. The data shape is no longer - used to discriminate (it is informative only): a missing UUID is the - only failure mode. + still exists in the corresponding panel. When structured object metadata + is available (current schema), each selected object's data shape and + dimensions must also match the saved signature. Histories without this + metadata fall back to legacy UUID-existence validation. Args: mainwindow: DataLab's main window @@ -640,16 +1243,24 @@ def is_current_state_compatible( # pylint: disable=unused-argument selection -- it only depends on object existence. Returns: - True if every saved UUID still exists in its panel, False otherwise. + True if every saved UUID still exists in its panel and saved + metadata, when available, still matches. """ if not self.selection: return True for panel in (mainwindow.signalpanel, mainwindow.imagepanel): - saved_uuids = self.selection.get(panel.PANEL_STR, []) + saved_uuids = self.selection.get(panel.PANEL_STR_ID, []) existing_uuids = set(panel.objmodel.get_object_ids()) + saved_metadata = self.object_metadata.get(panel.PANEL_STR_ID, {}) for uuid in saved_uuids: if uuid not in existing_uuids: return False + if uuid in saved_metadata: + current = self.get_object_metadata(panel.objmodel[uuid]) + current = self._normalize_object_metadata(current) + saved = self._normalize_object_metadata(saved_metadata[uuid]) + if saved and current != saved: + return False return True def restore(self, mainwindow: DLMainWindow) -> None: @@ -669,7 +1280,7 @@ def restore(self, mainwindow: DLMainWindow) -> None: "Current workspace state is not compatible with saved state" ) for panel in (mainwindow.signalpanel, mainwindow.imagepanel): - uuids = self.selection.get(panel.PANEL_STR, []) + uuids = self.selection.get(panel.PANEL_STR_ID, []) if uuids: panel.objview.select_objects(uuids) @@ -693,6 +1304,7 @@ def __init__(self, title: str = "", number: int = 0) -> None: self.number = number self.dtstr: str = get_datetime_str() self.actions: list[HistoryAction] = [] + self.schema_version: int = HISTORY_SCHEMA_VERSION def add_action(self, action: HistoryAction) -> None: """Add an action to the history session @@ -702,6 +1314,37 @@ def add_action(self, action: HistoryAction) -> None: """ self.actions.append(action) + def copy( + self, title: str | None = None, action_title_suffix: str | None = None + ) -> HistorySession: + """Return an independent copy of this history session.""" + session = HistorySession(title=title or self.title, number=self.number) + session.actions = [ + action.copy(title_suffix=action_title_suffix) for action in self.actions + ] + return session + + def copy_with_uuid_remap( + self, title: str, uuid_remap: dict[str, dict[str, str]] + ) -> HistorySession: + """Return a copy of this session with all UUIDs rewritten via ``uuid_remap``. + + Used by the Duplicate operation to build an independent session whose + captured object references point to the cloned data objects. + + Args: + title: Title for the new session. + uuid_remap: Per-panel mapping ``{panel_str: {old_uuid: new_uuid}}``. + + Returns: + A new :class:`HistorySession` with all captured UUIDs remapped. + """ + session = HistorySession(title=title, number=self.number) + session.actions = [ + action.copy_with_uuid_remap(uuid_remap) for action in self.actions + ] + return session + def is_current_state_compatible( self, mainwindow: DLMainWindow, restore_selection: bool ) -> bool: @@ -745,76 +1388,193 @@ def replay( # captured selection (and ``obj2_uuids``) into the freshly-created # UUIDs of the current replay, so chained ``n_to_1`` / ``2_to_1`` / # ``1_to_n`` actions operate on the correct inputs. Keys are - # ``panel.PANEL_STR`` (matches ``WorkspaceState.selection`` keys). + # ``panel.PANEL_STR_ID`` (matches ``WorkspaceState.selection`` keys). panels = (mainwindow.signalpanel, mainwindow.imagepanel) - # Map ``HistoryAction.panel_str`` (PANEL_STR_ID, e.g. ``"signal"``) - # to the corresponding ``panel.PANEL_STR`` used in remap keys. - id_to_pstr = { - mainwindow.signalpanel.PANEL_STR_ID: mainwindow.signalpanel.PANEL_STR, - mainwindow.imagepanel.PANEL_STR_ID: mainwindow.imagepanel.PANEL_STR, - } - uuid_remap: dict[str, dict[str, str]] = {p.PANEL_STR: {} for p in panels} + uuid_remap: dict[str, dict[str, str]] = {p.PANEL_STR_ID: {} for p in panels} # FIFO of newly-created UUIDs not yet claimed by a remap entry -- # required because most creation UI actions (e.g. ``new_signal``) # are recorded with ``save_state=False`` (empty captured selection), # so we cannot pair captured-vs-new UUIDs by position at UI time. # Subsequent compute actions claim from this queue on demand. - unclaimed: dict[str, list[str]] = {p.PANEL_STR: [] for p in panels} + unclaimed: dict[str, list[str]] = {p.PANEL_STR_ID: [] for p in panels} + def _claim_unmapped( + pstr: str, + old_uuids: list[str], + action: HistoryAction, + ) -> None: + """Claim unclaimed new UUIDs for *old_uuids* not yet in uuid_remap. + + Uses title matching (scanning the full unclaimed queue) followed by + panel-order index alignment to deterministically pair old UUIDs + to the correct new UUIDs, regardless of creation order. + """ + # Collect unmapped UUIDs (deduplicated, preserving first-seen order). + all_unmapped: list[str] = [] + seen: set[str] = set() + for u in old_uuids: + if u not in seen and u not in uuid_remap.get(pstr, {}): + all_unmapped.append(u) + seen.add(u) + if not all_unmapped: + return + # Re-sort by recorded panel position when available. + panel_order = list( + action.state.object_metadata.get(pstr, {}).keys() + ) + if panel_order and all(u in panel_order for u in all_unmapped): + all_unmapped.sort(key=panel_order.index) + queue = unclaimed.get(pstr) or [] + if not queue: + return + # Build old UUID → title from captured state and object_metadata. + sel_uuids = action.state.selection.get(pstr, []) + sel_titles = action.state.titles.get(pstr, []) + old_titles: dict[str, str] = {} + for _u, _t in zip(sel_uuids, sel_titles): + if _u in seen: + old_titles[_u] = _t + obj_meta = action.state.object_metadata.get(pstr, {}) + for _u in all_unmapped: + if _u not in old_titles and _u in obj_meta: + meta = obj_meta[_u] + if isinstance(meta, dict) and "title" in meta: + old_titles[_u] = meta["title"] + # Build new UUID → title from the live panel (full queue). + new_titles: dict[str, str] = {} + panel_obj = None + for p in panels: + if p.PANEL_STR_ID == pstr: + panel_obj = p + break + if panel_obj is not None: + for nu in queue: + try: + new_titles[nu] = panel_obj.objmodel[nu].title + except KeyError: + pass + # Phase 1: title matching against the FULL queue. + assigned_old: set[str] = set() + assigned_new: set[str] = set() + for ou in all_unmapped: + if ou not in old_titles: + continue + title = old_titles[ou] + candidates = [ + nu + for nu in queue + if nu not in assigned_new + and new_titles.get(nu) == title + ] + if len(candidates) == 1: + uuid_remap.setdefault(pstr, {})[ou] = candidates[0] + assigned_old.add(ou) + assigned_new.add(candidates[0]) + # Phase 2: positional fallback using panel-order alignment. + # Two modes depending on whether the remaining queue covers all + # free recorded panel slots: + # + # A) Absolute index alignment (len(rem_queue) == len(free_indices)): + # Each free panel_order index maps 1-to-1 to a queue slot. + # This ensures e.g. the second-created object maps to the + # second queue entry even when only a subset of old UUIDs + # needs claiming. + # + # B) Relative order fallback (queue is a strict subset): + # The queue only contains later compute-created objects while + # earlier full-panel entries are absent. Absolute alignment + # would leave non-first old UUIDs unmapped. Instead, zip + # rem_old (already sorted by panel order) with rem_queue + # sequentially. + rem_old = [u for u in all_unmapped if u not in assigned_old] + if rem_old and panel_order: + rem_queue = [u for u in queue if u not in assigned_new] + # Find which panel_order indices are "free" (unclaimed). + free_indices: list[int] = [] + for idx, po_uuid in enumerate(panel_order): + if po_uuid not in uuid_remap.get(pstr, {}): + if po_uuid not in assigned_old: + free_indices.append(idx) + if len(rem_queue) == len(free_indices): + # Mode A: absolute index alignment. + idx_to_new: dict[int, str] = {} + for qi, fi in enumerate(free_indices): + if qi < len(rem_queue): + idx_to_new[fi] = rem_queue[qi] + for ou in rem_old: + if ou in panel_order: + idx = panel_order.index(ou) + if idx in idx_to_new: + nu = idx_to_new[idx] + uuid_remap.setdefault(pstr, {})[ou] = nu + assigned_new.add(nu) + else: + # Mode B: relative order fallback. + for ou, nu in zip(rem_old, rem_queue): + uuid_remap.setdefault(pstr, {})[ou] = nu + assigned_new.add(nu) + elif rem_old: + # No panel_order available: sequential fallback. + rem_queue = [u for u in queue if u not in assigned_new] + for ou, nu in zip(rem_old, rem_queue): + uuid_remap.setdefault(pstr, {})[ou] = nu + assigned_new.add(nu) + # Remove all assigned new UUIDs from the unclaimed queue. + if assigned_new: + unclaimed[pstr] = [u for u in queue if u not in assigned_new] + for action in self.actions[:]: - before = {p.PANEL_STR: set(p.objmodel.get_object_ids()) for p in panels} + before = {p.PANEL_STR_ID: set(p.objmodel.get_object_ids()) for p in panels} if action.kind == HistoryAction.KIND_COMPUTE: # Lazy-resolve any captured UUIDs missing from the remap by - # claiming from ``unclaimed`` (FIFO, panel-local). - pstr = id_to_pstr.get(action.panel_str or "", "") + # claiming from ``unclaimed`` (deterministic: title + panel-order). + pstr = action.panel_str or "" captured = action.state.selection.get(pstr, []) - for old_uuid in captured: - if old_uuid in uuid_remap.get(pstr, {}): - continue - queue = unclaimed.get(pstr) or [] - if queue: - uuid_remap.setdefault(pstr, {})[old_uuid] = queue.pop(0) - # 2_to_1: also claim ``obj2_uuids`` from the queue if unknown. if action.pattern == "2_to_1": + # For 2_to_1: collect ALL unmapped old UUIDs from both + # captured selection and obj2_uuids in one batch so + # operand order is preserved by the helper. obj2 = action.kwargs.get("obj2_uuids") or [] if isinstance(obj2, str): obj2 = [obj2] - for old_uuid in obj2: - if old_uuid in uuid_remap.get(pstr, {}): - continue - queue = unclaimed.get(pstr) or [] - if queue: - uuid_remap.setdefault(pstr, {})[old_uuid] = queue.pop(0) + _claim_unmapped(pstr, list(obj2) + list(captured), action) + else: + # For all other compute patterns (1_to_1, n_to_1, etc.): + # use the same deterministic helper. + _claim_unmapped(pstr, list(captured), action) action.replay( mainwindow, restore_selection=restore_selection, edit=edit, uuid_remap=uuid_remap, ) - if action.kind == HistoryAction.KIND_UI: - for panel in panels: - pstr = panel.PANEL_STR - current_ids = set(panel.objmodel.get_object_ids()) - new_uuids = [ - u - for u in panel.objmodel.get_object_ids() - if u not in before[pstr] + # Post-action bookkeeping: track new/removed UUIDs for *every* + # action kind so that later actions consuming compute-created + # outputs can resolve them through ``uuid_remap`` / ``unclaimed``. + for panel in panels: + pstr = panel.PANEL_STR_ID + current_ids = set(panel.objmodel.get_object_ids()) + new_uuids = [ + u + for u in panel.objmodel.get_object_ids() + if u not in before[pstr] + ] + # Drop vanished UUIDs from the unclaimed queue and the + # reverse remap entries (e.g. ``Remove selected objects``): + # this keeps the FIFO claim in sync with the live panel + # contents during chained creation/removal replays. + removed_uuids = before[pstr] - current_ids + if removed_uuids: + unclaimed[pstr] = [ + u for u in unclaimed.get(pstr, []) if u not in removed_uuids ] - # Drop vanished UUIDs from the unclaimed queue and the - # reverse remap entries (e.g. ``Remove selected objects``): - # this keeps the FIFO claim in sync with the live panel - # contents during chained creation/removal replays. - removed_uuids = before[pstr] - current_ids - if removed_uuids: - unclaimed[pstr] = [ - u for u in unclaimed.get(pstr, []) if u not in removed_uuids - ] - panel_map = uuid_remap.get(pstr, {}) - for old_key in [ - k for k, v in panel_map.items() if v in removed_uuids - ]: - panel_map.pop(old_key, None) - if not new_uuids: - continue + panel_map = uuid_remap.get(pstr, {}) + for old_key in [ + k for k, v in panel_map.items() if v in removed_uuids + ]: + panel_map.pop(old_key, None) + if not new_uuids: + continue + if action.kind == HistoryAction.KIND_UI: captured = action.state.selection.get(pstr, []) if captured: # Captured post-action selection available: pair @@ -829,6 +1589,35 @@ def replay( # No captured selection (typical of ``new_signal``): # queue all new UUIDs for lazy claiming. unclaimed.setdefault(pstr, []).extend(new_uuids) + else: + # Compute actions: queue all newly-created UUIDs so + # later actions can lazily claim them. Do NOT map + # captured input UUIDs to output UUIDs — compute + # inputs and outputs are semantically different. + unclaimed.setdefault(pstr, []).extend(new_uuids) + + # Visually close the replay: select the output of the last compute + # action so the user sees the final result highlighted in the panel. + # Without this, the very last action's output is never selected + # (intermediate actions are implicitly "closed" by the next + # iteration's input restore). + if self.actions: + last = self.actions[-1] + if last.kind == HistoryAction.KIND_COMPUTE: + hpanel = getattr(mainwindow, "historypanel", None) + if hpanel is not None: + output_uuid = hpanel._action_output_uuid(last) + if output_uuid: + panel_str = last.panel_str or "" + panel_map = uuid_remap.get(panel_str, {}) + mapped_uuid = panel_map.get(output_uuid, output_uuid) + for panel in panels: + if panel.PANEL_STR_ID == panel_str: + try: + panel.objview.select_objects([mapped_uuid]) + except KeyError: + pass + break def serialize(self, writer: NativeH5Writer) -> None: """Serialize this history session @@ -836,6 +1625,8 @@ def serialize(self, writer: NativeH5Writer) -> None: Args: writer: Writer """ + with writer.group("schema_version"): + writer.write(self.schema_version) with writer.group("title"): writer.write(self.title) with writer.group("number"): @@ -850,6 +1641,9 @@ def deserialize(self, reader: NativeH5Reader) -> None: Args: reader: Reader """ + self.schema_version = reader.read( + "schema_version", default=HISTORY_SCHEMA_VERSION + ) with reader.group("title"): self.title = reader.read_any() with reader.group("number"): @@ -954,6 +1748,7 @@ class HistoryTree(QW.QTreeWidget): """Tree widget for the history panel""" DESCRIPTION_COLUMN = 2 + COMPATIBILITY_ROLE = QC.Qt.UserRole + 1 def __init__(self, parent: QW.QWidget) -> None: """Create a new history tree widget""" @@ -998,8 +1793,8 @@ def __install_description_widget( item.setText(self.DESCRIPTION_COLUMN, "") self.setItemWidget(item, self.DESCRIPTION_COLUMN, widget) - @staticmethod - def action_to_tree_item(action: HistoryAction) -> QW.QTreeWidgetItem: + @classmethod + def action_to_tree_item(cls, action: HistoryAction) -> QW.QTreeWidgetItem: """Convert an action to a tree item Args: @@ -1012,8 +1807,40 @@ def action_to_tree_item(action: HistoryAction) -> QW.QTreeWidgetItem: # installed by ``HistoryTree`` once the item is inserted in the tree. item = QW.QTreeWidgetItem([action.title, action.dtstr, ""]) item.setData(0, QC.Qt.UserRole, action.uuid) + item.setData(0, cls.COMPATIBILITY_ROLE, True) return item + def update_compatibility_states( + self, history_sessions: list[HistorySession], mainwindow: DLMainWindow + ) -> None: + """Update action item visual state from workspace compatibility.""" + default_brush = QG.QBrush() + disabled_brush = QG.QBrush( + self.palette().color(QG.QPalette.Disabled, QG.QPalette.Text) + ) + compatible_tip = _("Action is compatible with the current workspace state.") + incompatible_tip = _( + "Action is not compatible with the current workspace state." + ) + for i in range(self.topLevelItemCount()): + session_item = self.topLevelItem(i) + for j in range(session_item.childCount()): + child = session_item.child(j) + uuid = child.data(0, QC.Qt.UserRole) + action = self.get_action_from_uuid(uuid, history_sessions) + compatible = action.is_current_state_compatible( + mainwindow, restore_selection=True + ) + child.setData(0, self.COMPATIBILITY_ROLE, compatible) + brush = default_brush if compatible else disabled_brush + icon = get_icon("apply.svg") if compatible else get_icon("delete.svg") + child.setIcon(0, icon) + for col in range(self.columnCount()): + child.setForeground(col, brush) + child.setToolTip( + col, compatible_tip if compatible else incompatible_tip + ) + def __forget_orphan_expanded_states( self, history_sessions: list[HistorySession] ) -> None: @@ -1037,6 +1864,7 @@ def populate_tree(self, history_sessions: list[HistorySession]) -> None: self.clear() for session in history_sessions: ritem = QW.QTreeWidgetItem([session.title, session.dtstr]) + ritem.setData(0, self.COMPATIBILITY_ROLE, True) self.addTopLevelItem(ritem) for action in session.actions: child = self.action_to_tree_item(action) @@ -1063,6 +1891,33 @@ def add_action_to_tree(self, action: HistoryAction) -> None: ritem.addChild(item) self.__install_description_widget(item, action) + def refresh_action_item(self, action: HistoryAction) -> None: + """Refresh the tree item corresponding to ``action``. + + Re-installs the description widget so it reflects the current + ``action.kwargs`` (e.g. after the user edited a ``param`` via the + Processing tab of the Signal/Image panel). Also applies a light + orange background when ``action.is_stale`` is True, to signal that + the action is currently being recomputed in a cascade. + """ + target_uuid = action.uuid + stale_brush = QG.QBrush(QG.QColor(255, 220, 150)) # light orange + normal_brush = QG.QBrush() + iterator = QW.QTreeWidgetItemIterator(self) + while iterator.value(): + item = iterator.value() + if item.data(0, QC.Qt.UserRole) == target_uuid: + # Remove and re-install the collapsible description widget so + # it reflects the mutated ``action.kwargs``. + self.removeItemWidget(item, self.DESCRIPTION_COLUMN) + self.__install_description_widget(item, action) + brush = stale_brush if action.is_stale else normal_brush + for col in range(self.columnCount()): + item.setBackground(col, brush) + self.scheduleDelayedItemsLayout() + return + iterator += 1 + def get_action_from_uuid( self, uuid: str, history_sessions: list[HistorySession] ) -> HistoryAction: @@ -1121,6 +1976,73 @@ def get_selected_actions( return selected +class WorkspaceStateWidget(QW.QWidget): + """Side-by-side tables showing the workspace state captured by a history action. + + Left table: signals (title + data shape). + Right table: images (title + data shape/dimensions). + """ + + def __init__(self, parent: QW.QWidget | None = None) -> None: + super().__init__(parent) + self._signal_table = QW.QTableWidget(0, 2, self) + self._signal_table.setHorizontalHeaderLabels([_("Signal"), _("Shape")]) + self._signal_table.horizontalHeader().setStretchLastSection(True) + self._signal_table.setEditTriggers(QW.QAbstractItemView.NoEditTriggers) + self._signal_table.setSelectionMode(QW.QAbstractItemView.NoSelection) + self._signal_table.verticalHeader().hide() + + self._image_table = QW.QTableWidget(0, 2, self) + self._image_table.setHorizontalHeaderLabels([_("Image"), _("Dimensions")]) + self._image_table.horizontalHeader().setStretchLastSection(True) + self._image_table.setEditTriggers(QW.QAbstractItemView.NoEditTriggers) + self._image_table.setSelectionMode(QW.QAbstractItemView.NoSelection) + self._image_table.verticalHeader().hide() + + splitter = QW.QSplitter(QC.Qt.Horizontal, self) + splitter.addWidget(self._signal_table) + splitter.addWidget(self._image_table) + layout = QW.QVBoxLayout(self) + layout.setContentsMargins(0, 0, 0, 0) + layout.addWidget(splitter) + + def update_from_state(self, state: WorkspaceState | None) -> None: + """Populate tables from a WorkspaceState.""" + self._signal_table.setRowCount(0) + self._image_table.setRowCount(0) + if state is None: + return + self._populate_table(self._signal_table, state, "signal") + self._populate_table(self._image_table, state, "image") + + @staticmethod + def _populate_table( + table: QW.QTableWidget, state: WorkspaceState, panel_key: str + ) -> None: + """Fill a table from the state for a given panel key.""" + titles = state.titles.get(panel_key, []) + shapes = state.states.get(panel_key, []) + metadata = state.object_metadata.get(panel_key, {}) + uuids = state.selection.get(panel_key, []) + # Use metadata keyed by UUID when available + rows: list[tuple[str, str]] = [] + for i, uuid in enumerate(uuids): + title = titles[i] if i < len(titles) else uuid[:8] + meta = metadata.get(uuid, {}) + shape = meta.get("shape") + if shape is not None: + shape_str = " × ".join(str(s) for s in shape) + elif i < len(shapes): + shape_str = shapes[i] + else: + shape_str = "—" + rows.append((title, shape_str)) + table.setRowCount(len(rows)) + for row_idx, (title, shape_str) in enumerate(rows): + table.setItem(row_idx, 0, QW.QTableWidgetItem(title)) + table.setItem(row_idx, 1, QW.QTableWidgetItem(shape_str)) + + class HistoryPanel(AbstractPanel, DockableWidgetMixin): """History panel""" @@ -1146,13 +2068,28 @@ def __init__(self, parent: DLMainWindow) -> None: # history with synthetic entries triggered by their own internal # `compute_*` calls. Use `replaying()` as a context manager. self.__replaying = False + self.__output_suppressed = False + # Guard flag used by `__sync_panel_selection` to prevent re-entry + # while the data panels are being updated programmatically. + self.__syncing = False + self._cascade_in_progress = False self.__delete_action: QW.QAction | None = None + self.__duplicate_action: QW.QAction | None = None + self.__step_prev_action: QW.QAction | None = None + self.__step_next_action: QW.QAction | None = None + self.__restore_selection_action: QW.QAction | None = None + self.__edit_action: QW.QAction | None = None self.__menu_actions: list[QW.QAction] = self.__create_menu_actions() self.mainwindow = parent self.tree = HistoryTree(self) self.tree.customContextMenuRequested.connect(self.show_context_menu) self.tree.itemDoubleClicked.connect(self.replay_restore_actions) + self.tree.itemSelectionChanged.connect(self.__sync_panel_selection) + self.tree.itemSelectionChanged.connect(self.__update_actions_state) + self.tree.itemSelectionChanged.connect(self.__update_state_widget) + + self.__state_widget = WorkspaceStateWidget(self) toolbar = QW.QToolBar(self) add_actions(toolbar, self.__menu_actions) @@ -1160,6 +2097,7 @@ def __init__(self, parent: DLMainWindow) -> None: layout = QW.QVBoxLayout() layout.addWidget(toolbar) layout.addWidget(self.tree) + layout.addWidget(self.__state_widget) layout.setContentsMargins(0, 0, 0, 0) widget.setLayout(layout) @@ -1167,12 +2105,92 @@ def __init__(self, parent: DLMainWindow) -> None: self.__history_sessions: list[HistorySession] = [] self.__session_increment = 0 + # Bijective action ↔ output mapping (C1). Both dicts are kept in sync + # by :meth:`register_action_outputs` and pruned by + # :meth:`_prune_output_mapping` when objects are removed from a panel. + # Reconstructed at HDF5 load time from each action's ``output_uuids``. + self._action_output_uuids: dict[str, list[str]] = {} + self._output_to_action: dict[str, str] = {} + # Warnings collected during ``recompute_cascade`` (and the helpers + # it dispatches to). Aggregated into a single user-facing dialog + # at the end of the cascade so deleted output objects / missing + # sources / unsupported patterns do not spam the user. + self._cascade_warnings: list[str] = [] + # Actions detected as broken (missing plugin) during a cascade run. + # Transient — intentionally not persisted: recalculated from scratch + # on each cascade run, similar to ``is_stale``. + # The visual stale marker is *not* cleared for these so the user + # sees them flagged in the tree until the plugin is reinstalled and + # the cascade is re-run successfully. + self._broken_actions: set[str] = set() + # Re-entrancy guard for :meth:`_reconnect_chain_after_removal` (see + # method docstring): ``recompute_cascade`` pumps the event loop and + # could deliver a queued ``SIG_OBJECT_REMOVED`` mid-reconnection. + self.__reconnecting = False + for panel in (self.mainwindow.signalpanel, self.mainwindow.imagepanel): + panel.SIG_OBJECT_ADDED.connect(self.refresh_compatibility_items) + panel.SIG_OBJECT_ADDED.connect(self.__refresh_obj_ids_snapshot) + panel.SIG_OBJECT_REMOVED.connect(self.refresh_compatibility_items) + panel.SIG_OBJECT_REMOVED.connect( + functools.partial(self._reconnect_chain_after_removal, panel) + ) + panel.SIG_OBJECT_REMOVED.connect(self._prune_output_mapping) + panel.SIG_OBJECT_MODIFIED.connect(self.refresh_compatibility_items) + self.__refresh_obj_ids_snapshot() self.__update_actions_state() + self.refresh_compatibility_items() + + def __refresh_obj_ids_snapshot(self) -> None: + """Cache the current object ids of both data panels. + + ``SIG_OBJECT_REMOVED`` carries no payload, so the set of just-deleted + objects is recovered by diffing this snapshot against the live model + inside :meth:`_reconnect_chain_after_removal`. + """ + self.__obj_ids_snapshot = { + self.mainwindow.signalpanel.PANEL_STR_ID: set( + self.mainwindow.signalpanel.objmodel.get_object_ids() + ), + self.mainwindow.imagepanel.PANEL_STR_ID: set( + self.mainwindow.imagepanel.objmodel.get_object_ids() + ), + } def __update_actions_state(self) -> None: """Update the enabled state of menu actions depending on history content.""" - if self.__delete_action is not None: - self.__delete_action.setEnabled(len(self) > 0) + has_history = len(self) > 0 + for action in ( + self.__delete_action, + self.__duplicate_action, + ): + if action is not None: + action.setEnabled(has_history) + if self.__step_prev_action is not None: + self.__step_prev_action.setEnabled(self.__can_step_prev()) + if self.__step_next_action is not None: + self.__step_next_action.setEnabled(self.__can_step_next()) + if self.__restore_selection_action is not None: + self.__restore_selection_action.setEnabled( + self.__edit_mode or self._has_any_pending_edits() + ) + + def _has_any_pending_edits(self) -> bool: + """Return True if any action across all sessions has a pending + Edit mode snapshot (i.e. uncommitted edits that Restore can revert). + """ + return any( + action.has_pending_edits + for session in self.__history_sessions + for action in session.actions + ) + + def __update_state_widget(self) -> None: + """Update the workspace state widget from the currently selected action.""" + action = self.__current_action() + if action is not None: + self.__state_widget.update_from_state(action.state) + else: + self.__state_widget.update_from_state(None) def __create_menu_actions(self) -> list[QW.QAction]: """Create menu actions for the history panel @@ -1187,6 +2205,7 @@ def __create_menu_actions(self) -> list[QW.QAction]: icon=get_icon("edit_mode.svg"), ) edit_action.setChecked(self.__edit_mode) + self.__edit_action = edit_action record_action = create_action( self, _("Record mode"), @@ -1194,14 +2213,88 @@ def __create_menu_actions(self) -> list[QW.QAction]: icon=get_icon("record.svg"), ) record_action.setChecked(self.__record_mode) + new_session_action = create_action( + self, + _("New session"), + self.create_new_session, + icon=get_icon("libre-gui-add.svg"), + tip=_("Start a new history session"), + ) + open_action = create_action( + self, + _("Open history file..."), + triggered=lambda checked=False: self.open_dlhist_file(), + icon=get_icon("fileopen_h5.svg"), + tip=_("Open history from a standalone .dlhist file"), + ) + save_action = create_action( + self, + _("Save history file..."), + triggered=lambda checked=False: self.save_to_dlhist_file(), + icon=get_icon("filesave_h5.svg"), + tip=_("Save history to a standalone .dlhist file"), + ) self.__delete_action = create_action( self, _("Delete"), - self.delete_actions, + self.delete_selected, icon=get_icon("delete.svg"), ) + self.__duplicate_action = create_action( + self, + _("Duplicate"), + self.duplicate_selected_entries, + icon=get_icon("duplicate.svg"), + tip=_("Duplicate selected history action/session"), + ) + self.__step_prev_action = create_action( + self, + _("Previous step"), + triggered=self._step_prev, + icon=get_icon("libre-gui-arrow-left.svg"), + tip=_("Select the previous action in the current session"), + shortcut=QG.QKeySequence("Ctrl+Left"), + ) + self.__step_next_action = create_action( + self, + _("Next step"), + triggered=self._step_next, + icon=get_icon("libre-gui-arrow-right.svg"), + tip=_("Select the next action in the current session"), + shortcut=QG.QKeySequence("Ctrl+Right"), + ) + generate_macro_action = create_action( + self, + _("Generate macro"), + self.generate_macro, + icon=get_icon("console.svg"), + tip=_("Generate a Python macro script from history"), + ) + remove_incompatible_action = create_action( + self, + _("Remove incompatible"), + self.remove_incompatible_actions, + icon=get_icon("edit/delete_all.svg"), + tip=_("Remove actions incompatible with the current workspace"), + ) + self.__restore_selection_action = create_action( + self, + _("Restore parameters"), + lambda: self.replay_restore_actions( + restore_selection=True, replay=False + ), + icon=get_icon("restore_selection.svg"), + tip=_("Restore original parameters (discard edit-mode changes)"), + ) return [ record_action, + new_session_action, + None, + open_action, + save_action, + None, + self.__step_prev_action, + self.__step_next_action, None, create_action( self, @@ -1209,32 +2302,57 @@ def __create_menu_actions(self) -> list[QW.QAction]: lambda: self.replay_restore_actions(restore_selection=False), icon=get_icon("replay.svg"), ), - create_action( - self, - _("Restore selection"), - lambda: self.replay_restore_actions( - restore_selection=True, replay=False - ), - icon=get_icon("restore_selection.svg"), - ), - create_action( - self, - _("Restore selection and replay"), - self.replay_restore_actions, - icon=get_icon("restore_and_replay.svg"), - ), + self.__restore_selection_action, edit_action, None, + self.__duplicate_action, + generate_macro_action, + None, + remove_incompatible_action, self.__delete_action, ] def toggle_edit_mode(self, checked: bool) -> None: - """Toggle edit mode + """Toggle edit mode. + + Toggling Edit mode off is a **definitive commit**: all parameter + changes performed during the session become permanent and Restore + is no longer available for them. When pending edits exist, the + user is asked to confirm; refusing leaves Edit mode enabled. Args: - checked: True if the edit mode is checked, False otherwise + checked: True if the edit mode is checked, False otherwise. """ + if not checked and self._has_any_pending_edits(): + reply = QW.QMessageBox.question( + self.mainwindow, + _("Commit edit mode changes?"), + _( + "You are about to exit Edit mode.\n\n" + "All parameter changes made during this session will be " + "permanently kept.\n" + "This action cannot be undone — Restore will no longer " + "be available.\n\n" + "Do you want to continue?" + ), + QW.QMessageBox.Yes | QW.QMessageBox.No, + QW.QMessageBox.No, + ) + if reply != QW.QMessageBox.Yes: + # Re-check the action without triggering toggle_edit_mode + # again (blockSignals prevents recursion). + if self.__edit_action is not None: + self.__edit_action.blockSignals(True) + self.__edit_action.setChecked(True) + self.__edit_action.blockSignals(False) + return self.__edit_mode = checked + if not checked: + # Exiting edit mode: accept all pending edits (discard snapshots) + for session in self.__history_sessions: + for action in session.actions: + action.discard_snapshot() + self.__update_actions_state() def toggle_record_mode(self, checked: bool) -> None: """Toggle record mode @@ -1244,6 +2362,10 @@ def toggle_record_mode(self, checked: bool) -> None: """ self.__record_mode = checked + def is_edit_mode(self) -> bool: + """Return True when the History panel is in edit (parameter testing) mode.""" + return self.__edit_mode + @contextmanager def replaying(self) -> Generator[None, None, None]: """Context manager suppressing history capture during its scope. @@ -1264,12 +2386,33 @@ def is_replaying(self) -> bool: """Return True when an external replay/recompute is in progress.""" return self.__replaying + @contextmanager + def output_suppressed(self) -> Generator[None, None, None]: + """Context manager suppressing compute outputs during its scope. + + When active, :meth:`BaseProcessor._add_object_to_appropriate_panel` + and :meth:`BaseProcessor._create_group_for_result` become no-ops so + that History Panel replay can execute computations without altering + Signal/Image panel object counts. Reentrant-safe. + """ + previous = self.__output_suppressed + self.__output_suppressed = True + try: + yield + finally: + self.__output_suppressed = previous + + def is_output_suppressed(self) -> bool: + """Return True when compute outputs must not be added to panels.""" + return self.__output_suppressed + def show_context_menu(self, pos: QC.QPoint) -> None: """Show the context menu Args: pos: Position of the context menu """ + self.refresh_compatibility_items() menu = QW.QMenu() add_actions(menu, self.__menu_actions) menu.exec_(self.tree.mapToGlobal(pos)) @@ -1292,10 +2435,29 @@ def get_action_from_uuid(self, uuid: str) -> HistoryAction: def replay_restore_actions( self, replay: bool = True, restore_selection: bool = True ) -> None: - """Replay and/or restore selection for the selected actions""" - for session_or_action in self.tree.get_selected_actions_or_sessions( - self.__history_sessions - ): + """Replay and/or restore selection for the selected actions. + + When nothing is selected in the tree, replays the entire last session. + Replay is non-persistent: compute actions run but their outputs are + NOT added to Signal/Image panels. UI-creation actions are always + skipped during replay because source objects already exist. + """ + self.refresh_compatibility_items() + selected = self.tree.get_selected_actions_or_sessions(self.__history_sessions) + if not selected: + if not self.__history_sessions: + return + # Nothing selected → replay the last session + selected = [self.__history_sessions[-1]] + for session_or_action in selected: + # B4: if a stale action is Played, recompute its cascade in-place + # instead of running the standard non-persistent replay. + if ( + isinstance(session_or_action, HistoryAction) + and session_or_action.is_stale + ): + self.recompute_cascade(session_or_action) + continue if not session_or_action.is_current_state_compatible( self.mainwindow, restore_selection=restore_selection ): @@ -1306,59 +2468,1938 @@ def replay_restore_actions( ) return if replay: - with self.replaying(): - session_or_action.replay( - self.mainwindow, - restore_selection=restore_selection, - edit=self.__edit_mode, + if self.__edit_mode and isinstance( + session_or_action, HistoryAction + ): + self._edit_mode_replay(session_or_action) + elif self.__edit_mode and isinstance( + session_or_action, HistorySession + ): + self._view_only_session_replay( + session_or_action, restore_selection ) + else: + with self.replaying(), self.output_suppressed(): + session_or_action.replay( + self.mainwindow, + restore_selection=restore_selection, + edit=self.__edit_mode, + ) elif restore_selection: - session_or_action.restore(self.mainwindow) + # Restore button (replay=False, restore_selection=True): + # if Edit mode is active OR there are persisted pending + # edits (e.g. after a save/reload), revert the parameter + # snapshots in place. Otherwise behave as a workspace + # selection restore. + if self.__edit_mode or self._has_any_pending_edits(): + self._restore_action_params(session_or_action) + else: + session_or_action.restore(self.mainwindow) + + def _prompt_edit_action_params(self, action: HistoryAction) -> bool | None: + """Open the parameter dialog for *action* according to its pattern. - def delete_actions(self) -> None: - """Delete the selected actions""" - # Ask for confirmation as this will delete the action and all subsequent actions - reply = QW.QMessageBox.question( - self.mainwindow, - _("Delete actions"), - _( - "Do you really want to delete the selected action " - "and all the next ones?" - ), - QW.QMessageBox.Yes | QW.QMessageBox.No, - QW.QMessageBox.No, - ) - if reply == QW.QMessageBox.Yes: - for action in self.tree.get_selected_actions(self.__history_sessions): - for session in self.__history_sessions: - if action in session.actions: - session.remove_action(action) - self.tree.populate_tree(self.__history_sessions) - self.__update_actions_state() + Returns: + ``True`` – user accepted; ``action.kwargs`` mutated, snapshot taken. + ``False`` – user cancelled the dialog. + ``None`` – nothing to edit (no param/params, or unsupported pattern). + """ + import copy # pylint: disable=import-outside-toplevel + + pattern = action.pattern + if pattern in {"1_to_1", "1_to_0", "n_to_1", "2_to_1"}: + param = action.kwargs.get("param") + if param is None: + return None + edited = copy.deepcopy(param) + if not edited.edit(parent=self.mainwindow): + return False + action.snapshot_kwargs() + action.kwargs["param"] = edited + return True + if pattern == "1_to_n": + params = action.kwargs.get("params") or [] + if not params: + return None + edited_params = [copy.deepcopy(p) for p in params] + # Local import: ``gds`` is not used elsewhere in this module. + import guidata.dataset as gds # pylint: disable=import-outside-toplevel + + group = gds.DataSetGroup(edited_params, title=_("Parameters")) + if not group.edit(parent=self.mainwindow): + return False + action.snapshot_kwargs() + action.kwargs["params"] = edited_params + return True + # multiple_1_to_1 or any unknown pattern: nothing to edit. + return None - def serialize_to_hdf5(self, writer: NativeH5Writer) -> None: - """Serialize whole panel to a HDF5 file + def _edit_mode_replay(self, action: HistoryAction) -> None: + """Replay a single action in edit mode: open param dialog, update + kwargs on accept, recompute in-place and cascade downstream. - Args: - writer: HDF5 writer + Supports every compute pattern (1_to_1, 1_to_n, n_to_1, 2_to_1, + 1_to_0). ``multiple_1_to_1`` is currently not supported: the dialog + is skipped for that action but the rest of the chain is still + processed. + + UI actions and pattern-less entries fall back to normal replay. + + The parameter dialog is opened for the root action AND for every + downstream action in the cascade, in topological order. If the + user cancels ANY dialog, all snapshots already created in this + pass are rolled back and nothing is recomputed. """ - writer.write_object_list(self.__history_sessions, self.H5_PREFIX) + if action.kind != HistoryAction.KIND_COMPUTE or action.pattern is None: + with self.replaying(), self.output_suppressed(): + action.replay(self.mainwindow, restore_selection=True, edit=True) + return - def deserialize_from_hdf5( - self, reader: NativeH5Reader, reset_all: bool = False + chain: list[HistoryAction] = [action] + self.get_downstream_actions( + action + ) + edited_actions: list[HistoryAction] = [] + for a in chain: + result = self._prompt_edit_action_params(a) + if result is False: + # User cancelled – rollback every snapshot taken so far. + for done in edited_actions: + done.restore_kwargs() + self.tree.refresh_action_item(done) + return + if result is True: + edited_actions.append(a) + + for a in edited_actions: + self.tree.refresh_action_item(a) + + # Recompute root in-place, then cascade with the pre-computed + # descendants list. Re-using the chain avoids a second call to + # ``get_downstream_actions`` whose result could diverge after the + # root output's metadata has been rewritten by the root recompute. + downstream = chain[1:] + self._recompute_action_in_place(action) + self.recompute_cascade(action, descendants=downstream) + + # Belt-and-suspenders refresh: ensure the tree description widgets + # and the Signal/Image panels reflect the final state for every + # action in the chain (root included). + for a in chain: + self.tree.refresh_action_item(a) + QW.QApplication.processEvents() + + def _show_readonly_param_dialog( + self, dataset: gds.DataSet | gds.DataSetGroup ) -> None: - """Deserialize whole panel from a HDF5 file + """Show a parameter dialog identical to the edit dialog but read-only. + + Builds the same guidata dialog as edit mode (``DataSetEditDialog`` for a + single dataset, ``DataSetGroupEditDialog`` for a group) so the appearance + and title match exactly, then disables every input field (and its label) + so the parameters are displayed but cannot be modified. The OK button is + kept so the dialog can be dismissed. + + Args: + dataset: The dataset (or dataset group) whose parameters are shown. + """ + # Local import: not used elsewhere in this module. + import guidata.dataset as gds # pylint: disable=import-outside-toplevel + from guidata.dataset.qtwidgets import ( # pylint: disable=import-outside-toplevel + DataSetEditDialog, + DataSetGroupEditDialog, + ) + + # A DataSetGroup (1_to_n) needs the tabbed group dialog; a single + # DataSet uses the standard edit dialog. Both expose ``edit_layout``. + if isinstance(dataset, gds.DataSetGroup): + dialog = DataSetGroupEditDialog(dataset, parent=self.mainwindow) + else: + dialog = DataSetEditDialog(dataset, parent=self.mainwindow) + for edl in dialog.edit_layout: + for widget in edl.widgets: + if widget.group is not None: + widget.group.setEnabled(False) + if widget.label is not None: + widget.label.setEnabled(False) + dialog.exec() + + def _view_only_session_replay( + self, + session: HistorySession, + restore_selection: bool, + ) -> None: + """Replay a session in edit mode with read-only parameter dialogs. + + When edit mode is active and a full session is replayed, editable + dialogs would be misleading because modifications cannot be propagated + through the cascade. Instead, show each compute action's parameters in + a dialog that looks identical to the edit dialog but whose fields are + disabled, and keep the History tree and the data panel synchronized with + the action being shown. The session is then replayed with ``edit=False``. + """ + import copy # pylint: disable=import-outside-toplevel + + # Local import: ``gds`` is not used elsewhere in this module. + import guidata.dataset as gds # pylint: disable=import-outside-toplevel + + for action in session.actions: + if action.kind != HistoryAction.KIND_COMPUTE: + continue + pattern = action.pattern + # Sync the History tree and the data panel to this action so the + # user follows the replay step by step (same behaviour as edit mode). + self.__select_action_in_tree(action) + QW.QApplication.processEvents() + if pattern in {"1_to_1", "1_to_0", "n_to_1", "2_to_1"}: + param = action.kwargs.get("param") + if param is not None: + self._show_readonly_param_dialog(copy.deepcopy(param)) + elif pattern == "1_to_n": + params = action.kwargs.get("params") or [] + if params: + group = gds.DataSetGroup( + [copy.deepcopy(p) for p in params], + title=_("Parameters"), + ) + self._show_readonly_param_dialog(group) + + with self.replaying(), self.output_suppressed(): + session.replay( + self.mainwindow, + restore_selection=restore_selection, + edit=False, + ) + + def _restore_action_params( + self, item: HistoryAction | HistorySession + ) -> None: + """Restore original kwargs from snapshot and recompute in-place. + + Used by the Restore action in edit mode to discard parameter + changes and revert to the pre-edit state. + """ + actions: list[HistoryAction] + if isinstance(item, HistorySession): + actions = [ + a for a in item.actions if a.kind == HistoryAction.KIND_COMPUTE + ] + else: + actions = [item] + for action in actions: + if not action.has_pending_edits: + continue + action.restore_kwargs() + self.tree.refresh_action_item(action) + self._recompute_action_in_place(action) + self.recompute_cascade(action) + # Snapshots may have been consumed: refresh button states so the + # Restore action disables itself once no pending edits remain + # (relevant outside Edit mode after a save/reload restore). + self.__update_actions_state() + + def _find_parent_session(self, action: HistoryAction) -> HistorySession | None: + """Return the session that contains ``action``, or None if not found. + + Args: + action: Action to search for. + + Returns: + Parent :class:`HistorySession`, or ``None``. + """ + for session in self.__history_sessions: + if action in session.actions: + return session + return None + + # ------------------------------------------------------------------ + # Sync History tree selection → Signal/Image panel (B1) + # ------------------------------------------------------------------ + + def __resolve_panel_for_action( + self, action: HistoryAction + ) -> BaseDataPanel | None: + """Return the data panel targeted by ``action``, or ``None``.""" + if action.kind != HistoryAction.KIND_COMPUTE: + return None + if action.panel_str == "signal": + return self.mainwindow.signalpanel + if action.panel_str == "image": + return self.mainwindow.imagepanel + return None + + def __find_output_object_uuid( + self, panel: BaseDataPanel, action: HistoryAction + ) -> str | None: + """Find the UUID of the output object produced by ``action`` in ``panel``. + + Primary path: consult the bijective ``_action_output_uuids`` mapping + populated when the action was recorded (or rebuilt from HDF5 at load). + Returns the first registered output that still exists in ``panel``. + + Fallback path (legacy v1 sessions, or actions whose outputs were + re-created without registration): search the panel for an object whose + ``processing_parameters`` metadata has ``source_uuid`` matching one of + the action's recorded selection UUIDs and whose ``func_name`` equals + the action's ``func_name``. + """ + # Primary: bijective mapping (C1). + registered = self._action_output_uuids.get(action.uuid) + if registered: + existing_ids = set(panel.objmodel.get_object_ids()) + for out_uuid in registered: + if out_uuid in existing_ids: + return out_uuid + # Fallback heuristic for legacy sessions. + if action.func_name is None: + return None + from datalab.gui.processor.base import ( # pylint: disable=import-outside-toplevel + extract_processing_parameters, + ) + + recorded_uuids = set(action.state.selection.get(panel.PANEL_STR_ID, [])) + if not recorded_uuids: + return None + for obj in panel.objmodel: + pp = extract_processing_parameters(obj) + if pp is None or pp.func_name != action.func_name: + continue + if pp.source_uuid is not None and pp.source_uuid in recorded_uuids: + return get_uuid(obj) + if pp.source_uuids is not None and recorded_uuids.intersection( + pp.source_uuids + ): + return get_uuid(obj) + return None + + def find_action_for_output( + self, output_uuid: str, func_name: str + ) -> HistoryAction | None: + """Find the :class:`HistoryAction` that produced ``output_uuid``. + + Primary path: consult the bijective ``_output_to_action`` mapping. This + is exact and resolves the ambiguity of repeated applications of the + same ``func_name`` on the same source. + + Fallback path: searches all sessions (most-recent first) using the + heuristic ``(func_name, source_uuid)`` matching for legacy v1 sessions + without a registered output mapping. + + Args: + output_uuid: UUID of the output object (signal or image). + func_name: Processing function name expected on the action. + + Returns: + The matching action, or ``None`` if no match is found. + """ + if not self.__history_sessions: + return None + # Primary: bijective mapping (C1). + action_uuid = self._output_to_action.get(output_uuid) + if action_uuid is not None: + for session in self.__history_sessions: + for action in session.actions: + if action.uuid == action_uuid: + # Sanity check: func_name must still match. + if action.func_name == func_name: + return action + return None + # Fallback heuristic for legacy sessions. + from datalab.gui.processor.base import ( # pylint: disable=import-outside-toplevel + extract_processing_parameters, + ) + + # Find which panel contains output_uuid + panel: BaseDataPanel | None = None + output_obj = None + for p in (self.mainwindow.signalpanel, self.mainwindow.imagepanel): + try: + output_obj = p.objmodel[output_uuid] + panel = p + break + except KeyError: + continue + if panel is None or output_obj is None: + return None + pp = extract_processing_parameters(output_obj) + if pp is None or pp.func_name != func_name: + return None + target_source_uuid = pp.source_uuid + if target_source_uuid is None: + return None + # Search every session (most-recent first) instead of only [-1]. + # Uniqueness is guaranteed by target_source_uuid (remapped per-session + # during duplication). + for current_session in reversed(self.__history_sessions): + for action in reversed(current_session.actions): + if action.kind != HistoryAction.KIND_COMPUTE: + continue + if action.func_name != func_name: + continue + if action.panel_str != panel.PANEL_STR_ID: + continue + captured = action.state.selection.get(panel.PANEL_STR_ID, []) + if captured and captured[0] == target_source_uuid: + return action + return None + + def refresh_action(self, action: HistoryAction) -> None: + """Refresh the tree display for ``action`` after its kwargs were mutated. + + Used by :meth:`ObjectProp.apply_processing_parameters` to update the + Description column when the user edits a ``param`` from the Processing + tab of the Signal/Image panel. + """ + self.tree.refresh_action_item(action) + + # ------------------------------------------------------------------ + # B4: Cascade recompute of downstream actions after a param edit + # ------------------------------------------------------------------ + + def _get_session_of(self, action: HistoryAction) -> HistorySession | None: + """Return the session that contains ``action``, or None.""" + for session in self.__history_sessions: + if action in session.actions: + return session + return None + + def _action_output_uuid(self, action: HistoryAction) -> str | None: + """Return the UUID of the object produced by ``action``, or ``None``. + + Scans the target panel's object model for an object whose + :class:`ProcessingParameters` metadata matches the action's + ``func_name`` and one of its captured source UUIDs. + """ + panel = self.__resolve_panel_for_action(action) + if panel is None: + return None + return self.__find_output_object_uuid(panel, action) + + def _action_consumes_any( + self, action: HistoryAction, uuids: set[str] + ) -> bool: + """Return True if ``action``'s input UUIDs intersect ``uuids``.""" + if action.kind != HistoryAction.KIND_COMPUTE: + return False + pstr = action.panel_str or "" + captured: set[str] = set(action.state.selection.get(pstr, [])) + obj2 = action.kwargs.get("obj2_uuids") + if obj2: + if isinstance(obj2, str): + captured.add(obj2) + else: + captured.update(obj2) + return bool(captured & uuids) + + def _collect_downstream_uuids(self, action: HistoryAction) -> set[str]: + """Return the transitive closure of output UUIDs descending from + ``action`` within the current session (excluding ``action`` itself). + """ + if not self.__history_sessions: + return set() + current = self._get_session_of(action) + if current is None: + return set() + root_out = self._action_output_uuid(action) + if root_out is None: + return set() + closure: set[str] = {root_out} + # Walk only actions positioned strictly after ``action`` in the + # current session, in chronological order. + idx = current.actions.index(action) + for downstream in current.actions[idx + 1 :]: + if downstream.kind != HistoryAction.KIND_COMPUTE: + continue + if not self._action_consumes_any(downstream, closure): + continue + out_uuid = self._action_output_uuid(downstream) + if out_uuid is not None: + closure.add(out_uuid) + closure.discard(root_out) + return closure + + def get_downstream_actions( + self, action: HistoryAction + ) -> list[HistoryAction]: + """Return the actions of the current session that depend (transitively) + on ``action``'s output, in topological order (direct children first). + """ + if not self.__history_sessions: + return [] + current = self._get_session_of(action) + if current is None: + return [] + root_out = self._action_output_uuid(action) + if root_out is None: + return [] + closure: set[str] = {root_out} + downstream: list[HistoryAction] = [] + idx = current.actions.index(action) + for candidate in current.actions[idx + 1 :]: + if candidate.kind != HistoryAction.KIND_COMPUTE: + continue + if not self._action_consumes_any(candidate, closure): + continue + downstream.append(candidate) + out_uuid = self._action_output_uuid(candidate) + if out_uuid is not None: + closure.add(out_uuid) + return downstream + + # ------------------------------------------------------------------ + # In-place recompute dispatcher (C2): one helper per pattern. + # + # All helpers retrieve the existing output object(s) via the bijective + # ``_action_output_uuids`` mapping (C1), recompute via the processor's + # ``recompute_*`` methods (which do not register history nor add to the + # panel), then update the existing object in place (data + title + + # metadata) and refresh the view. Missing output objects (deleted by + # the user) are reported via :attr:`_cascade_warnings`. + # ------------------------------------------------------------------ + + def _resolve_target_outputs( + self, panel: BaseDataPanel, action: HistoryAction + ) -> tuple[list[str], list[str]]: + """Return ``(existing, missing)`` UUIDs registered for ``action``. + + Args: + panel: Data panel owning the action's outputs. + action: History action whose outputs must be resolved. + + Returns: + A pair of UUID lists: those still present in ``panel`` (in + registration order) and those that were deleted. + """ + registered = list(self._action_output_uuids.get(action.uuid, [])) + existing_ids = set(panel.objmodel.get_object_ids()) + existing: list[str] = [u for u in registered if u in existing_ids] + missing: list[str] = [u for u in registered if u not in existing_ids] + return existing, missing + + def _update_obj_in_place( + self, + target_obj: SignalObj | ImageObj, + new_obj: SignalObj | ImageObj, + ) -> None: + """Copy data + title + metadata from ``new_obj`` onto ``target_obj``. + + Preserves the target's identity (UUID, panel position, references) + while reflecting all user-visible changes produced by a recompute. + + Args: + target_obj: Existing object to mutate in place. + new_obj: Fresh object produced by a ``recompute_*`` call. + """ + target_obj.title = new_obj.title + if isinstance(target_obj, SignalObj): + target_obj.xydata = new_obj.xydata + else: + target_obj.data = new_obj.data + target_obj.invalidate_maskdata_cache() + # Replace compute-related metadata with the fresh set. In Edit mode + # the object is updated in place (not recreated), so stale analysis + # result keys (Geometry_*, Table_*) or obsolete metadata options from + # the previous compute would persist with a simple ``update()``. + # We clear and repopulate, but preserve the target's ``__uuid`` which + # is its identity key managed by the object model. + try: + saved_uuid = target_obj.metadata.get("__uuid") + saved_number = target_obj.metadata.get("__number") + target_obj.metadata.clear() + target_obj.metadata.update(new_obj.metadata) + if saved_uuid is not None: + target_obj.metadata["__uuid"] = saved_uuid + if saved_number is not None: + target_obj.metadata["__number"] = saved_number + except AttributeError: + pass + + def _refresh_target( + self, panel: BaseDataPanel, output_uuid: str + ) -> None: + """Refresh tree item + plot for ``output_uuid`` in ``panel``. + + Also updates the Properties panel when the refreshed object is + currently selected, marks the object as freshly processed so the + Processing tab is shown, and emits ``SIG_OBJECT_MODIFIED`` so + that compatibility icons are refreshed. + """ + panel.objview.update_item(output_uuid) + panel.refresh_plot(output_uuid, update_items=True, force=True) + + # Update the Properties panel if the recomputed object is selected + try: + obj = panel.objmodel[output_uuid] + except KeyError: + obj = None + if obj is not None: + if obj is panel.objview.get_current_object(): + panel.objprop.update_properties_from(obj, force_tab="processing") + else: + # Mark as freshly processed so the Processing tab opens on select + panel.objprop.mark_as_freshly_processed(obj) + + # Notify listeners (e.g. compatibility icons in history tree) + panel.SIG_OBJECT_MODIFIED.emit() + + def _record_missing_outputs( + self, action: HistoryAction, missing: list[str] + ) -> None: + """Log + queue a user-facing warning for deleted output objects.""" + if not missing: + return + name = action.func_name or action.title or action.uuid + _logger.warning( + "Cascade recompute: %d output(s) missing for action %s (%s).", + len(missing), + action.uuid, + name, + ) + self._cascade_warnings.append( + _( + "Action %s has been edited but its target output object(s) " + "no longer exist — skipping." + ) + % name + ) + + def _recompute_action_in_place(self, action: HistoryAction) -> None: + """Re-run ``action`` on the existing output object(s) (same UUIDs). + + Dispatches to a per-pattern helper. Missing target outputs are + recorded in :attr:`_cascade_warnings` and silently skipped so the + rest of the cascade can keep running. + + When the underlying processor feature is missing (e.g. the originating + plugin was uninstalled), :class:`FeatureNotFoundError` is caught here + and the action is flagged as broken (``is_stale`` left at ``True`` + beyond the cascade so the visual marker persists). A localised warning + including the plugin origin and required parameter class is appended + to :attr:`_cascade_warnings`. The cascade continues with the remaining + actions. + + Args: + action: History action to recompute in place. + """ + if action.kind != HistoryAction.KIND_COMPUTE: + return + method = { + "1_to_1": self._recompute_1_to_1_in_place, + "1_to_n": self._recompute_1_to_n_in_place, + "n_to_1": self._recompute_n_to_1_in_place, + "2_to_1": self._recompute_2_to_1_in_place, + "1_to_0": self._recompute_1_to_0_in_place, + }.get(action.pattern or "") + if method is None: + _logger.warning( + "Cascade recompute: unsupported pattern %r for action %s.", + action.pattern, + action.uuid, + ) + self._cascade_warnings.append( + _("Action %s uses pattern %r which is not recomputable yet.") + % (action.func_name or action.uuid, action.pattern) + ) + return + from datalab.gui.processor.base import ( # pylint: disable=import-outside-toplevel + FeatureNotFoundError, + ) + + try: + method(action) + except FeatureNotFoundError as exc: + self._handle_missing_feature(action, exc) + except Exception as exc: # pylint: disable=broad-except + _logger.exception( + "Cascade recompute failed for action %s (%s): %s", + action.uuid, + action.func_name, + exc, + ) + self._cascade_warnings.append( + _("Recompute failed for action %s: %s") + % (action.func_name or action.uuid, exc) + ) + + def _handle_missing_feature( + self, action: HistoryAction, exc: "FeatureNotFoundError" + ) -> None: + """Flag ``action`` as broken (missing plugin) and queue a user warning. + + Args: + action: Action whose feature could not be resolved. + exc: The raised :class:`FeatureNotFoundError`. + ``action.plugin_origin`` is the authoritative source. + ``exc.plugin_origin`` is kept only as a safety net for future + paths where ``get_feature`` might be called without forwarding + the action's ``plugin_origin``. + """ + action.is_stale = True + self._broken_actions.add(action.uuid) + plugin_origin = action.plugin_origin or exc.plugin_origin or {} + directory = (plugin_origin.get("directory") if plugin_origin else None) or "?" + param = action.kwargs.get("param") + paramclass = ( + exc.paramclass_name + or (type(param).__name__ if param is not None else "—") + ) + func_name = action.func_name or exc.func_name or action.uuid + # Format validated with the operator: "{directory}/plugins:{func_name}" + location = f"{directory}/plugins:{func_name}" + _logger.warning( + "Cascade recompute: plugin missing for action %s (%s) — %s.", + action.uuid, + func_name, + location, + ) + self._cascade_warnings.append( + _( + "Action %(name)s skipped: plugin '%(loc)s' is missing.\n" + "Required parameter class: %(param)s\n" + "Reinstall the plugin to re-enable this action." + ) + % {"name": func_name, "loc": location, "param": paramclass} + ) + + def _recompute_1_to_1_in_place(self, action: HistoryAction) -> None: + """Recompute a single 1-to-1 action in place.""" + panel = self.__resolve_panel_for_action(action) + if panel is None: + return + from datalab.gui.processor.base import ( # pylint: disable=import-outside-toplevel + ProcessingParameters, + extract_processing_parameters, + insert_processing_parameters, + ) + + existing, missing = self._resolve_target_outputs(panel, action) + # Fall back to legacy heuristic when bijective mapping is unavailable. + if not existing and not missing: + legacy = self.__find_output_object_uuid(panel, action) + if legacy is not None: + existing = [legacy] + self._record_missing_outputs(action, missing) + if not existing: + return + output_uuid = existing[0] + try: + output_obj = panel.objmodel[output_uuid] + except KeyError: + return + pp = extract_processing_parameters(output_obj) + if pp is None or pp.source_uuid is None: + return + try: + source_obj = panel.objmodel[pp.source_uuid] + except KeyError: + self._cascade_warnings.append( + _("Action %s: source object was deleted — skipping.") + % (action.func_name or action.uuid) + ) + return + param = action.kwargs.get("param") + new_obj = panel.processor.recompute_1_to_1( + action.func_name, source_obj, param, + plugin_origin=action.plugin_origin, + ) + if new_obj is None: + return + self._update_obj_in_place(output_obj, new_obj) + insert_processing_parameters( + output_obj, + ProcessingParameters( + func_name=pp.func_name, + pattern=pp.pattern, + param=param if param is not None else pp.param, + source_uuid=pp.source_uuid, + ), + ) + panel.processor.auto_recompute_analysis(output_obj) + self._refresh_target(panel, output_uuid) + + def _recompute_1_to_n_in_place(self, action: HistoryAction) -> None: + """Recompute a 1-to-n action in place: replace each of the N outputs.""" + panel = self.__resolve_panel_for_action(action) + if panel is None: + return + from datalab.gui.processor.base import ( # pylint: disable=import-outside-toplevel + ProcessingParameters, + extract_processing_parameters, + insert_processing_parameters, + ) + + existing, missing = self._resolve_target_outputs(panel, action) + self._record_missing_outputs(action, missing) + if not existing: + return + # All outputs of a 1_to_n share the same source. + try: + first_obj = panel.objmodel[existing[0]] + except KeyError: + return + pp = extract_processing_parameters(first_obj) + if pp is None or pp.source_uuid is None: + return + try: + source_obj = panel.objmodel[pp.source_uuid] + except KeyError: + self._cascade_warnings.append( + _("Action %s: source object was deleted — skipping.") + % (action.func_name or action.uuid) + ) + return + params = action.kwargs.get("params") or [] + if not params: + return + new_objs = panel.processor.recompute_1_to_n( + action.func_name, source_obj, params, + plugin_origin=action.plugin_origin, + ) + if not new_objs: + return + # Map each output to its (re)computed counterpart by index. If the + # cardinality changed (e.g. function now produces fewer outputs), + # we update what we can and report the rest as missing. + n = min(len(existing), len(new_objs)) + for idx in range(n): + out_uuid = existing[idx] + try: + out_obj = panel.objmodel[out_uuid] + except KeyError: + continue + new_obj = new_objs[idx] + self._update_obj_in_place(out_obj, new_obj) + new_param = params[idx] if idx < len(params) else None + insert_processing_parameters( + out_obj, + ProcessingParameters( + func_name=action.func_name, + pattern="1-to-n", + param=new_param, + source_uuid=pp.source_uuid, + ), + ) + panel.processor.auto_recompute_analysis(out_obj) + self._refresh_target(panel, out_uuid) + if len(new_objs) != len(existing): + _logger.warning( + "1-to-n cardinality changed for action %s: %d outputs, %d existing.", + action.uuid, + len(new_objs), + len(existing), + ) + + def _recompute_n_to_1_in_place(self, action: HistoryAction) -> None: + """Recompute an n-to-1 action in place.""" + panel = self.__resolve_panel_for_action(action) + if panel is None: + return + from datalab.gui.processor.base import ( # pylint: disable=import-outside-toplevel + ProcessingParameters, + extract_processing_parameters, + insert_processing_parameters, + ) + + existing, missing = self._resolve_target_outputs(panel, action) + self._record_missing_outputs(action, missing) + if not existing: + return + output_uuid = existing[0] + try: + output_obj = panel.objmodel[output_uuid] + except KeyError: + return + pp = extract_processing_parameters(output_obj) + source_uuids: list[str] = [] + if pp is not None and pp.source_uuids: + source_uuids = list(pp.source_uuids) + else: + source_uuids = list( + action.state.selection.get(panel.PANEL_STR_ID, []) + ) + src_objs: list[SignalObj | ImageObj] = [] + for uuid in source_uuids: + try: + src_objs.append(panel.objmodel[uuid]) + except KeyError: + continue + if not src_objs: + self._cascade_warnings.append( + _("Action %s: all source objects were deleted — skipping.") + % (action.func_name or action.uuid) + ) + return + param = action.kwargs.get("param") + new_obj = panel.processor.recompute_n_to_1( + action.func_name, src_objs, param, + plugin_origin=action.plugin_origin, + ) + if new_obj is None: + return + self._update_obj_in_place(output_obj, new_obj) + insert_processing_parameters( + output_obj, + ProcessingParameters( + func_name=action.func_name, + pattern="n-to-1", + param=param, + source_uuids=[get_uuid(o) for o in src_objs], + ), + ) + panel.processor.auto_recompute_analysis(output_obj) + self._refresh_target(panel, output_uuid) + + def _recompute_2_to_1_in_place(self, action: HistoryAction) -> None: + """Recompute a 2-to-1 action in place (single or pairwise).""" + panel = self.__resolve_panel_for_action(action) + if panel is None: + return + from datalab.gui.processor.base import ( # pylint: disable=import-outside-toplevel + ProcessingParameters, + extract_processing_parameters, + insert_processing_parameters, + ) + + existing, missing = self._resolve_target_outputs(panel, action) + self._record_missing_outputs(action, missing) + if not existing: + return + param = action.kwargs.get("param") + obj2_uuids = action.kwargs.get("obj2_uuids") or [] + if isinstance(obj2_uuids, str): + obj2_uuids = [obj2_uuids] + pairwise = bool(action.kwargs.get("pairwise")) + # In pairwise mode, expect one output per (obj1, obj2) pair. + # In single-operand mode, every output uses the same obj2. + recorded_inputs = list(action.state.selection.get(panel.PANEL_STR_ID, [])) + for idx, out_uuid in enumerate(existing): + try: + output_obj = panel.objmodel[out_uuid] + except KeyError: + continue + pp = extract_processing_parameters(output_obj) + src_uuids = ( + list(pp.source_uuids) + if pp is not None and pp.source_uuids + else (recorded_inputs[idx : idx + 1] + obj2_uuids[idx : idx + 1] + if pairwise + else recorded_inputs[idx : idx + 1] + obj2_uuids[:1]) + ) + if len(src_uuids) < 2: + self._cascade_warnings.append( + _("Action %s: missing source(s) for output #%d — skipping.") + % (action.func_name or action.uuid, idx + 1) + ) + continue + try: + obj1 = panel.objmodel[src_uuids[0]] + obj2 = panel.objmodel[src_uuids[1]] + except KeyError: + self._cascade_warnings.append( + _("Action %s: source object(s) were deleted — skipping.") + % (action.func_name or action.uuid) + ) + continue + new_obj = panel.processor.recompute_2_to_1( + action.func_name, obj1, obj2, param, + plugin_origin=action.plugin_origin, + ) + if new_obj is None: + continue + self._update_obj_in_place(output_obj, new_obj) + insert_processing_parameters( + output_obj, + ProcessingParameters( + func_name=action.func_name, + pattern="2-to-1", + param=param, + source_uuids=[get_uuid(obj1), get_uuid(obj2)], + ), + ) + panel.processor.auto_recompute_analysis(output_obj) + self._refresh_target(panel, out_uuid) + + def _recompute_1_to_0_in_place(self, action: HistoryAction) -> None: + """Recompute a 1-to-0 analysis on each source object in place.""" + panel = self.__resolve_panel_for_action(action) + if panel is None: + return + # 1-to-0 produces no data object; recompute on each captured source + # so analysis metadata stays consistent with the (possibly updated) + # data of upstream actions. + sources = list(action.state.selection.get(panel.PANEL_STR_ID, [])) + if not sources: + return + param = action.kwargs.get("param") + missing: list[str] = [] + for uuid in sources: + try: + src_obj = panel.objmodel[uuid] + except KeyError: + missing.append(uuid) + continue + panel.processor.recompute_1_to_0( + action.func_name, src_obj, param, + plugin_origin=action.plugin_origin, + ) + self._refresh_target(panel, uuid) + if missing: + self._cascade_warnings.append( + _("Action %s: %d analysed object(s) were deleted — skipping.") + % (action.func_name or action.uuid, len(missing)) + ) + + def recompute_cascade( + self, + root_action: HistoryAction, + descendants: list[HistoryAction] | None = None, + ) -> None: + """Recompute ``root_action``'s descendants in the current session + in-place (on existing UUIDs). + + Each action involved is flagged ``is_stale`` (light-orange background + in the tree) for the duration of the recompute, then cleared. The + root action itself is normally NOT recomputed here (the caller has + already updated its output object). For a stale Play, ``root_action`` + is included so its own flag is cleared. + + Every supported pattern (``1_to_1``, ``1_to_n``, ``n_to_1``, + ``2_to_1``, ``1_to_0``) is dispatched through + :meth:`_recompute_action_in_place`. Missing or unsupported items + are reported via a single end-of-cascade warning dialog. + + Actions whose underlying processor feature is missing (e.g. plugin + uninstalled) keep ``is_stale = True`` after the cascade completes, + so the visual marker persists until the plugin is reinstalled. + + Args: + root_action: Root action whose descendants must be recomputed. + descendants: Pre-computed downstream actions. When ``None`` + (default), :meth:`get_downstream_actions` is called + internally. Passing a pre-computed list avoids a redundant + graph traversal when the caller has already resolved the + chain (e.g. :meth:`_edit_mode_replay`). + """ + if descendants is None: + descendants = self.get_downstream_actions(root_action) + if root_action.is_stale: + descendants = [root_action] + descendants + # Re-entrancy guard. + if getattr(self, "_cascade_in_progress", False): + self._flush_cascade_warnings() + return + if not descendants: + # Still surface any warnings accumulated by a prior standalone + # ``_recompute_action_in_place`` call (e.g. root recompute in + # ``_edit_mode_replay``) before bailing out. + self._flush_cascade_warnings() + return + # Reset the broken set: only the current cascade's outcomes count. + self._broken_actions.clear() + self._cascade_in_progress = True + try: + for action in descendants: + action.is_stale = True + self.tree.refresh_action_item(action) + QW.QApplication.processEvents() + for action in descendants: + try: + self._recompute_action_in_place(action) + finally: + # Keep the stale marker for actions flagged as broken + # (missing plugin) so the user can spot them in the tree. + if action.uuid not in self._broken_actions: + action.is_stale = False + self.tree.refresh_action_item(action) + QW.QApplication.processEvents() + finally: + for action in descendants: + if action.is_stale and action.uuid not in self._broken_actions: + action.is_stale = False + self.tree.refresh_action_item(action) + self._cascade_in_progress = False + self._flush_cascade_warnings() + + def _flush_cascade_warnings(self) -> None: + """Show + clear accumulated cascade warnings (no-op when empty).""" + if self._cascade_warnings: + QW.QMessageBox.warning( + self.mainwindow, + _("Cascade recompute"), + _("Some downstream actions could not be recomputed:") + + "\n\n• " + + "\n• ".join(self._cascade_warnings), + ) + self._cascade_warnings = [] + + + def __existing_input_uuids( + self, panel: BaseDataPanel, action: HistoryAction + ) -> list[str]: + """Return recorded input UUIDs that still exist in ``panel``.""" + recorded = action.state.selection.get(panel.PANEL_STR_ID, []) + existing: list[str] = [] + for uuid in recorded: + try: + panel.objmodel[uuid] + except KeyError: + continue + existing.append(uuid) + return existing + + def __sync_panel_selection(self) -> None: + """Sync data panel selection from the currently selected tree item.""" + if self.__replaying or self.__syncing: + return + item = self.tree.currentItem() + if item is None or not item.isSelected(): + return + if item.parent() is None: + # Session-level selection: peek the first compute action + index = self.tree.indexOfTopLevelItem(item) + if index < 0 or index >= len(self.__history_sessions): + return + session = self.__history_sessions[index] + action = next( + (a for a in session.actions if a.kind == HistoryAction.KIND_COMPUTE), + None, + ) + if action is None: + return + else: + uuid = item.data(0, QC.Qt.UserRole) + try: + action = self.tree.get_action_from_uuid( + uuid, self.__history_sessions + ) + except ValueError: + return + + panel = self.__resolve_panel_for_action(action) + if panel is None: + return + + target_uuids: list[str] = [] + output_uuid = self.__find_output_object_uuid(panel, action) + if output_uuid is not None: + target_uuids = [output_uuid] + else: + target_uuids = self.__existing_input_uuids(panel, action) + + if not target_uuids: + return + + self.__syncing = True + try: + with QC.QSignalBlocker(panel.objview): + panel.objview.select_objects(target_uuids) + self.mainwindow.set_current_panel(panel) + finally: + self.__syncing = False + + # ------------------------------------------------------------------ + # Step-by-step navigation (B2) + # ------------------------------------------------------------------ + + def __current_action(self) -> HistoryAction | None: + """Return the action currently selected in the tree, or ``None``.""" + item = self.tree.currentItem() + if item is None or item.parent() is None: + return None + uuid = item.data(0, QC.Qt.UserRole) + try: + return self.tree.get_action_from_uuid(uuid, self.__history_sessions) + except ValueError: + return None + + def __current_session(self) -> HistorySession | None: + """Return the session relevant for step navigation.""" + item = self.tree.currentItem() + if item is not None: + if item.parent() is None: + index = self.tree.indexOfTopLevelItem(item) + if 0 <= index < len(self.__history_sessions): + return self.__history_sessions[index] + else: + action = self.__current_action() + if action is not None: + return self._find_parent_session(action) + if self.__history_sessions: + return self.__history_sessions[-1] + return None + + def __can_step_prev(self) -> bool: + """Return True if a previous action exists in the current session.""" + session = self.__current_session() + if session is None or not session.actions: + return False + action = self.__current_action() + if action is None or action not in session.actions: + return False + return session.actions.index(action) > 0 + + def __can_step_next(self) -> bool: + """Return True if a next action exists in the current session.""" + session = self.__current_session() + if session is None or not session.actions: + return False + action = self.__current_action() + if action is None or action not in session.actions: + # No action selected — Next would land on the first one. + return True + return session.actions.index(action) < len(session.actions) - 1 + + def __select_action_in_tree(self, action: HistoryAction) -> None: + """Select ``action`` in the tree (triggers `__sync_panel_selection`).""" + for i in range(self.tree.topLevelItemCount()): + sess_item = self.tree.topLevelItem(i) + for j in range(sess_item.childCount()): + child = sess_item.child(j) + if child.data(0, QC.Qt.UserRole) == action.uuid: + self.tree.clearSelection() + self.tree.setCurrentItem(child) + child.setSelected(True) + return + + def _step_prev(self) -> None: + """Select the previous action in the current session.""" + if not self.__can_step_prev(): + return + session = self.__current_session() + action = self.__current_action() + idx = session.actions.index(action) + self.__select_action_in_tree(session.actions[idx - 1]) + self.__update_actions_state() + + def _step_next(self) -> None: + """Select the next action in the current session.""" + if not self.__can_step_next(): + return + session = self.__current_session() + action = self.__current_action() + if action is None or action not in session.actions: + target = session.actions[0] + else: + target = session.actions[session.actions.index(action) + 1] + self.__select_action_in_tree(target) + self.__update_actions_state() + + def duplicate_selected_entries(self) -> None: + """Duplicate selected sessions (with their data) into new independent sessions. + + For each selected session (or the parent session of a selected action), + all referenced data objects are deep-copied into a new group and the + session is duplicated with all UUID references rewritten to the clones. + The result is an independent, editable and replayable session. + """ + selected = self.tree.get_selected_actions_or_sessions(self.__history_sessions) + if not selected: + return + # Normalise: resolve individual actions to their parent session, deduplicate. + sessions_to_dup: list[HistorySession] = [] + seen: set[int] = set() + for item in selected: + if isinstance(item, HistorySession): + session = item + else: + session = self._find_parent_session(item) + if session is None: + continue + if id(session) not in seen: + seen.add(id(session)) + sessions_to_dup.append(session) + + copy_suffix = _("Copy") + new_sessions: list[HistorySession] = [] + panel_map = { + "signal": self.mainwindow.signalpanel, + "image": self.mainwindow.imagepanel, + } + + for session in sessions_to_dup: + # 1. Collect all UUIDs referenced by this session + uuids_by_panel: dict[str, set[str]] = {} + for action in session.actions: + for pstr, uuids in action.state.selection.items(): + uuids_by_panel.setdefault(pstr, set()).update(uuids) + for pstr, metadata in action.state.object_metadata.items(): + uuids_by_panel.setdefault(pstr, set()).update(metadata.keys()) + obj2 = action.kwargs.get("obj2_uuids") + if obj2: + pstr = action.panel_str or "" + if isinstance(obj2, str): + obj2 = [obj2] + uuids_by_panel.setdefault(pstr, set()).update(obj2) + # Output UUIDs produced by this action (e.g. result of a + # compute step). Without this, the last action's outputs + # would be missing because no subsequent state captures them. + if action.output_uuids: + pstr = action.panel_str or "" + uuids_by_panel.setdefault(pstr, set()).update( + action.output_uuids + ) + + # 2. Clone objects and build uuid_remap + uuid_remap: dict[str, dict[str, str]] = {} + clones_by_pstr: dict[str, list] = {} + group_title = f"{copy_suffix} - {session.title}" + for pstr, uuids in uuids_by_panel.items(): + panel = panel_map.get(pstr) + if panel is None: + continue + uuid_remap[pstr] = {} + existing_ids = set(panel.objmodel.get_object_ids()) + clones = [] + # Iterate in panel order (not set order) to preserve + # the topological object ordering in the duplicated group. + ordered_ids = [ + u for u in panel.objmodel.get_object_ids() if u in uuids + ] + for old_uuid in ordered_ids: + if old_uuid not in existing_ids: + continue + obj = panel.objmodel[old_uuid] + clone = deepcopy(obj) + new_uuid = str(uuid4()) + # SignalObj/ImageObj store UUID via metadata option + try: + clone.set_metadata_option("uuid", new_uuid) + except AttributeError: + clone.uuid = new_uuid + uuid_remap[pstr][old_uuid] = new_uuid + clones.append(clone) + clones_by_pstr[pstr] = clones + if clones: + group_id = get_uuid(panel.add_group(group_title)) + for clone in clones: + panel.add_object(clone, group_id=group_id) + + # Second pass: remap source UUIDs in cloned objects' + # processing_parameters so reprocessing in the Processing tab + # uses the cloned source, not the original. + from datalab.gui.processor.base import ( # pylint: disable=import-outside-toplevel + PROCESSING_PARAMETERS_OPTION, + ProcessingParameters, + ) + + for pstr_inner, clones_inner in clones_by_pstr.items(): + pmap = uuid_remap.get(pstr_inner, {}) + if not pmap: + continue + for clone in clones_inner: + try: + pp_dict = clone.get_metadata_option( + PROCESSING_PARAMETERS_OPTION + ) + except (AttributeError, ValueError): + continue + if not pp_dict: + continue + try: + pp = ProcessingParameters.from_dict(pp_dict) + except Exception: # pylint: disable=broad-except + continue + changed = False + if pp.source_uuid is not None and pp.source_uuid in pmap: + pp.source_uuid = pmap[pp.source_uuid] + changed = True + if pp.source_uuids is not None: + new_src = [pmap.get(u, u) for u in pp.source_uuids] + if new_src != pp.source_uuids: + pp.source_uuids = new_src + changed = True + if changed: + try: + clone.set_metadata_option( + PROCESSING_PARAMETERS_OPTION, pp.to_dict() + ) + except (AttributeError, ValueError): + pass + + # 3. Build the new session with remapped UUIDs + self.__session_increment += 1 + title = f"{session.title} {copy_suffix}" + new_session = session.copy_with_uuid_remap( + title=title, uuid_remap=uuid_remap + ) + new_session.number = self.__session_increment + new_sessions.append(new_session) + + # Register output mappings for cloned actions so that + # _resolve_target_outputs / get_downstream_actions work on + # the duplicated session (same logic as read_h5_data). + for action in new_session.actions: + if action.output_uuids: + self._action_output_uuids[action.uuid] = list( + action.output_uuids + ) + for out_uuid in action.output_uuids: + self._output_to_action[out_uuid] = action.uuid + + # Insert each duplicated session immediately after its original. + offset = 0 + for original_session, new_session in zip(sessions_to_dup, new_sessions): + idx = self.__history_sessions.index(original_session) + self.__history_sessions.insert(idx + 1 + offset, new_session) + offset += 1 + self.tree.populate_tree(self.__history_sessions) + self.__select_sessions(new_sessions) + self.refresh_compatibility_items() + self.__update_actions_state() + + def generate_macro(self) -> None: + """Generate a standalone Python script from selected history entries. + + The generated script uses sigima functions directly with proper variable + chaining. Object references (UUIDs) are resolved to variable names so + that 2-to-1 operations reference the correct intermediate result. + The script is copied to the clipboard and the user is notified. + """ + selected = self.tree.get_selected_actions_or_sessions( + self.__history_sessions + ) + actions: list[HistoryAction] = [] + if not selected: + for session in self.__history_sessions: + actions.extend(session.actions) + else: + for item in selected: + if isinstance(item, HistorySession): + actions.extend(item.actions) + else: + actions.append(item) + if not actions: + return + + # Filter to compute-only actions for the pipeline + compute_actions = [ + a for a in actions if a.kind == HistoryAction.KIND_COMPUTE + ] + if not compute_actions: + QW.QMessageBox.information( + self.mainwindow, + _("Generate macro"), + _("No compute actions to export."), + ) + return + + # Determine input type from first action + first_panel = compute_actions[0].panel_str + if first_panel == "signal": + obj_type = "SignalObj" + obj_import = "from sigima.objects import SignalObj" + else: + obj_type = "ImageObj" + obj_import = "from sigima.objects import ImageObj" + + imports: set[str] = set() + imports.add(obj_import) + body_lines: list[str] = [] + + # UUID → variable mapping for resolving object references. + # Populated with input UUIDs ("src", "src_2", ...) and enriched + # with each step's output UUID after code generation. + uuid_to_var: dict[str, str] = {} + + # Extra input parameters discovered during generation (second + # operands that are not produced by any previous step). + extra_inputs: list[str] = [] + + # Seed the mapping with the first action's input selection. + first_sel = compute_actions[0].state.selection.get( + compute_actions[0].panel_str, [] + ) + for i, uuid in enumerate(first_sel): + var = "src" if i == 0 else f"src_{i + 1}" + uuid_to_var[uuid] = var + + step = 0 + current_var = "src" + + for action in compute_actions: + step += 1 + + # Resolve input variable from the action's selection UUIDs. + sel_uuids = action.state.selection.get( + action.panel_str or "", [] + ) + if sel_uuids and sel_uuids[0] in uuid_to_var: + input_var = uuid_to_var[sel_uuids[0]] + else: + input_var = current_var + + # Resolve second operand for 2-to-1 patterns. + obj2_var: str | None = None + if action.pattern == "2_to_1": + obj2_uuids = action.kwargs.get("obj2_uuids", []) + if isinstance(obj2_uuids, str): + obj2_uuids = [obj2_uuids] + if obj2_uuids: + obj2_uuid = obj2_uuids[0] + if obj2_uuid in uuid_to_var: + obj2_var = uuid_to_var[obj2_uuid] + else: + # External input — add as function parameter. + obj2_var = f"obj2_{step}" + uuid_to_var[obj2_uuid] = obj2_var + extra_inputs.append(obj2_var) + + code_lines, output_var = action.to_macro_code( + step, input_var, imports, obj2_var=obj2_var + ) + body_lines.extend(code_lines) + body_lines.append("") + + if output_var is not None: + current_var = output_var + # Map the output UUID so subsequent steps can reference it. + output_uuid = self._action_output_uuid(action) + if output_uuid: + uuid_to_var[output_uuid] = output_var + # Also register any new UUIDs from the action's selection + # that we haven't seen yet (secondary selections). + for uuid in sel_uuids[1:]: + if uuid not in uuid_to_var: + uuid_to_var[uuid] = input_var + + # Build the function signature with extra inputs. + params_str = f"src: {obj_type}" + for extra in extra_inputs: + params_str += f", {extra}: {obj_type}" + + # Assemble the full script + sorted_imports = sorted(imports) + script_lines: list[str] = [ + '"""', + "DataLab — standalone processing pipeline", + f"Generated from history ({len(compute_actions)} steps)", + '"""', + "", + ] + script_lines.extend(sorted_imports) + script_lines.append("") + script_lines.append("") + script_lines.append( + f"def process({params_str}) -> {obj_type}:" + ) + script_lines.append( + ' """Apply the recorded processing pipeline."""' + ) + for line in body_lines: + script_lines.append(f" {line}" if line else "") + script_lines.append(f" return {current_var}") + script_lines.append("") + script_lines.append("") + script_lines.append('if __name__ == "__main__":') + script_lines.append( + " # Standalone execution: run from DataLab's Macro panel." + ) + script_lines.append(" # Operates on the current object of the target panel.") + script_lines.append( + " from datalab.control.proxy import RemoteProxy" + ) + script_lines.append("") + script_lines.append(" proxy = RemoteProxy()") + panel_str = compute_actions[0].panel_str or ( + "signal" if obj_type == "SignalObj" else "image" + ) + script_lines.append(f' proxy.set_current_panel("{panel_str}")') + script_lines.append(" src = proxy.get_object()") + script_lines.append(" if src is None:") + script_lines.append( + f' raise RuntimeError("No current object in panel: {panel_str}")' + ) + if extra_inputs: + n_extra = len(extra_inputs) + script_lines.append( + " _uuids = [u for u in proxy.get_sel_object_uuids()" + " if u != src.uuid]" + ) + script_lines.append(f" if len(_uuids) < {n_extra}:") + script_lines.append( + " raise RuntimeError(" + ) + script_lines.append( + f' "Pipeline needs {n_extra} extra selected' + ' object(s) besides the current one"' + ) + script_lines.append(" )") + for idx, extra in enumerate(extra_inputs): + script_lines.append( + f" {extra} = proxy.get_object(" + f'_uuids[{idx}], "{panel_str}")' + ) + extra_args = "".join(f", {e}" for e in extra_inputs) + script_lines.append(f" result = process(src{extra_args})") + script_lines.append(" proxy.add_object(result)") + script_lines.append(' print(f"Pipeline applied: {result.title}")') + script_lines.append("") + + script = "\n".join(script_lines) + QW.QApplication.clipboard().setText(script) + QW.QMessageBox.information( + self.mainwindow, + _("Generate macro"), + _("Macro script copied to clipboard (%d actions).") + % len(compute_actions), + ) + + def __select_sessions(self, sessions: list[HistorySession]) -> None: + """Select top-level tree items matching ``sessions``.""" + self.tree.clearSelection() + for session in sessions: + index = self.__history_sessions.index(session) + item = self.tree.topLevelItem(index) + item.setSelected(True) + self.tree.setCurrentItem(item) + + def delete_selected(self) -> None: + """Delete the selected actions or sessions (with confirmation). + + When a top-level session is selected, the entire session is deleted. + When individual actions are selected, they and all subsequent actions + in their parent session are removed. After deletion, the first + available item in the tree is selected automatically. + """ + selected = self.tree.get_selected_actions_or_sessions(self.__history_sessions) + if not selected: + return + has_individual_actions = any( + isinstance(item, HistoryAction) for item in selected + ) + if has_individual_actions: + msg = _( + "Do you really want to delete the selected items?\n\n" + "Note: deleting an action also removes all subsequent " + "actions in the same session." + ) + else: + msg = _("Do you really want to delete the selected items?") + reply = QW.QMessageBox.question( + self.mainwindow, + _("Delete"), + msg, + QW.QMessageBox.Yes | QW.QMessageBox.No, + QW.QMessageBox.No, + ) + if reply != QW.QMessageBox.Yes: + return + sessions_to_remove: set[int] = set() + for item in selected: + if isinstance(item, HistorySession): + sessions_to_remove.add(id(item)) + else: + # Individual action: remove from its parent session + for session in self.__history_sessions: + if item in session.actions: + session.remove_action(item) + if not session.actions: + sessions_to_remove.add(id(session)) + break + self.__history_sessions = [ + s for s in self.__history_sessions if id(s) not in sessions_to_remove + ] + self.tree.populate_tree(self.__history_sessions) + self.refresh_compatibility_items() + self.__update_actions_state() + # Auto-select the first available item after deletion + if self.tree.topLevelItemCount() > 0: + first = self.tree.topLevelItem(0) + self.tree.setCurrentItem(first) + first.setSelected(True) + + def remove_incompatible_actions(self) -> None: + """Remove all actions whose workspace state is incompatible. + + Shows a confirmation dialog listing how many actions will be removed, + then purges them from their sessions. Empty sessions are also removed. + """ + incompatible: list[tuple[HistorySession, HistoryAction]] = [] + for session in self.__history_sessions: + for action in session.actions: + if not action.is_current_state_compatible( + self.mainwindow, restore_selection=True + ): + incompatible.append((session, action)) + if not incompatible: + QW.QMessageBox.information( + self.mainwindow, + _("Remove incompatible"), + _("All actions are compatible with the current workspace."), + ) + return + reply = QW.QMessageBox.question( + self.mainwindow, + _("Remove incompatible"), + _("%d incompatible action(s) will be removed. Continue?") + % len(incompatible), + QW.QMessageBox.Yes | QW.QMessageBox.No, + QW.QMessageBox.No, + ) + if reply != QW.QMessageBox.Yes: + return + for session, action in incompatible: + if action in session.actions: + session.actions.remove(action) + # Remove empty sessions + self.__history_sessions = [ + s for s in self.__history_sessions if s.actions + ] + self.tree.populate_tree(self.__history_sessions) + self.refresh_compatibility_items() + self.__update_actions_state() + + def save_to_dlhist_file(self, filename: str | None = None) -> bool: + """Save the History Panel content to a standalone ``.dlhist`` file. + + Args: + filename: History filename. If None, a file dialog is opened. + + Returns: + True if the history was saved, False if the operation was canceled. + """ + if filename is None: + basedir = Conf.main.base_dir.get() + with save_restore_stds(): + filename, _filt = getsavefilename( + self, _("Save history file"), basedir, self.FILE_FILTERS + ) + if not filename: + return False + if osp.splitext(filename)[1] == "": + filename += ".dlhist" + with qt_try_loadsave_file(self.parentWidget(), filename, "save"): + Conf.main.base_dir.set(filename) + from datalab.h5.native import NativeH5Writer # pylint: disable=C0415 + + with NativeH5Writer(filename) as writer: + # Make the .dlhist file self-contained: store the signal and + # image panel objects (all of them) alongside the history, so + # that reopening restores both the data objects and the history + # that references them. Each section is read back by its own + # H5_PREFIX key, so the write order is not significant. + self.mainwindow.signalpanel.serialize_to_hdf5(writer) + self.mainwindow.imagepanel.serialize_to_hdf5(writer) + self.serialize_to_hdf5(writer) + return True + + def open_dlhist_file(self, filename: str | None = None) -> bool: + """Open a standalone ``.dlhist`` file into the History Panel. + + Args: + filename: History filename. If None, a file dialog is opened. + + Returns: + True if the history was loaded, False if the operation was canceled. + """ + if filename is None: + basedir = Conf.main.base_dir.get() + with save_restore_stds(): + filename, _filt = getopenfilename( + self, _("Open history file"), basedir, self.FILE_FILTERS + ) + if not filename: + return False + with qt_try_loadsave_file(self.parentWidget(), filename, "load"): + Conf.main.base_dir.set(filename) + from datalab.h5.native import NativeH5Reader # pylint: disable=C0415 + + with NativeH5Reader(filename) as reader: + # A self-contained .dlhist file stores the signal and image + # panel objects in addition to the history sessions. The way + # they are restored depends on whether the workspace is already + # in use (data objects OR history): a pristine workspace is + # loaded directly while preserving UUIDs, otherwise the file + # is imported as new groups/sessions. + workspace_in_use = ( + self.mainwindow.signalpanel.objmodel.get_object_ids() + or self.mainwindow.imagepanel.objmodel.get_object_ids() + or bool(self.__history_sessions) + ) + if workspace_in_use: + # Workspace not empty: import the objects into new groups + # with fresh UUIDs and append the history as new sessions + # whose references are remapped to the imported objects. + self.__import_dlhist_into_new_session(reader) + else: + # Workspace empty: load directly, preserving original UUIDs + # (reset_all=True) so that history references stay valid. + self.mainwindow.signalpanel.deserialize_from_hdf5( + reader, reset_all=True + ) + self.mainwindow.imagepanel.deserialize_from_hdf5( + reader, reset_all=True + ) + self.deserialize_from_hdf5(reader) + return True + + def __import_dlhist_into_new_session(self, reader: NativeH5Reader) -> None: + """Import a ``.dlhist`` file into new groups and new history sessions. + + Used when the workspace already contains objects: the file's signal and + image objects are imported into fresh groups with regenerated UUIDs, and + the history sessions are appended as new independent sessions whose action + references are remapped to the freshly imported objects. + + Args: + reader: HDF5 reader positioned on a ``.dlhist`` file. + """ + panel_map = { + "signal": self.mainwindow.signalpanel, + "image": self.mainwindow.imagepanel, + } + uuid_remap: dict[str, dict[str, str]] = {} + imported_by_pstr: dict[str, list] = {} + # 1. Import objects from each panel (each panel is read by its own + # H5_PREFIX key). Read each object preserving its original UUID to + # capture the old->new mapping, then assign a fresh UUID so that the + # imported objects keep an independent identity. + for pstr, panel in panel_map.items(): + uuid_remap[pstr] = {} + imported: list = [] + imported_by_pstr[pstr] = imported + if panel.H5_PREFIX not in reader.h5: + continue + with reader.group(panel.H5_PREFIX): + for name in reader.h5.get(panel.H5_PREFIX, []): + with reader.group(name): + group = panel.add_group("") + with reader.group("title"): + group.title = reader.read_str() + for obj_name in reader.h5.get( + f"{panel.H5_PREFIX}/{name}", [] + ): + obj = panel.deserialize_object_from_hdf5( + reader, obj_name, reset_all=True + ) + old_uuid = get_uuid(obj) + new_uuid = str(uuid4()) + # SignalObj/ImageObj store UUID via metadata option + try: + obj.set_metadata_option("uuid", new_uuid) + except AttributeError: + obj.uuid = new_uuid + uuid_remap[pstr][old_uuid] = new_uuid + panel.add_object( + obj, get_uuid(group), set_current=False + ) + imported.append(obj) + panel.selection_changed() + # 2. Remap source UUIDs in imported objects' processing_parameters so + # that reprocessing in the Processing tab uses the imported sources, + # not the originals (same logic as duplicate_selected_entries). + from datalab.gui.processor.base import ( # pylint: disable=import-outside-toplevel + PROCESSING_PARAMETERS_OPTION, + ProcessingParameters, + ) + + for pstr, objs in imported_by_pstr.items(): + pmap = uuid_remap.get(pstr, {}) + if not pmap: + continue + for obj in objs: + try: + pp_dict = obj.get_metadata_option(PROCESSING_PARAMETERS_OPTION) + except (AttributeError, ValueError): + continue + if not pp_dict: + continue + try: + pp = ProcessingParameters.from_dict(pp_dict) + except Exception: # pylint: disable=broad-except + continue + changed = False + if pp.source_uuid is not None and pp.source_uuid in pmap: + pp.source_uuid = pmap[pp.source_uuid] + changed = True + if pp.source_uuids is not None: + new_src = [pmap.get(u, u) for u in pp.source_uuids] + if new_src != pp.source_uuids: + pp.source_uuids = new_src + changed = True + if changed: + try: + obj.set_metadata_option( + PROCESSING_PARAMETERS_OPTION, pp.to_dict() + ) + except (AttributeError, ValueError): + pass + # 3. Import history sessions as new independent sessions whose captured + # UUIDs are remapped to the imported objects. + if self.H5_PREFIX not in reader.h5: + return + sessions = reader.read_object_list(self.H5_PREFIX, HistorySession) or [] + imported_suffix = _("Imported") + new_sessions: list[HistorySession] = [] + for session in sessions: + self.__session_increment += 1 + title = f"{session.title} {imported_suffix}" + new_session = session.copy_with_uuid_remap( + title=title, uuid_remap=uuid_remap + ) + new_session.number = self.__session_increment + new_sessions.append(new_session) + # Register output mappings for imported actions so that + # _resolve_target_outputs / get_downstream_actions work. + for action in new_session.actions: + if action.output_uuids: + self._action_output_uuids[action.uuid] = list( + action.output_uuids + ) + for out_uuid in action.output_uuids: + self._output_to_action[out_uuid] = action.uuid + self.__history_sessions.extend(new_sessions) + self.tree.populate_tree(self.__history_sessions) + self.refresh_compatibility_items() + self.__update_actions_state() + + def refresh_compatibility_items(self, *args: Any) -> None: + """Refresh action item compatibility markers in the tree.""" + del args + self.tree.update_compatibility_states(self.__history_sessions, self.mainwindow) + + def serialize_to_hdf5(self, writer: NativeH5Writer) -> None: + """Serialize whole panel to a HDF5 file + + Args: + writer: HDF5 writer + """ + writer.write_object_list(self.__history_sessions, self.H5_PREFIX) + + def deserialize_from_hdf5( + self, reader: NativeH5Reader, reset_all: bool = False + ) -> None: + """Deserialize whole panel from a HDF5 file Args: reader: HDF5 reader reset_all: Unused (kept for compatibility with panel API) """ + if self.H5_PREFIX not in reader.h5: + self.__history_sessions = [] + self.__session_increment = 0 + self.tree.populate_tree(self.__history_sessions) + self.__update_actions_state() + return self.__history_sessions: list[HistorySession] = ( reader.read_object_list(self.H5_PREFIX, HistorySession) or [] ) if self.__history_sessions: self.__session_increment = self.__history_sessions[-1].number + # Rebuild the bijective mapping from the loaded actions. Legacy + # (v1) actions have empty ``output_uuids`` and contribute nothing + # to the index — the heuristic fallback handles them. + self._action_output_uuids = {} + self._output_to_action = {} + for session in self.__history_sessions: + for action in session.actions: + if action.output_uuids: + self._action_output_uuids[action.uuid] = list( + action.output_uuids + ) + for out_uuid in action.output_uuids: + self._output_to_action[out_uuid] = action.uuid self.tree.populate_tree(self.__history_sessions) + self.refresh_compatibility_items() self.__update_actions_state() def __len__(self) -> int: @@ -1384,6 +4425,12 @@ def create_new_session(self) -> None: session = HistorySession(number=self.__session_increment) self.__history_sessions.append(session) self.tree.populate_tree(self.__history_sessions) + self.refresh_compatibility_items() + + def start_new_session_after_workspace_reset(self) -> None: + """Start a new history session after a workspace reset, when useful.""" + if self.__history_sessions and self.__history_sessions[-1].actions: + self.create_new_session() def add_compute_entry( self, @@ -1392,8 +4439,10 @@ def add_compute_entry( func_name: str, pattern: str, save_state: bool = True, + output_uuids: list[str] | None = None, + plugin_origin: dict[str, Any] | None = None, **kwargs: Any, - ) -> None: + ) -> HistoryAction | None: """Record a *compute* action in the current history session. Args: @@ -1405,26 +4454,48 @@ def add_compute_entry( ``"1_to_n"``, ``"multiple_1_to_1"`` (the latter is recorded for traceability but not replayable). save_state: If True, capture the workspace state for replay. + output_uuids: Optional list of UUIDs of the data objects produced by + this action. When known at call time, prefer passing it here so the + bijective mapping is initialised in one step. Most callers do not + know the outputs yet and instead wrap the compute call with + :meth:`capture_outputs` (or call :meth:`register_action_outputs` + explicitly afterwards) using the returned action. + plugin_origin: Optional plugin origin descriptor (see + :func:`datalab.gui.processor.base._detect_plugin_origin`). ``None`` + for built-in Sigima/DataLab features. **kwargs: Extra primitive kwargs (``param``, ``obj2_uuids``, ``obj2_name``, ``pairwise``, ``params`` (list of DataSet), ``func_names`` (list of str), ...). ``DataSet`` instances are serialised as JSON. + + Returns: + The created :class:`HistoryAction`, or ``None`` if recording is + disabled (record mode off or replay in progress). """ if not self.__record_mode or self.__replaying: - return + return None state = WorkspaceState() if save_state: state.save(self.mainwindow) + # Deep-copy kwargs so each action owns independent parameter + # instances. Without this, consecutive applications of the same + # function (e.g. two gaussian_filter calls with different sigma) + # would share a single DataSet object and editing one action's + # parameters would silently mutate the other. action = HistoryAction( title=action_title, kind=HistoryAction.KIND_COMPUTE, panel_str=panel_str, func_name=func_name, pattern=pattern, - kwargs=kwargs, + kwargs=deepcopy(kwargs), state=state, + plugin_origin=plugin_origin, ) self.add_object(action) + if output_uuids is not None: + self.register_action_outputs(action, output_uuids) + return action def add_compute_entry_from_pp( self, @@ -1432,8 +4503,10 @@ def add_compute_entry_from_pp( pp: Any, # ProcessingParameters (avoid circular import) panel_str: str, save_state: bool = True, + output_uuids: list[str] | None = None, + plugin_origin: dict[str, Any] | None = None, **extras: Any, - ) -> None: + ) -> HistoryAction | None: """Record a *compute* action derived from a ``ProcessingParameters``. Bridges the dash-form pattern used in object metadata @@ -1447,23 +4520,329 @@ def add_compute_entry_from_pp( instance describing the operation. panel_str: ``"signal"`` or ``"image"``. save_state: If True, capture the workspace state for replay. + output_uuids: Optional list of UUIDs of the data objects produced + by this action (see :meth:`add_compute_entry`). + plugin_origin: Optional plugin origin descriptor (see + :meth:`add_compute_entry`). **extras: Additional history-only kwargs (``obj2_uuids``, ``obj2_name``, ``pairwise``, ``params``, ``func_names``…). + + Returns: + The created :class:`HistoryAction`, or ``None`` if recording is + disabled. """ hist_pattern = pp.pattern.replace("-", "_") kwargs: dict[str, Any] = {} if pp.param is not None and "param" not in extras and "params" not in extras: kwargs["param"] = pp.param kwargs.update(extras) - self.add_compute_entry( + return self.add_compute_entry( action_title, panel_str=panel_str, func_name=pp.func_name, pattern=hist_pattern, save_state=save_state, + output_uuids=output_uuids, + plugin_origin=plugin_origin, **kwargs, ) + def register_action_outputs( + self, action: HistoryAction, output_uuids: list[str] + ) -> None: + """Register the data objects produced by ``action``. + + Maintains the bijective ``action → outputs`` and ``output → action`` + mappings. May be called multiple times for a given action (later calls + replace earlier ones, e.g. after a cascade recompute). + + Args: + action: The history action that produced the outputs. + output_uuids: UUIDs of the produced data objects (empty for + ``1_to_0`` analysis patterns and for UI actions that did not + create new objects). + """ + # Drop previous outputs for this action from the reverse index. + previous = self._action_output_uuids.get(action.uuid, []) + for prev_uuid in previous: + if self._output_to_action.get(prev_uuid) == action.uuid: + self._output_to_action.pop(prev_uuid, None) + new_outputs = list(output_uuids) + # Ownership transfer: if an output_uuid already belongs to a + # *different* action, remove it from that action's output list so the + # forward mapping stays consistent. The HistoryAction object's + # ``output_uuids`` attribute is NOT updated here because traversing all + # sessions to locate the object would be expensive; the panel-level + # dicts are the source of truth. + for out_uuid in new_outputs: + old_action_uuid = self._output_to_action.get(out_uuid) + if old_action_uuid is not None and old_action_uuid != action.uuid: + old_list = self._action_output_uuids.get(old_action_uuid) + if old_list is not None: + try: + old_list.remove(out_uuid) + except ValueError: + pass + if not old_list: + del self._action_output_uuids[old_action_uuid] + _logger.debug( + "Output %s transferred from action %s to %s", + out_uuid, + old_action_uuid, + action.uuid, + ) + action.output_uuids = list(new_outputs) + self._action_output_uuids[action.uuid] = new_outputs + for out_uuid in new_outputs: + self._output_to_action[out_uuid] = action.uuid + + @contextmanager + def capture_outputs( + self, action: HistoryAction | None + ) -> Generator[None, None, None]: + """Context manager: snapshot panel object IDs and record diffs as outputs. + + Use around any compute call when the produced UUIDs are not known + upfront. On exit, every newly-added object (signal or image) is + registered as an output of ``action`` via + :meth:`register_action_outputs`. No-op when ``action`` is ``None`` + (recording disabled). + + Args: + action: The history action being processed, or ``None``. + """ + if action is None: + yield + return + panels = (self.mainwindow.signalpanel, self.mainwindow.imagepanel) + before = { + p.PANEL_STR_ID: set(p.objmodel.get_object_ids()) for p in panels + } + try: + yield + finally: + new_uuids: list[str] = [] + for p in panels: + before_p = before[p.PANEL_STR_ID] + for uid in p.objmodel.get_object_ids(): + if uid not in before_p: + new_uuids.append(uid) + self.register_action_outputs(action, new_uuids) + + def _prune_output_mapping(self) -> None: + """Drop entries of :attr:`_output_to_action` whose object no longer exists. + + Connected to each data panel's ``SIG_OBJECT_REMOVED`` so that the + reverse index stays consistent with the live workspace. The forward + ``_action_output_uuids`` mapping is intentionally left intact: it + records the *historical* outputs of each action (useful for replay + and cascade introspection even after an output was deleted). + """ + if not self._output_to_action: + return + alive: set[str] = set() + for panel in (self.mainwindow.signalpanel, self.mainwindow.imagepanel): + alive.update(panel.objmodel.get_object_ids()) + stale = [u for u in self._output_to_action if u not in alive] + for u in stale: + self._output_to_action.pop(u, None) + + def _reconnect_chain_after_removal(self, panel: BaseDataPanel) -> None: + """Reconnect the processing chain after object(s) were deleted from a + data panel, like removing a link from a linked list. + + Each deleted object that was an intermediate processing result has its + downstream consumers reconnected to its own source (the first source for + multi-source operations) and recomputed in cascade, so the chain keeps + producing consistent results. Cases that cannot be reconnected (the + deleted object has no valid source) are reported in a single warning but + the deletion is always kept. + + Connected to each data panel's ``SIG_OBJECT_REMOVED`` (bound to the + panel via ``functools.partial``). Runs before :meth:`_prune_output_mapping` + so the bijective output map is still available. + """ + pstr = panel.PANEL_STR_ID + previous = self.__obj_ids_snapshot.get(pstr, set()) + current = set(panel.objmodel.get_object_ids()) + removed = previous - current + if not removed or self.__reconnecting: + return + self.__reconnecting = True + try: + warnings: list[str] = [] + roots_to_recompute: list[HistoryAction] = [] + for x_uuid in removed: + self.__reconnect_single_removed( + panel, x_uuid, warnings, roots_to_recompute + ) + for action in roots_to_recompute: + self._recompute_action_in_place(action) + self.recompute_cascade(action) + if warnings: + QW.QMessageBox.warning( + self.mainwindow, + _("Delete"), + _( + "Some operations could not be reconnected after " + "deletion:" + ) + + "\n\n• " + + "\n• ".join(warnings), + ) + self.tree.populate_tree(self.__history_sessions) + self.refresh_compatibility_items() + self.__update_actions_state() + finally: + self.__reconnecting = False + self.__refresh_obj_ids_snapshot() + + def __reconnect_single_removed( + self, + panel: BaseDataPanel, + x_uuid: str, + warnings: list[str], + roots_to_recompute: list[HistoryAction], + ) -> None: + """Reconnect consumers of a single deleted object ``x_uuid``. + + Appends a localized message to ``warnings`` when reconnection is not + possible, and appends each consumer's producing action to + ``roots_to_recompute`` so the caller can recompute the cascade. + """ + from datalab.gui.processor.base import ( # pylint: disable=import-outside-toplevel + ProcessingParameters, + extract_processing_parameters, + insert_processing_parameters, + ) + + pstr = panel.PANEL_STR_ID + # 1. Producing action of the deleted object (to learn its source). + action_a = None + action_a_uuid = self._output_to_action.get(x_uuid) + if action_a_uuid is not None: + for session in self.__history_sessions: + for a in session.actions: + if a.uuid == action_a_uuid: + action_a = a + break + if action_a is not None: + break + # 2. Consumers: objects whose processing references x_uuid as a source. + consumers: list[tuple[Any, Any]] = [] + for obj in panel.objmodel: + pp = extract_processing_parameters(obj) + if pp is None: + continue + if pp.source_uuid == x_uuid or ( + pp.source_uuids and x_uuid in pp.source_uuids + ): + consumers.append((obj, pp)) + if not consumers: + # Leaf deletion: nothing downstream to reconnect. + return + # 3. Source S of the deleted object (first source for multi-source ops). + s_uuid: str | None = None + if action_a is not None: + sel = action_a.state.selection.get(pstr, []) + if sel: + s_uuid = sel[0] + alive_ids = set(panel.objmodel.get_object_ids()) + if s_uuid is None or s_uuid not in alive_ids: + label = ( + action_a.title + or action_a.func_name + if action_a is not None + else x_uuid + ) + warnings.append( + _( + "“%s” has dependent operations but no valid source to " + "reconnect to — downstream results are left unchanged." + ) + % label + ) + return + # 4. Reconnect each consumer: replace x_uuid -> s_uuid in its pp and in + # its producing action's recorded inputs, then queue it for recompute. + for obj, pp in consumers: + new_source_uuid = ( + s_uuid if pp.source_uuid == x_uuid else pp.source_uuid + ) + new_source_uuids = pp.source_uuids + if pp.source_uuids and x_uuid in pp.source_uuids: + new_source_uuids = [ + s_uuid if u == x_uuid else u for u in pp.source_uuids + ] + insert_processing_parameters( + obj, + ProcessingParameters( + func_name=pp.func_name, + pattern=pp.pattern, + param=pp.param, + source_uuid=new_source_uuid, + source_uuids=new_source_uuids, + ), + ) + if pp.func_name: + action_b = self.find_action_for_output( + get_uuid(obj), pp.func_name + ) + if action_b is not None: + self.__rewrite_action_source( + action_b, pstr, x_uuid, s_uuid + ) + if action_b not in roots_to_recompute: + roots_to_recompute.append(action_b) + # 5. Drop the deleted node's action if all its outputs are gone. + if action_a is not None: + outs = self._action_output_uuids.get(action_a.uuid, []) + if not any(o in alive_ids for o in outs): + self.__remove_single_action(action_a) + + def __rewrite_action_source( + self, + action: HistoryAction, + pstr: str, + old_uuid: str, + new_uuid: str, + ) -> None: + """Replace ``old_uuid`` with ``new_uuid`` in an action's recorded inputs. + + Updates both the captured selection and the ``obj2_uuids`` kwarg (for + 2_to_1 actions) so future replays/recomputes use the new source. + """ + sel = action.state.selection.get(pstr) + if sel: + action.state.selection[pstr] = [ + new_uuid if u == old_uuid else u for u in sel + ] + obj2 = action.kwargs.get("obj2_uuids") + if isinstance(obj2, str): + if obj2 == old_uuid: + action.kwargs["obj2_uuids"] = new_uuid + elif obj2: + action.kwargs["obj2_uuids"] = [ + new_uuid if u == old_uuid else u for u in obj2 + ] + + def __remove_single_action(self, action: HistoryAction) -> None: + """Remove a single action from its session (splice, not truncate). + + Also drops the action's entries from the bijective output maps, and + removes the parent session if it becomes empty. + """ + for session in self.__history_sessions: + if action in session.actions: + session.actions.remove(action) + outs = self._action_output_uuids.pop(action.uuid, []) + for out_uuid in outs: + if self._output_to_action.get(out_uuid) == action.uuid: + self._output_to_action.pop(out_uuid, None) + if not session.actions: + self.__history_sessions.remove(session) + break + def add_ui_entry( self, action_title: str, @@ -1488,12 +4867,14 @@ def add_ui_entry( state = WorkspaceState() if save_state: state.save(self.mainwindow) + # Deep-copy kwargs to ensure independent parameter ownership + # (same rationale as in add_compute_entry). action = HistoryAction( title=action_title, kind=HistoryAction.KIND_UI, target=target, method_name=method_name, - kwargs=kwargs, + kwargs=deepcopy(kwargs), state=state, ) self.add_object(action) @@ -1541,9 +4922,12 @@ def add_object(self, obj: HistoryAction) -> None: self.__history_sessions[-1].add_action(obj) self.tree.add_action_to_tree(obj) self.tree.rearrange_tree() + self.refresh_compatibility_items() self.__update_actions_state() def remove_all_objects(self): """Remove all objects""" super().remove_all_objects() + self._action_output_uuids.clear() + self._output_to_action.clear() self.__update_actions_state() diff --git a/datalab/gui/processor/base.py b/datalab/gui/processor/base.py index 5507ad00d..412b3a1fa 100644 --- a/datalab/gui/processor/base.py +++ b/datalab/gui/processor/base.py @@ -1,4 +1,4 @@ -# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. """ .. Base processor object (see parent package :mod:`datalab.gui.processor`) @@ -9,10 +9,12 @@ from __future__ import annotations import abc +import inspect import multiprocessing +import os.path as osp import time import warnings -from dataclasses import asdict, dataclass +from dataclasses import asdict, dataclass, field from enum import Enum, auto from multiprocessing.pool import Pool from typing import TYPE_CHECKING, Any, Callable, Generic, Literal, Optional @@ -527,6 +529,158 @@ def is_pairwise_mode() -> bool: return state +class FeatureNotFoundError(ValueError): + """Raised when a computing feature cannot be resolved by name or callable. + + Inherits from :class:`ValueError` to preserve backward compatibility with + callers that already catch ``ValueError`` on lookup failures. + + Attributes: + func_name: Name (or repr) of the missing feature. + plugin_origin: Optional plugin origin descriptor captured at registration + time. See :func:`_detect_plugin_origin` for the dict shape. + paramclass_name: Optional name of the required parameter class (for + diagnostic display). + """ + + def __init__( + self, + func_name: str, + plugin_origin: dict[str, Any] | None = None, + paramclass_name: str | None = None, + ) -> None: + self.func_name = func_name + self.plugin_origin = plugin_origin + self.paramclass_name = paramclass_name + super().__init__(self._build_message()) + + def _build_message(self) -> str: + """Build the default exception message.""" + if self.plugin_origin: + po = self.plugin_origin + param = self.paramclass_name or "—" + return ( + f"Cannot replay action: function '{self.func_name}' from plugin " + f"'{po.get('plugin_class')}' (module: {po.get('module')}, " + f"directory: {po.get('directory')}) is not available. " + f"Required parameter class: {param}. " + "Please reinstall or check the plugin." + ) + return f"Unknown computing feature: {self.func_name}" + + +# Module name prefixes considered as built-in (not plugin) origins. +_BUILTIN_MODULE_PREFIXES: tuple[str, ...] = ( + "sigima", + "datalab", + "numpy", + "scipy", + "skimage", + "guidata", + "plotpy", + "qtpy", + "builtins", + "__main__", +) + + +def _detect_plugin_origin(func: Callable) -> dict[str, Any] | None: + """Detect whether ``func`` originates from a DataLab plugin. + + Inspects ``func.__module__`` and compares it against registered plugins + (:class:`datalab.plugins.PluginRegistry`). Falls back to a heuristic for + modules that are clearly not from the DataLab/Sigima/scientific-Python + built-in surface (then treated as "anonymous" plugin origin). + + **Wrapper-aware**: when *func* is a Sigima wrapper (e.g. + ``Wrap1to1Func``), its ``__module__`` points to the wrapper class's + module (``sigima.proc.image.base``), not to the user-supplied function. + The method therefore probes ``func.__wrapped__`` (``functools.wraps`` + convention) and ``func.func`` (Sigima ``Wrap1to1Func`` / signal + ``Wrap1to1Func`` attribute) to recover the *inner* function and uses + that function's ``__module__`` for origin detection. + + Args: + func: Computation function to inspect. + + Returns: + A dict ``{"plugin_class", "module", "directory", "version"}`` if the + function originates from a plugin, otherwise ``None``. + """ + # Build a list of candidate functions to inspect, starting with the + # innermost wrapped function so that plugin origins are detected even + # when the outer callable belongs to a built-in module (e.g. sigima). + candidates: list[Callable] = [] + inner = getattr(func, "__wrapped__", None) or getattr(func, "func", None) + if inner is not None and callable(inner): + candidates.append(inner) + candidates.append(func) + + module_name = "" + for candidate in candidates: + mod = getattr(candidate, "__module__", "") or "" + if mod: + top = mod.split(".", 1)[0] + if top not in _BUILTIN_MODULE_PREFIXES: + module_name = mod + break + if not module_name: + # All candidates are built-in; fall back to the outer func's module + # so the rest of the logic can still run (and return None). + module_name = getattr(func, "__module__", "") or "" + if not module_name: + return None + # Local import to avoid a circular dependency at module load time. + try: + from datalab.plugins import ( # pylint: disable=import-outside-toplevel + PluginRegistry, + ) + except ImportError: + PluginRegistry = None # type: ignore[assignment] + + if PluginRegistry is not None: + for plugin in PluginRegistry.get_plugins(): + plugin_module = plugin.__class__.__module__ + if module_name == plugin_module or module_name.startswith( + plugin_module + "." + ): + directory: str | None = None + try: + directory = osp.basename( + osp.dirname(inspect.getfile(plugin.__class__)) + ) + except (TypeError, OSError): + pass + version: str | None = None + info = getattr(plugin, "info", None) + if info is not None: + version = getattr(info, "version", None) + return { + "plugin_class": plugin.__class__.__name__, + "module": module_name, + "directory": directory, + "version": version, + } + + # Heuristic fallback: anything not from a known built-in prefix is + # treated as an anonymous plugin origin (e.g. user macros, third-party + # functions wrapped through ``compute_1_to_1`` directly). + top = module_name.split(".", 1)[0] + if top and top not in _BUILTIN_MODULE_PREFIXES: + directory = None + try: + directory = osp.basename(osp.dirname(inspect.getfile(func))) + except (TypeError, OSError): + pass + return { + "plugin_class": None, + "module": module_name, + "directory": directory, + "version": None, + } + return None + + @dataclass class ComputingFeature: """Computing feature dataclass. @@ -541,6 +695,9 @@ class ComputingFeature: edit: whether to edit the parameters obj2_name: name of the second object skip_xarray_compat: whether to skip X-array compatibility check for this feature + plugin_origin: optional plugin origin descriptor (auto-detected at + :meth:`BaseProcessor.add_feature` time). ``None`` for built-in + (Sigima/DataLab) features. """ pattern: Literal["1_to_1", "1_to_0", "1_to_n", "n_to_1", "2_to_1"] @@ -552,6 +709,7 @@ class ComputingFeature: edit: Optional[bool] = None obj2_name: Optional[str] = None skip_xarray_compat: Optional[bool] = None + plugin_origin: Optional[dict[str, Any]] = field(default=None) def __post_init__(self): """Validate the function after initialization.""" @@ -776,6 +934,9 @@ def _add_object_to_appropriate_panel( If False, non-native objects are added to default group. Set to False when group_id is from the source panel and object goes to a different panel. """ + hpanel = getattr(self.mainwindow, "historypanel", None) + if hpanel is not None and hpanel.is_output_suppressed(): + return is_new_obj_native = isinstance(new_obj, self.panel.PARAMCLASS) if is_new_obj_native: self.panel.add_object(new_obj, group_id=group_id) @@ -787,7 +948,7 @@ def _add_object_to_appropriate_panel( def _create_group_for_result( self, new_obj: SignalObj | ImageObj, group_name: str - ) -> str: + ) -> str | None: """Create a group in the appropriate panel for the result object. For native objects, creates group in current panel. For non-native objects, @@ -798,8 +959,11 @@ def _create_group_for_result( group_name: Name for the new group Returns: - UUID of the created group + UUID of the created group. """ + hpanel = getattr(self.mainwindow, "historypanel", None) + if hpanel is not None and hpanel.is_output_suppressed(): + return None is_new_obj_native = isinstance(new_obj, self.panel.PARAMCLASS) if is_new_obj_native: return get_uuid(self.panel.add_group(group_name)) @@ -1030,7 +1194,7 @@ def auto_recompute_analysis( feature = self.get_feature(proc_params.func_name) # Recompute the analysis operation silently, only for this specific object - # (not all selected objects, to avoid O(n²) behavior when called in a loop). + # (not all selected objects, to avoid O(n²) behavior when called in a loop). # The history-panel ``replaying()`` guard suppresses the synthetic entry # that ``compute_1_to_0`` would otherwise add for this internally-triggered # recomputation. @@ -1083,6 +1247,7 @@ def recompute_1_to_1( func_name: str, obj: SignalObj | ImageObj, param: gds.DataSet | None = None, + plugin_origin: dict[str, Any] | None = None, ) -> SignalObj | ImageObj | None: """Recompute a 1-to-1 processing operation without adding result to panel. @@ -1095,18 +1260,22 @@ def recompute_1_to_1( func_name: Name of the processing function obj: Source object to process param: Processing parameters (optional) + plugin_origin: Optional plugin origin descriptor (propagated to + :meth:`get_feature` for richer error reporting). Returns: New processed object (not added to panel), or None if cancelled or error Raises: - ValueError: If function is not found in registry + FeatureNotFoundError: If function is not found in registry. """ # Get the function from the registry - try: - feature = self.get_feature(func_name) - except ValueError as exc: - raise ValueError(f"Function '{func_name}' not found in registry") from exc + paramclass_name = type(param).__name__ if param is not None else None + feature = self.get_feature( + func_name, + plugin_origin=plugin_origin, + paramclass_name=paramclass_name, + ) func = feature.function @@ -1135,6 +1304,185 @@ def recompute_1_to_1( patch_title_with_ids(new_obj, [obj], get_short_id) return new_obj + # ------------------------------------------------------------------ + # In-place recompute helpers used by the History panel cascade + # (Edit mode tweaks + downstream propagation). They mirror their + # ``compute_*`` counterparts but: + # - never add results to a panel (caller updates targets in place); + # - never record a history entry (cascade runs under ``replaying``); + # - never insert :class:`ProcessingParameters` (caller does, so that + # ``source_uuid`` / ``source_uuids`` stay consistent with the + # existing output object identity). + # ------------------------------------------------------------------ + + def recompute_1_to_n( + self, + func_name: str, + obj: SignalObj | ImageObj, + params: list[gds.DataSet], + plugin_origin: dict[str, Any] | None = None, + ) -> list[SignalObj | ImageObj] | None: + """Recompute a 1-to-n processing operation without adding results to panel. + + Args: + func_name: Name of the processing function. + obj: Source object to process. + params: List of N parameter datasets (one per output). + plugin_origin: Optional plugin origin descriptor. + + Returns: + List of N new objects (in input order), or ``None`` if cancelled + or an unrecoverable error occurred. Shorter lists are possible + when individual sub-calls return ``None``. + """ + paramclass_name = ( + type(params[0]).__name__ if params and params[0] is not None else None + ) + feature = self.get_feature( + func_name, + plugin_origin=plugin_origin, + paramclass_name=paramclass_name, + ) + func = feature.function + results: list[SignalObj | ImageObj] = [] + with create_progress_bar( + self.panel, _("Recomputing..."), max_=len(params) + ) as progress: + for idx, param in enumerate(params): + progress.setValue(idx) + progress.setLabelText(_("Processing object with updated parameters...")) + args = (obj, param) if param is not None else (obj,) + comp_out = self.__exec_func(func, args, progress) + if comp_out is None: + return None + new_obj = self.handle_output(comp_out, _("Recomputing"), progress) + if new_obj is None: + continue + if isinstance(new_obj, (SignalObj, ImageObj)): + self._handle_keep_results(new_obj) + patch_title_with_ids(new_obj, [obj], get_short_id) + results.append(new_obj) + return results + + def recompute_n_to_1( + self, + func_name: str, + objs: list[SignalObj | ImageObj], + param: gds.DataSet | None = None, + plugin_origin: dict[str, Any] | None = None, + ) -> SignalObj | ImageObj | None: + """Recompute an n-to-1 processing operation without adding result to panel. + + Args: + func_name: Name of the processing function. + objs: Source object list to aggregate. + param: Processing parameters (optional). + plugin_origin: Optional plugin origin descriptor. + + Returns: + New aggregated object, or ``None`` if cancelled / errored. + + .. note:: + Pairwise mode is not handled here: each pairwise output is a + distinct single-output recompute -- the caller is expected to + split the work per output and iterate. + """ + paramclass_name = type(param).__name__ if param is not None else None + feature = self.get_feature( + func_name, + plugin_origin=plugin_origin, + paramclass_name=paramclass_name, + ) + func = feature.function + with create_progress_bar(self.panel, _("Recomputing..."), max_=1) as progress: + progress.setValue(0) + progress.setLabelText(_("Processing object with updated parameters...")) + args = (objs, param) if param is not None else (objs,) + comp_out = self.__exec_func(func, args, progress) + if comp_out is None: + return None + new_obj = self.handle_output(comp_out, _("Recomputing"), progress) + if new_obj is None: + return None + if isinstance(new_obj, (SignalObj, ImageObj)): + self._handle_keep_results(new_obj) + self._merge_geometry_results_for_n_to_1(new_obj, objs) + patch_title_with_ids(new_obj, objs, get_short_id) + return new_obj + + def recompute_2_to_1( + self, + func_name: str, + obj1: SignalObj | ImageObj, + obj2: SignalObj | ImageObj, + param: gds.DataSet | None = None, + plugin_origin: dict[str, Any] | None = None, + ) -> SignalObj | ImageObj | None: + """Recompute a 2-to-1 processing operation without adding result to panel. + + Args: + func_name: Name of the processing function. + obj1: First source object. + obj2: Second source object. + param: Processing parameters (optional). + plugin_origin: Optional plugin origin descriptor. + + Returns: + New combined object, or ``None`` if cancelled / errored. + """ + paramclass_name = type(param).__name__ if param is not None else None + feature = self.get_feature( + func_name, + plugin_origin=plugin_origin, + paramclass_name=paramclass_name, + ) + func = feature.function + with create_progress_bar(self.panel, _("Recomputing..."), max_=1) as progress: + progress.setValue(0) + progress.setLabelText(_("Processing object with updated parameters...")) + args = (obj1, obj2, param) if param is not None else (obj1, obj2) + comp_out = self.__exec_func(func, args, progress) + if comp_out is None: + return None + new_obj = self.handle_output(comp_out, _("Recomputing"), progress) + if new_obj is None: + return None + if isinstance(new_obj, (SignalObj, ImageObj)): + self._handle_keep_results(new_obj) + patch_title_with_ids(new_obj, [obj1, obj2], get_short_id) + return new_obj + + def recompute_1_to_0( + self, + func_name: str, + obj: SignalObj | ImageObj, + param: gds.DataSet | None = None, + plugin_origin: dict[str, Any] | None = None, + ) -> None: + """Recompute a 1-to-0 analysis on ``obj`` in place. + + Reuses :meth:`compute_1_to_0` with ``target_objs=[obj]`` under the + history-panel ``replaying`` guard so no synthetic history entry is + recorded. The analysis result is written to ``obj``'s metadata. + + Args: + func_name: Name of the analysis function. + obj: Object whose analysis must be refreshed. + param: Analysis parameters (optional). + plugin_origin: Optional plugin origin descriptor. + """ + paramclass_name = type(param).__name__ if param is not None else None + feature = self.get_feature( + func_name, + plugin_origin=plugin_origin, + paramclass_name=paramclass_name, + ) + historypanel = self.mainwindow.historypanel + with historypanel.replaying(), Conf.proc.show_result_dialog.temp(False): + self.compute_1_to_0( + feature.function, param, edit=False, target_objs=[obj] + ) + def _compute_1_to_1_subroutine( self, funcs: list[Callable], params: list, title: str ) -> None: @@ -1279,7 +1627,7 @@ def compute_1_to_1( comment: str | None = None, edit: bool | None = None, ) -> None: - """Generic processing method: 1 object in → 1 object out. + """Generic processing method: 1 object in → 1 object out. Applies a function independently to each selected object in the active panel. The result of each computation is a new object appended to the same panel. @@ -1310,10 +1658,14 @@ def compute_1_to_1( if edit and not param.edit(parent=self.mainwindow): return pp = build_processing_parameters(func.__name__, "1-to-1", param=param) - self.mainwindow.historypanel.add_compute_entry_from_pp( - title or func.__name__, pp, panel_str=self.panel.PANEL_STR_ID + action = self.mainwindow.historypanel.add_compute_entry_from_pp( + title or func.__name__, + pp, + panel_str=self.panel.PANEL_STR_ID, + plugin_origin=self._get_plugin_origin_for(func), ) - self._compute_1_to_1_subroutine([func], [param], title) + with self.mainwindow.historypanel.capture_outputs(action): + self._compute_1_to_1_subroutine([func], [param], title) def compute_multiple_1_to_1( self, @@ -1322,7 +1674,7 @@ def compute_multiple_1_to_1( title: str | None = None, edit: bool | None = None, ) -> None: - """Generic processing method: 1 object in → n objects out. + """Generic processing method: 1 object in → n objects out. Applies multiple functions to each selected object, generating multiple outputs per object. The resulting objects are appended to the active panel. @@ -1338,7 +1690,7 @@ def compute_multiple_1_to_1( .. note:: With k selected objects and n outputs per function, - the method produces k × n outputs. + the method produces k × n outputs. .. note:: This method does not support pairwise mode. @@ -1354,14 +1706,18 @@ def compute_multiple_1_to_1( pp = build_processing_parameters( funcs[0].__name__ if funcs else "", "multiple-1-to-1" ) - self.mainwindow.historypanel.add_compute_entry_from_pp( + action = self.mainwindow.historypanel.add_compute_entry_from_pp( title or "compute_multiple_1_to_1", pp, panel_str=self.panel.PANEL_STR_ID, func_names=[f.__name__ for f in funcs], params=params if any(p is not None for p in params) else None, + plugin_origin=( + self._get_plugin_origin_for(funcs[0]) if funcs else None + ), ) - self._compute_1_to_1_subroutine(funcs, params, title) + with self.mainwindow.historypanel.capture_outputs(action): + self._compute_1_to_1_subroutine(funcs, params, title) def compute_1_to_n( self, @@ -1370,7 +1726,7 @@ def compute_1_to_n( title: str | None = None, edit: bool | None = None, ) -> None: - """Generic processing method: 1 object in → n objects out. + """Generic processing method: 1 object in → n objects out. Applies a single function to each selected object, with n different parameters set, thus generating n outputs per object. The resulting objects are appended to @@ -1387,7 +1743,7 @@ def compute_1_to_n( .. note:: With k selected objects and n parameter sets, - the method produces k × n outputs. + the method produces k × n outputs. .. note:: This method does not support pairwise mode. @@ -1398,13 +1754,15 @@ def compute_1_to_n( if not group.edit(parent=self.mainwindow): return pp = build_processing_parameters(func.__name__, "1-to-n") - self.mainwindow.historypanel.add_compute_entry_from_pp( + action = self.mainwindow.historypanel.add_compute_entry_from_pp( title or func.__name__, pp, panel_str=self.panel.PANEL_STR_ID, params=params, + plugin_origin=self._get_plugin_origin_for(func), ) - self._compute_1_to_1_subroutine([func] * len(params), params, title) + with self.mainwindow.historypanel.capture_outputs(action): + self._compute_1_to_1_subroutine([func] * len(params), params, title) def compute_1_to_0( self, @@ -1416,7 +1774,7 @@ def compute_1_to_0( edit: bool | None = None, target_objs: list[SignalObj | ImageObj] | None = None, ) -> ResultData: - """Generic processing method: 1 object in → no object out. + """Generic processing method: 1 object in → no object out. Applies a function to each selected object (or specified target objects), returning metadata or measurement results (e.g. peak coordinates, statistical @@ -1459,9 +1817,16 @@ def compute_1_to_0( current_obj = self.panel.objview.get_current_object() title = func.__name__ if title is None else title pp_history = build_processing_parameters(func.__name__, "1-to-0", param=param) - self.mainwindow.historypanel.add_compute_entry_from_pp( - title, pp_history, panel_str=self.panel.PANEL_STR_ID + action = self.mainwindow.historypanel.add_compute_entry_from_pp( + title, + pp_history, + panel_str=self.panel.PANEL_STR_ID, + plugin_origin=self._get_plugin_origin_for(func), ) + # 1-to-0: no data object is produced. Register an empty output list so + # the bijective mapping records the action even with zero outputs. + if action is not None: + self.mainwindow.historypanel.register_action_outputs(action, []) refresh_needed = False with create_progress_bar(self.panel, title, max_=len(objs)) as progress: rdata = ResultData() @@ -1539,7 +1904,7 @@ def compute_n_to_1( edit: bool | None = None, pairwise: bool | None = None, ) -> None: - """Generic processing method: n objects in → 1 object out. + """Generic processing method: n objects in → 1 object out. Aggregates multiple selected objects into a single result using the provided function. In pairwise mode, applies the function to object pairs (grouped by @@ -1574,202 +1939,211 @@ def compute_n_to_1( name = func.__name__ pp_history = build_processing_parameters(name, "n-to-1", param=param) - self.mainwindow.historypanel.add_compute_entry_from_pp( + action = self.mainwindow.historypanel.add_compute_entry_from_pp( name, pp_history, panel_str=self.panel.PANEL_STR_ID, pairwise=pairwise, + plugin_origin=self._get_plugin_origin_for(func), ) - if pairwise: - src_grps, src_gids, src_objs, _nbobj, valid = ( - self.__get_src_grps_gids_objs_nbobj_valid(min_group_nb=2) - ) - if not valid: - return - dst_gname = ( - f"{name}({','.join([get_short_id(grp) for grp in src_grps])})|pairwise" - ) - group_exclusive = len(self.panel.objview.get_sel_groups()) != 0 - if not group_exclusive: - # This is not a group exclusive selection - dst_gname += "[...]" - # Delay group creation until after first result to determine target panel - dst_gid = None - n_pairs = len(src_objs[src_gids[0]]) - max_i_pair = min( - n_pairs, max(len(src_objs[get_uuid(grp)]) for grp in src_grps) - ) - # Track "Yes to All" choice for this compute operation - auto_interpolate_for_operation = False + with self.mainwindow.historypanel.capture_outputs(action): + if pairwise: + src_grps, src_gids, src_objs, _nbobj, valid = ( + self.__get_src_grps_gids_objs_nbobj_valid(min_group_nb=2) + ) + if not valid: + return + dst_gname = ( + f"{name}({','.join([get_short_id(grp) for grp in src_grps])})" + "|pairwise" + ) + group_exclusive = len(self.panel.objview.get_sel_groups()) != 0 + if not group_exclusive: + # This is not a group exclusive selection + dst_gname += "[...]" + # Delay group creation until after first result + # to determine target panel + dst_gid = None + n_pairs = len(src_objs[src_gids[0]]) + max_i_pair = min( + n_pairs, max(len(src_objs[get_uuid(grp)]) for grp in src_grps) + ) + # Track "Yes to All" choice for this compute operation + auto_interpolate_for_operation = False - with create_progress_bar(self.panel, title, max_=n_pairs) as progress: - for i_pair, src_obj1 in enumerate(src_objs[src_gids[0]][:max_i_pair]): - progress.setValue(i_pair + 1) - progress.setLabelText(title) - src_objs_pair = [src_obj1] - for src_gid in src_gids[1:]: - src_obj = src_objs[src_gid][i_pair] - src_objs_pair.append(src_obj) - - # Check signal x-array compatibility for n-to-1 operations - if auto_interpolate_for_operation: - # "Yes to All" selected, automatically interpolate - # by temporarily changing the configuration - with Conf.proc.xarray_compat_behavior.temp("interpolate"): + with create_progress_bar(self.panel, title, max_=n_pairs) as progress: + for i_pair, src_obj1 in enumerate( + src_objs[src_gids[0]][:max_i_pair] + ): + progress.setValue(i_pair + 1) + progress.setLabelText(title) + src_objs_pair = [src_obj1] + for src_gid in src_gids[1:]: + src_obj = src_objs[src_gid][i_pair] + src_objs_pair.append(src_obj) + + # Check signal x-array compatibility for n-to-1 operations + if auto_interpolate_for_operation: + # "Yes to All" selected, automatically interpolate + # by temporarily changing the configuration + with Conf.proc.xarray_compat_behavior.temp("interpolate"): + result = self._check_signal_xarray_compatibility( + src_objs_pair, progress=progress + ) + else: + # Normal compatibility check with dialog result = self._check_signal_xarray_compatibility( src_objs_pair, progress=progress ) - else: - # Normal compatibility check with dialog - result = self._check_signal_xarray_compatibility( - src_objs_pair, progress=progress - ) - if result is None: - # User canceled or compatibility check failed - return - - checked_objs, yes_to_all_selected = result - if yes_to_all_selected: - auto_interpolate_for_operation = True - - src_objs_pair = checked_objs - if param is None: - args = (src_objs_pair,) - else: - args = (src_objs_pair, param) - result = self.__exec_func(func, args, progress) - if result is None: - break - new_obj = self.handle_output( - result, _("Calculating: %s") % title, progress - ) - if new_obj is None: - break - assert isinstance(new_obj, (SignalObj, ImageObj)) + if result is None: + # User canceled or compatibility check failed + return + + checked_objs, yes_to_all_selected = result + if yes_to_all_selected: + auto_interpolate_for_operation = True + + src_objs_pair = checked_objs + if param is None: + args = (src_objs_pair,) + else: + args = (src_objs_pair, param) + result = self.__exec_func(func, args, progress) + if result is None: + break + new_obj = self.handle_output( + result, _("Calculating: %s") % title, progress + ) + if new_obj is None: + break + assert isinstance(new_obj, (SignalObj, ImageObj)) - patch_title_with_ids(new_obj, src_objs_pair, get_short_id) + patch_title_with_ids(new_obj, src_objs_pair, get_short_id) - # Handle keep_results and geometry result merging - self._handle_keep_results(new_obj) - self._merge_geometry_results_for_n_to_1(new_obj, src_objs_pair) + # Handle keep_results and geometry result merging + self._handle_keep_results(new_obj) + self._merge_geometry_results_for_n_to_1(new_obj, src_objs_pair) - # Store lightweight processing metadata (non-interactive) - proc_params = ProcessingParameters( - func_name=name, - pattern="n-to-1", - param=param, - source_uuids=[get_uuid(obj) for obj in src_objs_pair], - ) - insert_processing_parameters(new_obj, proc_params) + # Store lightweight processing metadata (non-interactive) + proc_params = ProcessingParameters( + func_name=name, + pattern="n-to-1", + param=param, + source_uuids=[get_uuid(obj) for obj in src_objs_pair], + ) + insert_processing_parameters(new_obj, proc_params) - # Create destination group on first result, in appropriate panel - if dst_gid is None: - dst_gid = self._create_group_for_result(new_obj, dst_gname) + # Create destination group on first result, in appropriate panel + if dst_gid is None: + dst_gid = self._create_group_for_result(new_obj, dst_gname) - self._add_object_to_appropriate_panel(new_obj, group_id=dst_gid) + self._add_object_to_appropriate_panel(new_obj, group_id=dst_gid) - else: - # In single operand mode, we create a single object for all selected objects + else: + # In single operand mode, we create a single object + # for all selected objects + + # [src_objs dictionary] keys: old group id, values: list of old objects + src_objs: dict[str, list[SignalObj | ImageObj]] = {} + + grps = self.panel.objview.get_sel_groups() + dst_group_name = None + if grps: + # (Group exclusive selection) + # At least one group is selected: create a new group + dst_gname = f"{name}({','.join([get_uuid(grp) for grp in grps])})" + # Delay group creation until after first result + dst_gid = None + dst_group_name = dst_gname # Store name for later use + else: + # (Object exclusive selection) + # No group is selected: use each object's group + dst_gid = None - # [src_objs dictionary] keys: old group id, values: list of old objects - src_objs: dict[str, list[SignalObj | ImageObj]] = {} + for src_obj in objs: + src_gid = objmodel.get_object_group_id(src_obj) + src_objs.setdefault(src_gid, []).append(src_obj) - grps = self.panel.objview.get_sel_groups() - dst_group_name = None - if grps: - # (Group exclusive selection) - # At least one group is selected: create a new group - dst_gname = f"{name}({','.join([get_uuid(grp) for grp in grps])})" - # Delay group creation until after first result - dst_gid = None - dst_group_name = dst_gname # Store name for later use - else: - # (Object exclusive selection) - # No group is selected: use each object's group - dst_gid = None + # Track "Yes to All" choice for this compute operation + auto_interpolate_for_operation = False - for src_obj in objs: - src_gid = objmodel.get_object_group_id(src_obj) - src_objs.setdefault(src_gid, []).append(src_obj) - - # Track "Yes to All" choice for this compute operation - auto_interpolate_for_operation = False - - with create_progress_bar(self.panel, title, max_=len(objs)) as progress: - progress.setValue(0) - progress.setLabelText(title) - for src_gid, src_obj_list in src_objs.items(): - # Check signal x-array compatibility for n-to-1 operations - if auto_interpolate_for_operation: - # "Yes to All" selected, automatically interpolate - with Conf.proc.xarray_compat_behavior.temp("interpolate"): + with create_progress_bar(self.panel, title, max_=len(objs)) as progress: + progress.setValue(0) + progress.setLabelText(title) + for src_gid, src_obj_list in src_objs.items(): + # Check signal x-array compatibility for n-to-1 operations + if auto_interpolate_for_operation: + # "Yes to All" selected, automatically interpolate + with Conf.proc.xarray_compat_behavior.temp("interpolate"): + result = self._check_signal_xarray_compatibility( + src_obj_list, progress=progress + ) + else: + # Normal compatibility check with dialog result = self._check_signal_xarray_compatibility( src_obj_list, progress=progress ) - else: - # Normal compatibility check with dialog - result = self._check_signal_xarray_compatibility( - src_obj_list, progress=progress - ) - if result is None: - # User canceled or compatibility check failed - return + if result is None: + # User canceled or compatibility check failed + return - checked_objs, yes_to_all_selected = result - if yes_to_all_selected: - auto_interpolate_for_operation = True + checked_objs, yes_to_all_selected = result + if yes_to_all_selected: + auto_interpolate_for_operation = True - src_obj_list = checked_objs + src_obj_list = checked_objs - if param is None: - args = (src_obj_list,) - else: - args = (src_obj_list, param) - result = self.__exec_func(func, args, progress) - if result is None: - break - new_obj = self.handle_output( - result, _("Calculating: %s") % title, progress - ) - if new_obj is None: - break - assert isinstance(new_obj, (SignalObj, ImageObj)) + if param is None: + args = (src_obj_list,) + else: + args = (src_obj_list, param) + result = self.__exec_func(func, args, progress) + if result is None: + break + new_obj = self.handle_output( + result, _("Calculating: %s") % title, progress + ) + if new_obj is None: + break + assert isinstance(new_obj, (SignalObj, ImageObj)) - group_id = dst_gid if dst_gid is not None else src_gid - patch_title_with_ids(new_obj, src_obj_list, get_short_id) + group_id = dst_gid if dst_gid is not None else src_gid + patch_title_with_ids(new_obj, src_obj_list, get_short_id) - # Handle keep_results and geometry result merging - self._handle_keep_results(new_obj) - self._merge_geometry_results_for_n_to_1(new_obj, src_obj_list) + # Handle keep_results and geometry result merging + self._handle_keep_results(new_obj) + self._merge_geometry_results_for_n_to_1(new_obj, src_obj_list) - # Store lightweight processing metadata (non-interactive) - proc_params = ProcessingParameters( - func_name=name, - pattern="n-to-1", - param=param, - source_uuids=[get_uuid(obj) for obj in src_obj_list], - ) - insert_processing_parameters(new_obj, proc_params) + # Store lightweight processing metadata (non-interactive) + proc_params = ProcessingParameters( + func_name=name, + pattern="n-to-1", + param=param, + source_uuids=[get_uuid(obj) for obj in src_obj_list], + ) + insert_processing_parameters(new_obj, proc_params) - # Create destination group on first result, in appropriate panel - use_group_for_non_native = False - if dst_gid is None and dst_group_name is not None: - dst_gid = self._create_group_for_result(new_obj, dst_group_name) - group_id = dst_gid - use_group_for_non_native = True + # Create destination group on first result, in appropriate panel + use_group_for_non_native = False + if dst_gid is None and dst_group_name is not None: + dst_gid = self._create_group_for_result( + new_obj, dst_group_name + ) + group_id = dst_gid + use_group_for_non_native = True - self._add_object_to_appropriate_panel( - new_obj, - group_id=group_id, - use_group_for_non_native=use_group_for_non_native, - ) + self._add_object_to_appropriate_panel( + new_obj, + group_id=group_id, + use_group_for_non_native=use_group_for_non_native, + ) - # Select newly created group, if any - if dst_gid is not None: - self.panel.objview.set_current_item_id(dst_gid) + # Select newly created group, if any + if dst_gid is not None: + self.panel.objview.set_current_item_id(dst_gid) def compute_2_to_1( self, @@ -1789,7 +2163,7 @@ def compute_2_to_1( skip_xarray_compat: bool | None = None, pairwise: bool | None = None, ) -> None: - """Generic processing method: binary operation 1+1 → 1. + """Generic processing method: binary operation 1+1 → 1. Applies a binary function between each selected object and a second operand. Supports both single operand mode (same operand for all objects) @@ -1866,126 +2240,135 @@ def compute_2_to_1( pp_history = build_processing_parameters( func.__name__, "2-to-1", param=param ) - self.mainwindow.historypanel.add_compute_entry_from_pp( + action = self.mainwindow.historypanel.add_compute_entry_from_pp( title or func.__name__, pp_history, panel_str=self.panel.PANEL_STR_ID, obj2_uuids=[get_uuid(obj) for obj in objs2], obj2_name=obj2_name, pairwise=True, + plugin_origin=self._get_plugin_origin_for(func), ) - n_pairs = len(src_objs[src_gids[0]]) - max_i_pair = min( - n_pairs, max(len(src_objs[get_uuid(grp)]) for grp in src_grps) - ) - grp2_id = objmodel.get_object_group_id(objs2[0]) - grp2 = objmodel.get_group(grp2_id) - - # Initialize pair mapping for potential interpolations - pair_maps = {} - - # Check x-array compatibility for signal processing (pairwise mode) - if self._is_signal_panel() and not skip_xarray_compat: - # Check compatibility between objects from both groups - all_pairs = [] - for src_gid in src_gids: - for i_pair in range(max_i_pair): - src_obj1 = src_objs[src_gid][i_pair] - src_obj2 = objs2[i_pair] - if isinstance(src_obj1, SignalObj) and isinstance( - src_obj2, SignalObj - ): - all_pairs.append((src_obj1, src_obj2)) - - # Track "Yes to All" choice for this compute operation - auto_interpolate_for_operation = False - - # Check all pairs for compatibility and create interpolation maps - for src_obj1, src_obj2 in all_pairs: - if auto_interpolate_for_operation: - # "Yes to All" selected, automatically interpolate - with Conf.proc.xarray_compat_behavior.temp("interpolate"): + with self.mainwindow.historypanel.capture_outputs(action): + n_pairs = len(src_objs[src_gids[0]]) + max_i_pair = min( + n_pairs, max(len(src_objs[get_uuid(grp)]) for grp in src_grps) + ) + grp2_id = objmodel.get_object_group_id(objs2[0]) + grp2 = objmodel.get_group(grp2_id) + + # Initialize pair mapping for potential interpolations + pair_maps = {} + + # Check x-array compatibility for signal processing (pairwise mode) + if self._is_signal_panel() and not skip_xarray_compat: + # Check compatibility between objects from both groups + all_pairs = [] + for src_gid in src_gids: + for i_pair in range(max_i_pair): + src_obj1 = src_objs[src_gid][i_pair] + src_obj2 = objs2[i_pair] + if isinstance(src_obj1, SignalObj) and isinstance( + src_obj2, SignalObj + ): + all_pairs.append((src_obj1, src_obj2)) + + # Track "Yes to All" choice for this compute operation + auto_interpolate_for_operation = False + + # Check all pairs for compatibility and create interpolation maps + for src_obj1, src_obj2 in all_pairs: + if auto_interpolate_for_operation: + # "Yes to All" selected, automatically interpolate + with Conf.proc.xarray_compat_behavior.temp("interpolate"): + result = self._check_signal_xarray_compatibility( + [src_obj1, src_obj2] + ) + else: + # Normal compatibility check with dialog result = self._check_signal_xarray_compatibility( [src_obj1, src_obj2] ) - else: - # Normal compatibility check with dialog - result = self._check_signal_xarray_compatibility( - [src_obj1, src_obj2] - ) - - if result is None: - return # User cancelled or error occurred - checked_pair, yes_to_all_selected = result - if yes_to_all_selected: - auto_interpolate_for_operation = True - - # Store mapping for this specific pair - pair_maps[(src_obj1, src_obj2)] = checked_pair - - with create_progress_bar(self.panel, title, max_=len(src_gids)) as progress: - for i_group, src_gid in enumerate(src_gids): - progress.setValue(i_group + 1) - progress.setLabelText(title) - if group_exclusive: - # This is a group exclusive selection - src_grp = objmodel.get_group(src_gid) - grp_short_ids = [get_uuid(grp) for grp in (src_grp, grp2)] - dst_gname = f"{name}({','.join(grp_short_ids)})|pairwise" - else: - dst_gname = f"{name}[...]" - # Delay group creation until after first result - dst_gid = None - for i_pair in range(max_i_pair): - orig_obj1, orig_obj2 = src_objs[src_gid][i_pair], objs2[i_pair] - - # Use interpolated signals if available, keep original refs - actual_obj1, actual_obj2 = orig_obj1, orig_obj2 - if (orig_obj1, orig_obj2) in pair_maps: - interpolated_pair = pair_maps[(orig_obj1, orig_obj2)] - actual_obj1 = interpolated_pair[0] - actual_obj2 = interpolated_pair[1] - - args = [actual_obj1, actual_obj2] - if param is not None: - args.append(param) - result = self.__exec_func(func, tuple(args), progress) if result is None: - break - new_obj = self.handle_output( - result, _("Calculating: %s") % title, progress - ) - if new_obj is None: - continue - assert isinstance(new_obj, (SignalObj, ImageObj)) - - # Use original objects for title generation - patch_title_with_ids( - new_obj, [orig_obj1, orig_obj2], get_short_id - ) + return # User cancelled or error occurred + + checked_pair, yes_to_all_selected = result + if yes_to_all_selected: + auto_interpolate_for_operation = True + + # Store mapping for this specific pair + pair_maps[(src_obj1, src_obj2)] = checked_pair + + with create_progress_bar( + self.panel, title, max_=len(src_gids) + ) as progress: + for i_group, src_gid in enumerate(src_gids): + progress.setValue(i_group + 1) + progress.setLabelText(title) + if group_exclusive: + # This is a group exclusive selection + src_grp = objmodel.get_group(src_gid) + grp_short_ids = [get_uuid(grp) for grp in (src_grp, grp2)] + dst_gname = f"{name}({','.join(grp_short_ids)})|pairwise" + else: + dst_gname = f"{name}[...]" + # Delay group creation until after first result + dst_gid = None + for i_pair in range(max_i_pair): + orig_obj1 = src_objs[src_gid][i_pair] + orig_obj2 = objs2[i_pair] + + # Use interpolated signals if available, keep original refs + actual_obj1, actual_obj2 = orig_obj1, orig_obj2 + if (orig_obj1, orig_obj2) in pair_maps: + interpolated_pair = pair_maps[(orig_obj1, orig_obj2)] + actual_obj1 = interpolated_pair[0] + actual_obj2 = interpolated_pair[1] + + args = [actual_obj1, actual_obj2] + if param is not None: + args.append(param) + result = self.__exec_func(func, tuple(args), progress) + if result is None: + break + new_obj = self.handle_output( + result, _("Calculating: %s") % title, progress + ) + if new_obj is None: + continue + assert isinstance(new_obj, (SignalObj, ImageObj)) - # Handle keep_results logic for 2_to_1 operations - self._handle_keep_results(new_obj) + # Use original objects for title generation + patch_title_with_ids( + new_obj, [orig_obj1, orig_obj2], get_short_id + ) - # Store lightweight processing metadata (non-interactive) - proc_params = ProcessingParameters( - func_name=name, - pattern="2-to-1", - param=param, - source_uuids=[ - get_uuid(orig_obj1), - get_uuid(orig_obj2), - ], - ) - insert_processing_parameters(new_obj, proc_params) + # Handle keep_results logic for 2_to_1 operations + self._handle_keep_results(new_obj) + + # Store lightweight processing metadata (non-interactive) + proc_params = ProcessingParameters( + func_name=name, + pattern="2-to-1", + param=param, + source_uuids=[ + get_uuid(orig_obj1), + get_uuid(orig_obj2), + ], + ) + insert_processing_parameters(new_obj, proc_params) - # Create destination group on first result, in appropriate panel - if dst_gid is None: - dst_gid = self._create_group_for_result(new_obj, dst_gname) + # Create dest group on first result + if dst_gid is None: + dst_gid = self._create_group_for_result( + new_obj, dst_gname + ) - self._add_object_to_appropriate_panel(new_obj, group_id=dst_gid) + self._add_object_to_appropriate_panel( + new_obj, group_id=dst_gid + ) else: if not objs2: @@ -2003,97 +2386,103 @@ def compute_2_to_1( pp_history = build_processing_parameters( func.__name__, "2-to-1", param=param ) - self.mainwindow.historypanel.add_compute_entry_from_pp( + action = self.mainwindow.historypanel.add_compute_entry_from_pp( title or func.__name__, pp_history, panel_str=self.panel.PANEL_STR_ID, obj2_uuids=[get_uuid(obj2)], obj2_name=obj2_name, pairwise=False, + plugin_origin=self._get_plugin_origin_for(func), ) - # Initialize signal mapping for potential interpolations - signal_map = {} - - # Check x-array compatibility for signal processing (single operand mode) - orig_obj2 = obj2 # Keep reference to original obj2 for title generation - if ( - self._is_signal_panel() - and isinstance(obj2, SignalObj) - and not skip_xarray_compat - ): - signal_objs = [obj for obj in objs if isinstance(obj, SignalObj)] - if signal_objs: - # Check compatibility and get potentially interpolated signals - result = self._check_signal_xarray_compatibility( - signal_objs + [obj2] - ) - if result is None: - return # User cancelled or error occurred - - checked_objs, _yes_to_all_selected = result - # Note: In single operand mode, "Yes to All" doesn't apply - # since there's only one compatibility check - - # Replace obj2 with the potentially interpolated version - obj2 = checked_objs[-1] # obj2 was added last + with self.mainwindow.historypanel.capture_outputs(action): + # Initialize signal mapping for potential interpolations + signal_map = {} + + # Check x-array compatibility for signal processing + # (single operand mode) + orig_obj2 = obj2 # Keep reference to original obj2 for title generation + if ( + self._is_signal_panel() + and isinstance(obj2, SignalObj) + and not skip_xarray_compat + ): + signal_objs = [obj for obj in objs if isinstance(obj, SignalObj)] + if signal_objs: + # Check compatibility and get potentially interpolated signals + result = self._check_signal_xarray_compatibility( + signal_objs + [obj2] + ) + if result is None: + return # User cancelled or error occurred - # Create a mapping of original to interpolated signals - for orig_obj, checked_obj in zip(signal_objs, checked_objs[:-1]): - signal_map[orig_obj] = checked_obj + checked_objs, _yes_to_all_selected = result + # Note: In single operand mode, "Yes to All" doesn't apply + # since there's only one compatibility check - with create_progress_bar(self.panel, title, max_=len(objs)) as progress: - for index, obj in enumerate(objs): - progress.setValue(index + 1) - progress.setLabelText(title) + # Replace obj2 with the potentially interpolated version + obj2 = checked_objs[-1] # obj2 was added last - # Use interpolated signal if available - actual_obj = obj - if ( - self._is_signal_panel() - and isinstance(obj, SignalObj) - and obj in signal_map - ): - actual_obj = signal_map[obj] + # Create a mapping of original to interpolated signals + for orig_obj, checked_obj in zip( + signal_objs, checked_objs[:-1] + ): + signal_map[orig_obj] = checked_obj + + with create_progress_bar(self.panel, title, max_=len(objs)) as progress: + for index, obj in enumerate(objs): + progress.setValue(index + 1) + progress.setLabelText(title) + + # Use interpolated signal if available + actual_obj = obj + if ( + self._is_signal_panel() + and isinstance(obj, SignalObj) + and obj in signal_map + ): + actual_obj = signal_map[obj] - args = ( - (actual_obj, obj2) - if param is None - else (actual_obj, obj2, param) - ) - result = self.__exec_func(func, args, progress) - if result is None: - break - new_obj = self.handle_output( - result, _("Calculating: %s") % title, progress - ) - if new_obj is None: - continue - assert isinstance(new_obj, (SignalObj, ImageObj)) + args = ( + (actual_obj, obj2) + if param is None + else (actual_obj, obj2, param) + ) + result = self.__exec_func(func, args, progress) + if result is None: + break + new_obj = self.handle_output( + result, _("Calculating: %s") % title, progress + ) + if new_obj is None: + continue + assert isinstance(new_obj, (SignalObj, ImageObj)) - group_id = objmodel.get_object_group_id(obj) - # Use original objects for title generation - patch_title_with_ids(new_obj, [obj, orig_obj2], get_short_id) + group_id = objmodel.get_object_group_id(obj) + # Use original objects for title generation + patch_title_with_ids(new_obj, [obj, orig_obj2], get_short_id) - # Handle keep_results logic for 2_to_1 operations - self._handle_keep_results(new_obj) + # Handle keep_results logic for 2_to_1 operations + self._handle_keep_results(new_obj) - # Store lightweight processing metadata (non-interactive) - proc_params = ProcessingParameters( - func_name=name, - pattern="2-to-1", - param=param, - source_uuids=[ - get_uuid(obj), - get_uuid(orig_obj2), - ], - ) - insert_processing_parameters(new_obj, proc_params) + # Store lightweight processing metadata (non-interactive) + proc_params = ProcessingParameters( + func_name=name, + pattern="2-to-1", + param=param, + source_uuids=[ + get_uuid(obj), + get_uuid(orig_obj2), + ], + ) + insert_processing_parameters(new_obj, proc_params) - # group_id is from source panel, don't use for non-native objects - self._add_object_to_appropriate_panel( - new_obj, group_id=group_id, use_group_for_non_native=False - ) + # group_id is from source panel, don't use + # for non-native objects + self._add_object_to_appropriate_panel( + new_obj, group_id=group_id, use_group_for_non_native=False + ) def register_1_to_1( self, @@ -2285,27 +2674,66 @@ def register_2_to_1( def add_feature(self, feature: ComputingFeature) -> None: """Add a computing feature to the registry. + Auto-detects the plugin origin from ``feature.function.__module__`` and + stores it on the feature (see :func:`_detect_plugin_origin`). + Args: feature: ComputingFeature instance to add. """ + if feature.function is not None and feature.plugin_origin is None: + feature.plugin_origin = _detect_plugin_origin(feature.function) self.computing_registry[feature.function] = feature - def get_feature(self, function_or_name: Callable | str) -> ComputingFeature: + def _get_plugin_origin_for(self, func: Callable) -> dict[str, Any] | None: + """Return the plugin origin descriptor for ``func`` if known. + + Falls back to a fresh detection if ``func`` is not in the registry. + + Args: + func: Computation function. + + Returns: + Plugin origin dict, or ``None`` for built-in functions. + """ + feature = self.computing_registry.get(func) + if feature is not None: + return feature.plugin_origin + return _detect_plugin_origin(func) + + def get_feature( + self, + function_or_name: Callable | str, + plugin_origin: dict[str, Any] | None = None, + paramclass_name: str | None = None, + ) -> ComputingFeature: """Get a computing feature by name or function. Args: function_or_name: Name of the feature or the function itself. + plugin_origin: Optional plugin origin descriptor used to enrich the + :class:`FeatureNotFoundError` raised when the feature is unknown. + paramclass_name: Optional name of the required parameter class, also + used to enrich the error message. Returns: Computing feature instance. + + Raises: + FeatureNotFoundError: If no matching feature is registered. The + exception subclasses :class:`ValueError` to preserve backward + compatibility with existing callers. """ try: return self.computing_registry[function_or_name] - except KeyError as exc: + except KeyError: for _func, feature in self.computing_registry.items(): if feature.name == function_or_name: return feature - raise ValueError(f"Unknown computing feature: {function_or_name}") from exc + raise FeatureNotFoundError( + str(function_or_name), + plugin_origin=plugin_origin, + paramclass_name=paramclass_name, + ) @qt_try_except() def run_feature( @@ -2372,6 +2800,9 @@ def run_feature( assert isinstance(param, (gds.DataSet, type(None))), ( f"For pattern '{pattern}', 'param' must be a DataSet or None" ) + compute_kwargs = {} + if pattern == "n_to_1": + compute_kwargs["pairwise"] = kwargs.pop("pairwise", None) return compute_method( feature.function, param=param, @@ -2379,6 +2810,7 @@ def run_feature( title=title, comment=comment, edit=edit, + **compute_kwargs, ) if pattern == "2_to_1": obj2 = kwargs.pop("obj2", args[0] if args else None) @@ -2390,6 +2822,7 @@ def run_feature( assert isinstance(param, (gds.DataSet, type(None))), ( "For pattern '2_to_1', 'param' must be a DataSet or None" ) + pairwise = kwargs.pop("pairwise", None) return self.compute_2_to_1( obj2, feature.obj2_name or _("Second operand"), @@ -2400,6 +2833,7 @@ def run_feature( comment=comment, edit=edit, skip_xarray_compat=feature.skip_xarray_compat, + pairwise=pairwise, ) if pattern == "1_to_n": params = kwargs.get("params", args[0] if args else []) diff --git a/datalab/h5/native.py b/datalab/h5/native.py index 78aaff0b8..5004c5774 100644 --- a/datalab/h5/native.py +++ b/datalab/h5/native.py @@ -139,7 +139,7 @@ def read( Returns: The read value. """ - val = super().read(group_name) + val = super().read(group_name, func=func, instance=instance, default=default) if isinstance(val, str) and val.startswith(H5_CALLABLE_PREFIX): return self.deserialize_func_or_class(val) return val From 2aef1dcf44b33dea93efe7f6d6e7ccfd103991c8 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Wed, 3 Jun 2026 13:06:23 +0200 Subject: [PATCH 020/108] Update doc and translation --- datalab/locale/fr/LC_MESSAGES/datalab.po | 215 ++++++++++- doc/features/common/historypanel.rst | 139 ++++++- .../features/common/historypanel.po | 357 +++++++++++++++--- .../LC_MESSAGES/release_notes/release_1.03.po | 67 +++- doc/release_notes/release_1.03.md | 6 + 5 files changed, 705 insertions(+), 79 deletions(-) diff --git a/datalab/locale/fr/LC_MESSAGES/datalab.po b/datalab/locale/fr/LC_MESSAGES/datalab.po index 7e49681a5..4b4b85108 100644 --- a/datalab/locale/fr/LC_MESSAGES/datalab.po +++ b/datalab/locale/fr/LC_MESSAGES/datalab.po @@ -65,6 +65,9 @@ msgstr "Assistant IA prêt. Configurez votre fournisseur dans le menu Edition > msgid "You" msgstr "Vous" +msgid "Assistant" +msgstr "Assistant" + msgid "Save to Macros" msgstr "Enregistrer dans les macros" @@ -1341,6 +1344,9 @@ msgstr "Propriétés" msgid "Parameters for function `%s`" msgstr "Paramètres pour la fonction `%s`" +msgid "Created" +msgstr "Créé" + msgid "Original object" msgstr "Objet original" @@ -1376,6 +1382,12 @@ msgstr "" msgid "Processing Parameters" msgstr "Paramètres de traitement" +msgid "Auto-recompute on edit" +msgstr "Recalcul automatique lors de l'édition" + +msgid "Automatically re-run processing when parameters are modified" +msgstr "Relancer automatiquement le traitement à chaque modification de paramètre" + msgid "No processing object available." msgstr "Aucun objet de traitement disponible." @@ -1420,6 +1432,9 @@ msgstr "Autres métadonnées" msgid "Save to directory" msgstr "Enregistrer dans un répertoire" +msgid "Pattern help" +msgstr "Aide sur le motif" + msgid "Directory" msgstr "Répertoire" @@ -1672,32 +1687,203 @@ msgstr "Description" msgid "Title" msgstr "Titre" +msgid "Action is compatible with the current workspace state." +msgstr "L'action est compatible avec l'état actuel de l'espace de travail." + +msgid "Action is not compatible with the current workspace state." +msgstr "L'action n'est pas compatible avec l'état actuel de l'espace de travail." + +msgid "Signal" +msgstr "Signal" + +msgid "Shape" +msgstr "Forme" + +msgid "Image" +msgstr "Image" + +msgid "Dimensions" +msgstr "Dimensions" + msgid "History panel" msgstr "Panneau d'historique" +msgid "History files" +msgstr "Fichiers d'historique" + msgid "Edit mode" msgstr "Mode d'édition" msgid "Record mode" msgstr "Mode d'enregistrement" +msgid "New session" +msgstr "Nouvelle session" + +msgid "Start a new history session" +msgstr "Démarrer une nouvelle session d'historique" + +msgid "Open history file..." +msgstr "Ouvrir un fichier d'historique..." + +msgid "Open history from a standalone .dlhist file" +msgstr "Ouvrir l'historique depuis un fichier .dlhist autonome" + +msgid "Save history file..." +msgstr "Enregistrer un fichier d'historique..." + +msgid "Save history to a standalone .dlhist file" +msgstr "Enregistrer l'historique dans un fichier .dlhist autonome" + +msgid "Duplicate selected history action/session" +msgstr "Dupliquer l'action ou la session d'historique sélectionnée" + +msgid "Previous step" +msgstr "Étape précédente" + +msgid "Select the previous action in the current session" +msgstr "Sélectionner l'action précédente dans la session courante" + +msgid "Next step" +msgstr "Étape suivante" + +msgid "Select the next action in the current session" +msgstr "Sélectionner l'action suivante dans la session courante" + +msgid "Generate macro" +msgstr "Générer une macro" + +msgid "Generate a Python macro script from history" +msgstr "Générer un script macro Python à partir de l'historique" + +msgid "Remove incompatible" +msgstr "Supprimer les incompatibles" + +msgid "Remove actions incompatible with the current workspace" +msgstr "Supprimer les actions incompatibles avec l'espace de travail courant" + +msgid "Restore parameters" +msgstr "Restaurer les paramètres" + +msgid "Restore original parameters (discard edit-mode changes)" +msgstr "Restaurer les paramètres d'origine (annuler les modifications du mode d'édition)" + msgid "Replay" msgstr "Rejouer" -msgid "Restore selection" -msgstr "Restaurer la sélection" +msgid "Commit edit mode changes?" +msgstr "Valider les modifications du mode d'édition ?" -msgid "Restore selection and replay" -msgstr "Restaurer la sélection et rejouer" +msgid "" +"You are about to exit Edit mode.\n" +"\n" +"All parameter changes made during this session will be permanently kept.\n" +"This action cannot be undone — Restore will no longer be available.\n" +"\n" +"Do you want to continue?" +msgstr "" +"Vous êtes sur le point de quitter le mode d'édition.\n" +"\n" +"Toutes les modifications de paramètres effectuées lors de cette session seront conservées de façon permanente.\n" +"Cette action est irréversible — la fonction Restaurer ne sera plus disponible.\n" +"\n" +"Souhaitez-vous continuer ?" msgid "The current workspace state is not compatible with the action." msgstr "L'état actuel de l'espace de travail n'est pas compatible avec l'action." -msgid "Delete actions" -msgstr "Supprimer les actions" +msgid "Parameters" +msgstr "Paramètres" + +#, python-format +msgid "Action %s has been edited but its target output object(s) no longer exist — skipping." +msgstr "L'action %s a été modifiée mais son ou ses objets de sortie cibles n'existent plus — ignorée." -msgid "Do you really want to delete the selected action and all the next ones?" -msgstr "Voulez-vous vraiment supprimer l'action sélectionnée et toutes les suivantes ?" +#, python-format +msgid "Action %s uses pattern %r which is not recomputable yet." +msgstr "L'action %s utilise le motif %r qui n'est pas encore recalculable." + +#, python-format +msgid "Recompute failed for action %s: %s" +msgstr "Échec du recalcul pour l'action %s : %s" + +#, python-format +msgid "" +"Action %(name)s skipped: plugin '%(loc)s' is missing.\n" +"Required parameter class: %(param)s\n" +"Reinstall the plugin to re-enable this action." +msgstr "" +"Action %(name)s ignorée : le plugin '%(loc)s' est manquant.\n" +"Classe de paramètre requise : %(param)s\n" +"Réinstallez le plugin pour réactiver cette action." + +#, python-format +msgid "Action %s: source object was deleted — skipping." +msgstr "Action %s : l'objet source a été supprimé — ignorée." + +#, python-format +msgid "Action %s: all source objects were deleted — skipping." +msgstr "Action %s : tous les objets source ont été supprimés — ignorée." + +#, python-format +msgid "Action %s: missing source(s) for output #%d — skipping." +msgstr "Action %s : source(s) manquante(s) pour la sortie n°%d — ignorée." + +#, python-format +msgid "Action %s: source object(s) were deleted — skipping." +msgstr "Action %s : le ou les objets source ont été supprimés — ignorée." + +#, python-format +msgid "Action %s: %d analysed object(s) were deleted — skipping." +msgstr "Action %s : %d objet(s) analysé(s) ont été supprimés — ignorée." + +msgid "Cascade recompute" +msgstr "Recalcul en cascade" + +msgid "Some downstream actions could not be recomputed:" +msgstr "Certaines actions en aval n'ont pas pu être recalculées :" + +msgid "No compute actions to export." +msgstr "Aucune action de calcul à exporter." + +#, python-format +msgid "Macro script copied to clipboard (%d actions)." +msgstr "Script macro copié dans le presse-papiers (%d actions)." + +msgid "" +"Do you really want to delete the selected items?\n" +"\n" +"Note: deleting an action also removes all subsequent actions in the same session." +msgstr "" +"Voulez-vous vraiment supprimer les éléments sélectionnés ?\n" +"\n" +"Note : la suppression d'une action supprime également toutes les actions suivantes de la même session." + +msgid "Do you really want to delete the selected items?" +msgstr "Voulez-vous vraiment supprimer les éléments sélectionnés ?" + +msgid "All actions are compatible with the current workspace." +msgstr "Toutes les actions sont compatibles avec l'espace de travail courant." + +#, python-format +msgid "%d incompatible action(s) will be removed. Continue?" +msgstr "%d action(s) incompatible(s) vont être supprimée(s). Continuer ?" + +msgid "Save history file" +msgstr "Enregistrer un fichier d'historique" + +msgid "Open history file" +msgstr "Ouvrir un fichier d'historique" + +msgid "Imported" +msgstr "Importé" + +msgid "Some operations could not be reconnected after deletion:" +msgstr "Certaines opérations n'ont pas pu être reconnectées après la suppression :" + +#, python-format +msgid "“%s” has dependent operations but no valid source to reconnect to — downstream results are left unchanged." +msgstr "« %s » possède des opérations dépendantes mais aucune source valide à laquelle se reconnecter — les résultats en aval restent inchangés." msgid "New image" msgstr "Nouvelle image" @@ -1717,6 +1903,9 @@ msgstr "Effacer toutes les macros récentes ?" msgid "Macro panel" msgstr "Panneau des macros" +msgid "Python files" +msgstr "Fichiers Python" + msgid "Clear console" msgstr "Effacer la console" @@ -1831,6 +2020,9 @@ msgstr "Les modifications seront appliquées après avoir cliqué sur OK et rech msgid "The following directories are scanned at startup for plugins:" msgstr "Les répertoires suivants sont analysés au démarrage pour détecter les plugins :" +msgid "from" +msgstr "depuis" + msgid "No plugin search path is currently active." msgstr "Aucun chemin de recherche de plugins n'est actuellement actif." @@ -1906,9 +2098,6 @@ msgstr "En mode 'pairwise', vous devez sélectionner des objets dans au moins de msgid "In pairwise mode, you need to select the same number of objects in each group." msgstr "En mode 'pairwise', vous devez sélectionner le même nombre d'objets dans chaque groupe." -msgid "Parameters" -msgstr "Paramètres" - #, python-format msgid "Calculating: %s" msgstr "Calcul : %s" @@ -3647,6 +3836,9 @@ msgstr "Distance minimale :" msgid "Signal peak detection" msgstr "Détection de pics 1D" +msgid "Peaks:" +msgstr "Pics :" + msgid "Internal console" msgstr "Console interne" @@ -3996,3 +4188,4 @@ msgstr "Aucun contour n'a été trouvé pour la plage de niveaux sélectionnée. msgid "Show contour plot..." msgstr "Afficher le tracé de contours..." + diff --git a/doc/features/common/historypanel.rst b/doc/features/common/historypanel.rst index 0400d7136..7f1ecf594 100644 --- a/doc/features/common/historypanel.rst +++ b/doc/features/common/historypanel.rst @@ -21,8 +21,10 @@ list of either: A recorded session can be: -- **Replayed**, either entirely or starting from a selected action, to - reproduce the exact same sequence on the current workspace; +- **Replayed** in validation mode, without adding new signal/image outputs to + the workspace; +- **Duplicated and applied**, to create an explicit comparison branch with new + outputs in the signal/image panels; - **Restored to a given selection state** without re-executing anything, to quickly jump back to a previous working context; - **Saved to a standalone history file** (``.dlhist``) or **embedded in the @@ -48,6 +50,16 @@ The toolbar at the top of the panel exposes the following actions: :height: 24px :class: dark-light no-scaled-link +.. |open_history| image:: ../../../datalab/data/icons/io/fileopen_h5.svg + :width: 24px + :height: 24px + :class: dark-light no-scaled-link + +.. |save_history| image:: ../../../datalab/data/icons/io/filesave_h5.svg + :width: 24px + :height: 24px + :class: dark-light no-scaled-link + .. |replay| image:: ../../../datalab/data/icons/replay.svg :width: 24px :height: 24px @@ -58,12 +70,22 @@ The toolbar at the top of the panel exposes the following actions: :height: 24px :class: dark-light no-scaled-link -.. |restore_and_replay| image:: ../../../datalab/data/icons/restore_and_replay.svg +.. |edit_mode| image:: ../../../datalab/data/icons/edit_mode.svg :width: 24px :height: 24px :class: dark-light no-scaled-link -.. |edit_mode| image:: ../../../datalab/data/icons/edit_mode.svg +.. |duplicate| image:: ../../../datalab/data/icons/edit/duplicate.svg + :width: 24px + :height: 24px + :class: dark-light no-scaled-link + +.. |step_prev| image:: ../../../datalab/data/icons/libre-gui-arrow-left.svg + :width: 24px + :height: 24px + :class: dark-light no-scaled-link + +.. |step_next| image:: ../../../datalab/data/icons/libre-gui-arrow-right.svg :width: 24px :height: 24px :class: dark-light no-scaled-link @@ -73,25 +95,53 @@ The toolbar at the top of the panel exposes the following actions: :height: 24px :class: dark-light no-scaled-link +.. |generate_macro| image:: ../../../datalab/data/icons/console.svg + :width: 24px + :height: 24px + :class: dark-light no-scaled-link + +.. |remove_incompatible| image:: ../../../datalab/data/icons/edit/delete_all.svg + :width: 24px + :height: 24px + :class: dark-light no-scaled-link + - |record| **Record mode**: toggle the recording of new actions. When off, no new entry is added to the history (existing sessions are preserved). -- |replay| **Replay**: replay the selected action (or the whole session if a - session row is selected) without changing the current workspace selection - beforehand. +- |open_history| **Open history file**: load recorded sessions from a standalone + ``.dlhist`` file. +- |save_history| **Save history file**: save the current recorded sessions to a + standalone ``.dlhist`` file. +- |replay| **Replay**: validate/replay the selected action (or the whole + session if a session row is selected) without changing the current workspace + selection beforehand and without adding new outputs to the signal/image + panels. - |restore_selection| **Restore selection**: only re-select the objects that were selected when the action was originally executed; no computation is re-run. -- |restore_and_replay| **Restore selection and replay**: combine the two - previous actions -- restore the selection first, then replay. - |edit_mode| **Edit mode**: when on, replaying a computation opens the parameters dialog so the user can tweak the parameters before re-running. + When replaying a *whole session*, the parameter dialogs open in a + **read-only** mode — all fields are shown with their recorded values but + cannot be edited. +- |duplicate| **Duplicate**: copy the selected action or session into a new + history session. The copied parameters are independent from the original + record. +- |generate_macro| **Generate macro**: generate a Python macro script from the + selected actions (or all actions if nothing is selected). The generated script + is copied to the clipboard. +- |remove_incompatible| **Remove incompatible**: remove all actions whose + workspace state is no longer compatible with the current workspace. A + confirmation dialog shows how many actions will be removed. - |delete| **Delete**: remove the selected actions or sessions from the history. +- |step_prev| **Previous step**: select the preceding action in the current + session (keyboard shortcut: :kbd:`Ctrl+Left`). +- |step_next| **Next step**: select the following action in the current + session (keyboard shortcut: :kbd:`Ctrl+Right`). .. note:: - Double-clicking on an action row in the tree is equivalent to "Restore - selection and replay". + Double-clicking on an action row in the tree is equivalent to **Replay**. Tree view --------- @@ -106,6 +156,24 @@ The tree view organizes recorded actions into expandable sessions: The selection of one or several rows drives which actions are targeted by the toolbar buttons. +Actions that are not compatible with the current workspace state (for example +because a referenced object identifier no longer exists, or because its data +shape changed) are shown with a disabled foreground and an explanatory tooltip. +They cannot be replayed until the workspace matches the recorded state again. + +Workspace state display +----------------------- + +Below the action tree, a split-view widget shows the **workspace state** +captured at the time of the selected action: + +- **Left table**: lists the signals that were selected, with their data shape. +- **Right table**: lists the images that were selected, with their dimensions. + +This information helps the user understand the context in which each action +was originally executed and diagnose compatibility issues when replaying +sessions on a different workspace. + Session replay across workspaces -------------------------------- @@ -135,12 +203,55 @@ The history can be persisted in two complementary ways: (``File > Save to HDF5 file``), the History Panel content is automatically saved alongside the signals and images. Reloading the workspace restores the recorded sessions. -- **Standalone history file**: the panel can also be serialised to a - dedicated ``.dlhist`` file, which is convenient to share or version a - processing chain independently of the data it was applied to. +- **Standalone history file** (``.dlhist``): the file embeds both the + recorded sessions **and** all signal/image objects referenced by those + sessions. This makes the file fully self-contained: + + - Opening a ``.dlhist`` into an **empty workspace** loads sessions and + objects directly, restoring the workspace to its recorded state. + - Opening a ``.dlhist`` into a **non-empty workspace** creates new + signal/image groups for the imported objects (with remapped identifiers + to avoid collisions) and appends new history sessions that reference + those fresh identifiers. .. warning:: Replaying a session that depends on external files (e.g. opening a dataset from disk) will only succeed if those files are still available at the same locations as when the session was recorded. + +Chain reconnection on deletion +------------------------------- + +When a result object is deleted from the **signal or image panel** (not +from the History Panel tree), and that object was produced by a recorded +processing step, the History Panel automatically reconnects the processing +chain: + +- All downstream steps that consumed the deleted object are rewired to use + the source of the deleted step as their new input. +- For ``2_to_1`` operations (e.g. *difference*), the first source is used + for reconnection. +- If no valid source can be determined (e.g. the source itself was already + deleted), a warning is displayed listing the unreconnectable operations, + but the deletion is allowed to proceed. + +This behaviour mirrors removing a link from a chain: the adjacent links +reconnect to preserve the processing flow. + +.. note:: + + Reconnection is only triggered by deletions initiated from the + signal/image panels. Deleting an action directly from the History Panel + tree removes it and all subsequent actions in that session. + +Auto-recompute +-------------- + +.. note:: + + When a result object is selected in the signal/image panel and it has + processing parameters (i.e. was produced by a 1-to-1 computation), a + **Processing** tab appears in the Properties panel. Checking + **Auto-recompute on edit** in that tab will re-run the computation + automatically 300 ms after any parameter modification. diff --git a/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po b/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po index afcb4a95e..8183e3c0c 100644 --- a/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po +++ b/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: DataLab \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-16 11:30+0200\n" +"POT-Creation-Date: 2026-06-02 15:49+0200\n" "PO-Revision-Date: 2026-05-16 11:35+0200\n" "Last-Translator: DataLab Platform Developers\n" "Language: fr\n" @@ -29,8 +29,8 @@ msgid "" "DataLab, history, record, replay, session, scientific, data, analysis, " "visualization, platform" msgstr "" -"DataLab, historique, enregistrement, rejeu, session, scientifique, données, " -"analyse, visualisation, plateforme" +"DataLab, historique, enregistrement, rejeu, session, scientifique, " +"données, analyse, visualisation, plateforme" msgid "History Panel" msgstr "Panneau historique" @@ -45,8 +45,8 @@ msgid "" msgstr "" "Le « Panneau historique » enregistre la séquence des actions effectuées " "par l'utilisateur sur les signaux et les images, organisée en " -"**sessions**. Chaque session est une liste chronologique constituée " -"soit :" +"**sessions**. Chaque session est une liste chronologique constituée soit " +":" msgid "" "**UI actions** (creating a new signal, removing selected objects, saving " @@ -67,12 +67,18 @@ msgid "A recorded session can be:" msgstr "Une session enregistrée peut être :" msgid "" -"**Replayed**, either entirely or starting from a selected action, to " -"reproduce the exact same sequence on the current workspace;" +"**Replayed** in validation mode, without adding new signal/image outputs " +"to the workspace;" msgstr "" -"**rejouée**, soit intégralement, soit à partir d'une action sélectionnée, " -"afin de reproduire exactement la même séquence sur l'espace de travail " -"courant ;" +"**rejouée** en mode validation, sans ajouter de nouvelles sorties " +"signal/image à l'espace de travail ;" + +msgid "" +"**Duplicated and applied**, to create an explicit comparison branch with " +"new outputs in the signal/image panels;" +msgstr "" +"**dupliquée et appliquée**, afin de créer une branche de comparaison " +"explicite avec de nouvelles sorties dans les panneaux signal/image ;" msgid "" "**Restored to a given selection state** without re-executing anything, to" @@ -96,9 +102,9 @@ msgid "" "Gaussian signal, compute the average, add Gaussian noise to the result " "and run a Gaussian fit." msgstr "" -"Le Panneau historique après l'enregistrement d'une session représentative :" -" création de trois signaux (Voigt, lorentzien, lorentzien), suppression " -"de l'un d'eux, création d'un signal gaussien, calcul de la moyenne, " +"Le Panneau historique après l'enregistrement d'une session représentative" +" : création de trois signaux (Voigt, lorentzien, lorentzien), suppression" +" de l'un d'eux, création d'un signal gaussien, calcul de la moyenne, " "ajout d'un bruit gaussien au résultat et ajustement par une gaussienne." msgid "Toolbar" @@ -119,13 +125,35 @@ msgid "record" msgstr "record" msgid "" -"|replay| **Replay**: replay the selected action (or the whole session if " -"a session row is selected) without changing the current workspace " -"selection beforehand." +"|open_history| **Open history file**: load recorded sessions from a " +"standalone ``.dlhist`` file." +msgstr "" +"|open_history| **Ouvrir un fichier d'historique** : charge des sessions " +"enregistrées depuis un fichier ``.dlhist`` autonome." + +msgid "open_history" +msgstr "open_history" + +msgid "" +"|save_history| **Save history file**: save the current recorded sessions " +"to a standalone ``.dlhist`` file." +msgstr "" +"|save_history| **Enregistrer le fichier d'historique** : enregistre les " +"sessions actuellement enregistrées dans un fichier ``.dlhist`` autonome." + +msgid "save_history" +msgstr "save_history" + +msgid "" +"|replay| **Replay**: validate/replay the selected action (or the whole " +"session if a session row is selected) without changing the current " +"workspace selection beforehand and without adding new outputs to the " +"signal/image panels." msgstr "" -"|replay| **Rejouer** : rejoue l'action sélectionnée (ou la session " -"entière si une ligne de session est sélectionnée) sans modifier au " -"préalable la sélection courante de l'espace de travail." +"|replay| **Rejouer** : valide/rejoue l'action sélectionnée (ou la session" +" entière si une ligne de session est sélectionnée) sans modifier au " +"préalable la sélection courante de l'espace de travail et sans ajouter de" +" nouvelles sorties aux panneaux signal/image." msgid "replay" msgstr "replay" @@ -142,16 +170,6 @@ msgstr "" msgid "restore_selection" msgstr "restore_selection" -msgid "" -"|restore_and_replay| **Restore selection and replay**: combine the two " -"previous actions -- restore the selection first, then replay." -msgstr "" -"|restore_and_replay| **Restaurer la sélection et rejouer** : combine les " -"deux actions précédentes -- restaure d'abord la sélection, puis rejoue." - -msgid "restore_and_replay" -msgstr "restore_and_replay" - msgid "" "|edit_mode| **Edit mode**: when on, replaying a computation opens the " "parameters dialog so the user can tweak the parameters before re-running." @@ -163,6 +181,43 @@ msgstr "" msgid "edit_mode" msgstr "edit_mode" +msgid "" +"|duplicate| **Duplicate**: copy the selected action or session into a new" +" history session. The copied parameters are independent from the original" +" record." +msgstr "" +"|duplicate| **Dupliquer** : copie l'action ou la session sélectionnée " +"dans une nouvelle session d'historique. Les paramètres copiés sont " +"indépendants de l'enregistrement d'origine." + +msgid "duplicate" +msgstr "duplicate" + +msgid "" +"|generate_macro| **Generate macro**: generate a Python macro script from " +"the selected actions (or all actions if nothing is selected). The " +"generated script is copied to the clipboard." +msgstr "" +"|generate_macro| **Générer une macro** : génère un script macro Python à " +"partir des actions sélectionnées (ou de toutes les actions si rien n'est " +"sélectionné). Le script généré est copié dans le presse-papiers." + +msgid "generate_macro" +msgstr "generate_macro" + +msgid "" +"|remove_incompatible| **Remove incompatible**: remove all actions whose " +"workspace state is no longer compatible with the current workspace. A " +"confirmation dialog shows how many actions will be removed." +msgstr "" +"|remove_incompatible| **Supprimer les incompatibles** : supprime toutes " +"les actions dont l'état de l'espace de travail n'est plus compatible avec " +"l'espace de travail actuel. Une boîte de dialogue de confirmation indique " +"combien d'actions seront supprimées." + +msgid "remove_incompatible" +msgstr "remove_incompatible" + msgid "" "|delete| **Delete**: remove the selected actions or sessions from the " "history." @@ -174,11 +229,29 @@ msgid "delete" msgstr "delete" msgid "" -"Double-clicking on an action row in the tree is equivalent to \"Restore " -"selection and replay\"." +"|step_prev| **Previous step**: select the preceding action in the current" +" session (keyboard shortcut: :kbd:`Ctrl+Left`)." +msgstr "" +"|step_prev| **Étape précédente** : sélectionne l'action précédente dans " +"la session courante (raccourci clavier : :kbd:`Ctrl+Gauche`)." + +msgid "step_prev" +msgstr "step_prev" + +msgid "" +"|step_next| **Next step**: select the following action in the current " +"session (keyboard shortcut: :kbd:`Ctrl+Right`)." +msgstr "" +"|step_next| **Étape suivante** : sélectionne l'action suivante dans la " +"session courante (raccourci clavier : :kbd:`Ctrl+Droite`)." + +msgid "step_next" +msgstr "step_next" + +msgid "Double-clicking on an action row in the tree is equivalent to **Replay**." msgstr "" "Un double-clic sur la ligne d'une action dans l'arborescence équivaut à " -"« Restaurer la sélection et rejouer »." +"**Rejouer**." msgid "Tree view" msgstr "Arborescence" @@ -192,8 +265,8 @@ msgid "" "Each top-level row is a **session**, automatically created when recording" " is enabled and a new application context is started." msgstr "" -"Chaque ligne de premier niveau est une **session**, créée automatiquement " -"lorsque l'enregistrement est activé et qu'un nouveau contexte " +"Chaque ligne de premier niveau est une **session**, créée automatiquement" +" lorsque l'enregistrement est activé et qu'un nouveau contexte " "d'application est démarré." msgid "" @@ -202,8 +275,8 @@ msgid "" "(for UI actions)." msgstr "" "Chaque ligne enfant est une **action**, accompagnée de son titre, de sa " -"date et de son heure, ainsi que d'une description résumant les " -"paramètres (pour les calculs) ou l'appel (pour les actions de l'interface)." +"date et de son heure, ainsi que d'une description résumant les paramètres" +" (pour les calculs) ou l'appel (pour les actions de l'interface)." msgid "" "The selection of one or several rows drives which actions are targeted by" @@ -212,6 +285,55 @@ msgstr "" "La sélection d'une ou de plusieurs lignes détermine les actions ciblées " "par les boutons de la barre d'outils." +msgid "" +"Actions that are not compatible with the current workspace state (for " +"example because a referenced object identifier no longer exists, or " +"because its data shape changed) are shown with a disabled foreground and " +"an explanatory tooltip. They cannot be replayed until the workspace " +"matches the recorded state again." +msgstr "" +"Les actions qui ne sont pas compatibles avec l'état courant de l'espace " +"de travail (par exemple parce qu'un identifiant d'objet référencé " +"n'existe plus, ou parce que la forme de ses données a changé) sont " +"affichées avec un texte désactivé et une infobulle explicative. Elles ne " +"peuvent pas être rejouées tant que l'espace de travail ne correspond pas " +"de nouveau à l'état enregistré." + +msgid "Workspace state display" +msgstr "Affichage de l'état de l'espace de travail" + +msgid "" +"Below the action tree, a split-view widget shows the **workspace state** " +"captured at the time of the selected action:" +msgstr "" +"Sous l'arborescence des actions, un widget en vue divisée affiche " +"l'**état de l'espace de travail** tel qu'il était au moment de l'action " +"sélectionnée :" + +msgid "" +"**Left table**: lists the signals that were selected, with their data " +"shape." +msgstr "" +"**Tableau de gauche** : liste les signaux qui étaient sélectionnés, avec " +"leur forme de données." + +msgid "" +"**Right table**: lists the images that were selected, with their " +"dimensions." +msgstr "" +"**Tableau de droite** : liste les images qui étaient sélectionnées, avec " +"leurs dimensions." + +msgid "" +"This information helps the user understand the context in which each " +"action was originally executed and diagnose compatibility issues when " +"replaying sessions on a different workspace." +msgstr "" +"Ces informations aident l'utilisateur à comprendre le contexte dans " +"lequel chaque action a été exécutée à l'origine et à diagnostiquer les " +"problèmes de compatibilité lors du rejeu de sessions sur un espace de " +"travail différent." + msgid "Session replay across workspaces" msgstr "Rejeu d'une session entre espaces de travail" @@ -224,8 +346,8 @@ msgid "" msgstr "" "Une session complète peut être rejouée sur un espace de travail qui ne " "contient plus les objets référencés à l'origine par les actions " -"enregistrées -- typiquement après le chargement d'une session sauvegardée " -"dans un espace de travail vierge. Dans ce cas, le panneau **réassocie à " +"enregistrées -- typiquement après le chargement d'une session sauvegardée" +" dans un espace de travail vierge. Dans ce cas, le panneau **réassocie à " "la volée les identifiants d'objets enregistrés** aux nouveaux " "identifiants créés :" @@ -248,9 +370,9 @@ msgid "" "workspace contents, so chained creation/removal sequences replay " "correctly." msgstr "" -"les actions de l'interface qui suppriment des objets maintiennent la " -"file synchronisée avec le contenu réel de l'espace de travail, de sorte " -"que les séquences enchaînées de création et de suppression se rejouent " +"les actions de l'interface qui suppriment des objets maintiennent la file" +" synchronisée avec le contenu réel de l'espace de travail, de sorte que " +"les séquences enchaînées de création et de suppression se rejouent " "correctement." msgid "" @@ -259,8 +381,8 @@ msgid "" "different but structurally identical input." msgstr "" "Cela permet par exemple d'enregistrer une chaîne de traitement complète " -"sur un jeu de données, de la sauvegarder, puis de la ré-appliquer " -"telle quelle à une entrée différente mais structurellement identique." +"sur un jeu de données, de la sauvegarder, puis de la ré-appliquer telle " +"quelle à une entrée différente mais structurellement identique." msgid "Persistence" msgstr "Persistance" @@ -296,6 +418,149 @@ msgid "" "at the same locations as when the session was recorded." msgstr "" "Le rejeu d'une session qui dépend de fichiers externes (par exemple " -"l'ouverture d'un jeu de données depuis le disque) ne réussira que si " -"ces fichiers sont toujours disponibles aux mêmes emplacements qu'au " -"moment de l'enregistrement de la session." +"l'ouverture d'un jeu de données depuis le disque) ne réussira que si ces " +"fichiers sont toujours disponibles aux mêmes emplacements qu'au moment de" +" l'enregistrement de la session." + +msgid "Auto-recompute" +msgstr "Recalcul automatique" + +msgid "" +"When a result object is selected in the signal/image panel and it has " +"processing parameters (i.e. was produced by a 1-to-1 computation), a " +"**Processing** tab appears in the Properties panel. Checking **Auto-" +"recompute on edit** in that tab will re-run the computation automatically" +" 300 ms after any parameter modification." +msgstr "" +"Lorsqu'un objet résultat est sélectionné dans le panneau signal/image et " +"qu'il possède des paramètres de traitement (c'est-à-dire qu'il a été " +"produit par un calcul 1-à-1), un onglet **Traitement** apparaît dans le " +"panneau Propriétés. Cocher **Recalcul automatique lors de l'édition** " +"dans cet onglet relancera automatiquement le calcul 300 ms après toute " +"modification d'un paramètre." + +msgid "" +"When replaying a *whole session*, the parameter dialogs open in a " +"**read-only** mode — all fields are shown with their recorded values but " +"cannot be edited." +msgstr "" +"Lors du rejeu d'une *session entière*, les boîtes de dialogue des " +"paramètres s'ouvrent en mode **lecture seule** — tous les champs " +"affichent les valeurs enregistrées mais ne peuvent pas être édités." + +msgid "Chain reconnection on deletion" +msgstr "Reconnexion de la chaîne lors d'une suppression" + +msgid "" +"When a result object is deleted from the **signal or image panel** (not " +"from the History Panel tree), and that object was produced by a recorded " +"processing step, the History Panel automatically reconnects the processing " +"chain:" +msgstr "" +"Lorsqu'un objet résultat est supprimé depuis le **panneau signal ou image** " +"(et non depuis l'arborescence du panneau historique), et que cet objet a " +"été produit par une étape de traitement enregistrée, le Panneau historique " +"reconnecte automatiquement la chaîne de traitement :" + +msgid "" +"All downstream steps that consumed the deleted object are rewired to use " +"the source of the deleted step as their new input." +msgstr "" +"Toutes les étapes aval qui consommaient l'objet supprimé sont recâblées " +"pour utiliser la source de l'étape supprimée comme nouvelle entrée." + +msgid "" +"For ``2_to_1`` operations (e.g. *difference*), the first source is used " +"for reconnection." +msgstr "" +"Pour les opérations ``2_to_1`` (par exemple *différence*), la première " +"source est utilisée pour la reconnexion." + +msgid "" +"If no valid source can be determined (e.g. the source itself was already " +"deleted), a warning is displayed listing the unreconnectable operations, " +"but the deletion is allowed to proceed." +msgstr "" +"Si aucune source valide ne peut être déterminée (par exemple la source " +"elle-même a déjà été supprimée), un avertissement est affiché listant les " +"opérations non reconnectables, mais la suppression est néanmoins autorisée." + +msgid "" +"This behaviour mirrors removing a link from a chain: the adjacent links " +"reconnect to preserve the processing flow." +msgstr "" +"Ce comportement reproduit la suppression d'un maillon d'une chaîne : les " +"maillons adjacents se reconnectent pour préserver le flux de traitement." + +msgid "" +"Reconnection is only triggered by deletions initiated from the " +"signal/image panels. Deleting an action directly from the History Panel " +"tree removes it and all subsequent actions in that session." +msgstr "" +"La reconnexion n'est déclenchée que par les suppressions initiées depuis " +"les panneaux signal/image. Supprimer une action directement depuis " +"l'arborescence du Panneau historique la retire ainsi que toutes les " +"actions suivantes de cette session." + +msgid "" +"**Standalone history file** (``.dlhist``): the file embeds both the " +"recorded sessions **and** all signal/image objects referenced by those " +"sessions. This makes the file fully self-contained:" +msgstr "" +"**Fichier d'historique autonome** (``.dlhist``) : le fichier embarque à " +"la fois les sessions enregistrées **et** tous les objets signal/image " +"référencés par ces sessions. Cela rend le fichier entièrement autonome :" + +msgid "" +"Opening a ``.dlhist`` into an **empty workspace** loads sessions and " +"objects directly, restoring the workspace to its recorded state." +msgstr "" +"Ouvrir un fichier ``.dlhist`` dans un **espace de travail vide** charge " +"les sessions et les objets directement, restaurant l'espace de travail " +"dans son état enregistré." + +msgid "" +"Opening a ``.dlhist`` into a **non-empty workspace** creates new " +"signal/image groups for the imported objects (with remapped identifiers " +"to avoid collisions) and appends new history sessions that reference " +"those fresh identifiers." +msgstr "" +"Ouvrir un fichier ``.dlhist`` dans un **espace de travail non vide** crée " +"de nouveaux groupes signal/image pour les objets importés (avec des " +"identifiants remappés pour éviter les collisions) et ajoute de nouvelles " +"sessions d'historique référençant ces nouveaux identifiants." + +#~ msgid "" +#~ "|restore_and_replay| **Restore selection and " +#~ "replay**: combine the two previous " +#~ "actions -- restore the selection first," +#~ " then replay." +#~ msgstr "" +#~ "|restore_and_replay| **Restaurer la sélection " +#~ "et rejouer** : combine les deux " +#~ "actions précédentes -- restaure d'abord " +#~ "la sélection, puis rejoue." + +#~ msgid "restore_and_replay" +#~ msgstr "restore_and_replay" + +#~ msgid "" +#~ "|replay| **Apply duplicate**: replay the " +#~ "selected duplicate persistently, adding " +#~ "comparison outputs to the signal/image " +#~ "panels. Outputs without an existing " +#~ "destination group are placed in a " +#~ "``Replay duplicate`` group, and their " +#~ "titles are prefixed with ``Replay " +#~ "duplicate -``." +#~ msgstr "" +#~ "|replay| **Appliquer le duplicata** : " +#~ "rejoue le duplicata sélectionné de façon" +#~ " persistante, en ajoutant des sorties " +#~ "de comparaison aux panneaux signal/image. " +#~ "Les sorties sans groupe de destination" +#~ " existant sont placées dans un groupe" +#~ " ``Rejeu du duplicata``, et leurs " +#~ "titres sont préfixés par ``Rejeu du " +#~ "duplicata -``." + diff --git a/doc/locale/fr/LC_MESSAGES/release_notes/release_1.03.po b/doc/locale/fr/LC_MESSAGES/release_notes/release_1.03.po index 6019a4299..809cc8ff5 100644 --- a/doc/locale/fr/LC_MESSAGES/release_notes/release_1.03.po +++ b/doc/locale/fr/LC_MESSAGES/release_notes/release_1.03.po @@ -5,11 +5,17 @@ # msgid "" msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2026-05-28 17:03+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.18.0\n" msgid "Version 1.3" msgstr "Version 1.3" @@ -23,14 +29,59 @@ msgstr "✨ Nouvelles fonctionnalités" msgid "**Third-party plugin discovery via environment variable:**" msgstr "**Découverte des plugins tiers via une variable d'environnement :**" -msgid "Added support for the `DATALAB_PLUGINS` environment variable, allowing one or more directories to be specified as additional plugin search paths" -msgstr "Ajout de la prise en charge de la variable d'environnement `DATALAB_PLUGINS`, permettant de spécifier un ou plusieurs répertoires comme chemins de recherche supplémentaires pour les plugins" +msgid "" +"Added support for the `DATALAB_PLUGINS` environment variable, allowing " +"one or more directories to be specified as additional plugin search paths" +msgstr "" +"Ajout de la prise en charge de la variable d'environnement " +"`DATALAB_PLUGINS`, permettant de spécifier un ou plusieurs répertoires " +"comme chemins de recherche supplémentaires pour les plugins" -msgid "Multiple directories can be listed using the OS path separator (`;` on Windows, `:` on Linux/macOS), following the same convention as `PYTHONPATH`" -msgstr "Plusieurs répertoires peuvent être listés en utilisant le séparateur de chemin du système d'exploitation (`;` sous Windows, `:` sous Linux/macOS), selon la même convention que `PYTHONPATH`" +msgid "" +"Multiple directories can be listed using the OS path separator (`;` on " +"Windows, `:` on Linux/macOS), following the same convention as " +"`PYTHONPATH`" +msgstr "" +"Plusieurs répertoires peuvent être listés en utilisant le séparateur de " +"chemin du système d'exploitation (`;` sous Windows, `:` sous " +"Linux/macOS), selon la même convention que `PYTHONPATH`" -msgid "Listed directories are appended to the existing plugin search paths at startup and are picked up automatically by the plugin discovery mechanism" -msgstr "Les répertoires listés sont ajoutés aux chemins de recherche existants au démarrage et sont automatiquement pris en compte par le mécanisme de découverte des plugins" +msgid "" +"Listed directories are appended to the existing plugin search paths at " +"startup and are picked up automatically by the plugin discovery mechanism" +msgstr "" +"Les répertoires listés sont ajoutés aux chemins de recherche existants au" +" démarrage et sont automatiquement pris en compte par le mécanisme de " +"découverte des plugins" + +msgid "" +"Non-existent directories are silently skipped (a warning is recorded in " +"the log file), so a stale environment variable on another machine will " +"not prevent DataLab from starting" +msgstr "" +"Les répertoires inexistants sont ignorés silencieusement (un " +"avertissement est consigné dans le fichier journal), ainsi une variable " +"d'environnement obsolète sur une autre machine n'empêchera pas le " +"démarrage de DataLab" -msgid "Non-existent directories are silently skipped (a warning is recorded in the log file), so a stale environment variable on another machine will not prevent DataLab from starting" -msgstr "Les répertoires inexistants sont ignorés silencieusement (un avertissement est consigné dans le fichier journal), ainsi une variable d'environnement obsolète sur une autre machine n'empêchera pas le démarrage de DataLab" +msgid "**History Panel sessions:**" +msgstr "**Sessions du panneau d'historique :**" + +msgid "" +"Added serialized and replayable history sessions with workspace-state " +"validation" +msgstr "" +"Ajout de sessions d'historique sérialisées et rejouables, avec validation " +"de l'état de l'espace de travail" + +msgid "" +"Added `.dlhist` import/export support and separated reset sessions from " +"regular history sessions" +msgstr "" +"Ajout de la prise en charge de l'import/export `.dlhist` et séparation des " +"sessions de réinitialisation des sessions d'historique ordinaires" + +msgid "Improved replay compatibility reporting for clearer user feedback" +msgstr "" +"Amélioration du rapport de compatibilité de relecture pour fournir un retour " +"utilisateur plus clair" diff --git a/doc/release_notes/release_1.03.md b/doc/release_notes/release_1.03.md index 87c809b1b..ac317ab42 100644 --- a/doc/release_notes/release_1.03.md +++ b/doc/release_notes/release_1.03.md @@ -10,3 +10,9 @@ * Multiple directories can be listed using the OS path separator (`;` on Windows, `:` on Linux/macOS), following the same convention as `PYTHONPATH` * Listed directories are appended to the existing plugin search paths at startup and are picked up automatically by the plugin discovery mechanism * Non-existent directories are silently skipped (a warning is recorded in the log file), so a stale environment variable on another machine will not prevent DataLab from starting + +**History Panel sessions:** + +* Added serialized and replayable history sessions with workspace-state validation +* Added `.dlhist` import/export support and separated reset sessions from regular history sessions +* Improved replay compatibility reporting for clearer user feedback From 3a55ab06d9a87de57cee78cb83cd72412bb04a4e Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Thu, 4 Jun 2026 17:10:31 +0200 Subject: [PATCH 021/108] feat(history): refactor history panel and replay workflow Split the history feature into dedicated modules, refresh the GUI wiring and widgets, and update the related tests and translations. --- datalab/config.py | 6 + datalab/gui/historysession_ops.py | 312 ++ datalab/gui/historytools_ops.py | 456 ++ datalab/gui/panel/history.py | 4933 ----------------- datalab/gui/panel/history/__init__.py | 21 + datalab/gui/panel/history/chain.py | 375 ++ .../gui/panel/history/interactive_replay.py | 195 + datalab/gui/panel/history/panel.py | 902 +++ datalab/gui/panel/history/recompute.py | 495 ++ datalab/h5/history.py | 263 + datalab/history/__init__.py | 23 + datalab/history/action.py | 781 +++ datalab/history/core.py | 235 + datalab/history/session.py | 392 ++ datalab/history/workspace_state.py | 249 + datalab/locale/fr/LC_MESSAGES/datalab.po | 202 +- .../auto_analysis_recompute_unit_test.py | 4 + .../tests/features/common/history_app_test.py | 31 +- .../common/history_contract_unit_test.py | 214 - .../common/history_replay_app_test.py | 448 -- datalab/tests/features/common/history_test.py | 1508 +++++ .../common/interactive_processing_test.py | 20 + datalab/widgets/historydescription.py | 90 + datalab/widgets/historytree.py | 249 + datalab/widgets/workspacestate_widget.py | 82 + 25 files changed, 6778 insertions(+), 5708 deletions(-) create mode 100644 datalab/gui/historysession_ops.py create mode 100644 datalab/gui/historytools_ops.py delete mode 100644 datalab/gui/panel/history.py create mode 100644 datalab/gui/panel/history/__init__.py create mode 100644 datalab/gui/panel/history/chain.py create mode 100644 datalab/gui/panel/history/interactive_replay.py create mode 100644 datalab/gui/panel/history/panel.py create mode 100644 datalab/gui/panel/history/recompute.py create mode 100644 datalab/h5/history.py create mode 100644 datalab/history/__init__.py create mode 100644 datalab/history/action.py create mode 100644 datalab/history/core.py create mode 100644 datalab/history/session.py create mode 100644 datalab/history/workspace_state.py delete mode 100644 datalab/tests/features/common/history_contract_unit_test.py delete mode 100644 datalab/tests/features/common/history_replay_app_test.py create mode 100644 datalab/tests/features/common/history_test.py create mode 100644 datalab/widgets/historydescription.py create mode 100644 datalab/widgets/historytree.py create mode 100644 datalab/widgets/workspacestate_widget.py diff --git a/datalab/config.py b/datalab/config.py index 68996035f..0a8c4e525 100644 --- a/datalab/config.py +++ b/datalab/config.py @@ -295,6 +295,11 @@ class ProcSection(conf.Section, metaclass=conf.SectionMeta): # - False: do not ignore warnings ignore_warnings = conf.Option() + # Automatically start recording history at DataLab launch: + # - True: history recording is enabled at startup (default) + # - False: user must enable it manually via the History panel toolbar + history_auto_record = conf.Option() + # X-array compatibility behavior for multi-signal computations: # - "ask": ask user for confirmation when x-arrays are incompatible (default) # - "interpolate": automatically interpolate when x-arrays are incompatible @@ -582,6 +587,7 @@ def initialize(): Conf.proc.keep_results.get(False) Conf.proc.show_result_dialog.get(True) Conf.proc.ignore_warnings.get(False) + Conf.proc.history_auto_record.get(True) Conf.proc.xarray_compat_behavior.get("ask") Conf.proc.small_mono_font.get((configtools.MONOSPACE, 8, False)) # View section diff --git a/datalab/gui/historysession_ops.py b/datalab/gui/historysession_ops.py new file mode 100644 index 000000000..67102cdf6 --- /dev/null +++ b/datalab/gui/historysession_ops.py @@ -0,0 +1,312 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +"""Helpers for History panel session recording and indexing.""" + +from __future__ import annotations + +import logging +from contextlib import contextmanager +from copy import deepcopy +from typing import TYPE_CHECKING, Any, Callable, Generator + +from datalab.history import HistoryAction, HistorySession, WorkspaceState +from datalab.history.core import _resolve_self_target + +if TYPE_CHECKING: + from datalab.gui.panel.history import HistoryPanel + +_logger = logging.getLogger(__name__) + + +def create_new_session(panel: HistoryPanel) -> None: + """Create a new history list""" + panel.session_increment += 1 + session = HistorySession(number=panel.session_increment) + panel.history_sessions.append(session) + panel.tree.populate_tree(panel.history_sessions) + panel.refresh_compatibility_items() + + +def start_new_session_after_workspace_reset(panel: HistoryPanel) -> None: + """Start a new history session after a workspace reset, when useful.""" + if panel.history_sessions and panel.history_sessions[-1].actions: + panel.create_new_session() + + +def add_compute_entry( + panel: HistoryPanel, + action_title: str, + panel_str: str, + func_name: str, + pattern: str, + save_state: bool = True, + output_uuids: list[str] | None = None, + plugin_origin: dict[str, Any] | None = None, + **kwargs: Any, +) -> HistoryAction | None: + """Record a *compute* action in the current history session. + + Args: + action_title: Title shown in the history tree. + panel_str: ``"signal"`` or ``"image"``. + func_name: Sigima feature name (resolvable via + :meth:`BaseProcessor.get_feature`). + pattern: One of ``"1_to_1"``, ``"1_to_0"``, ``"n_to_1"``, ``"2_to_1"``, + ``"1_to_n"``, ``"multiple_1_to_1"`` (the latter is recorded for + traceability but not replayable). + save_state: If True, capture the workspace state for replay. + output_uuids: Optional list of UUIDs of the data objects produced by + this action. When known at call time, prefer passing it here so the + bijective mapping is initialised in one step. Most callers do not + know the outputs yet and instead wrap the compute call with + :meth:`capture_outputs` (or call :meth:`register_action_outputs` + explicitly afterwards) using the returned action. + plugin_origin: Optional plugin origin descriptor (see + :func:`datalab.gui.processor.base._detect_plugin_origin`). ``None`` + for built-in Sigima/DataLab features. + **kwargs: Extra primitive kwargs (``param``, ``obj2_uuids``, + ``obj2_name``, ``pairwise``, ``params`` (list of DataSet), + ``func_names`` (list of str), ...). ``DataSet`` instances are + serialised as JSON. + + Returns: + The created :class:`HistoryAction`, or ``None`` if recording is + disabled (record mode off or replay in progress). + """ + if not panel.record_mode_enabled or panel.is_replaying(): + return None + state = WorkspaceState() + if save_state: + state.save(panel.mainwindow) + # Deep-copy kwargs so each action owns independent parameter + # instances. Without this, consecutive applications of the same + # function (e.g. two gaussian_filter calls with different sigma) + # would share a single DataSet object and editing one action's + # parameters would silently mutate the other. + action = HistoryAction( + title=action_title, + kind=HistoryAction.KIND_COMPUTE, + panel_str=panel_str, + func_name=func_name, + pattern=pattern, + kwargs=deepcopy(kwargs), + state=state, + plugin_origin=plugin_origin, + ) + panel.add_object(action) + if output_uuids is not None: + panel.register_action_outputs(action, output_uuids) + return action + + +def add_compute_entry_from_pp( + panel: HistoryPanel, + action_title: str, + pp: Any, # ProcessingParameters (avoid circular import) + panel_str: str, + save_state: bool = True, + output_uuids: list[str] | None = None, + plugin_origin: dict[str, Any] | None = None, + **extras: Any, +) -> HistoryAction | None: + """Record a *compute* action derived from a ``ProcessingParameters``. + + Bridges the dash-form pattern used in object metadata + (``"1-to-1"`` …) with the underscore form expected by + :class:`HistoryAction` (``"1_to_1"`` …) so that both sides share + a single identity (``func_name`` / ``pattern`` / ``param``). + + Args: + action_title: Title shown in the history tree. + pp: :class:`~datalab.gui.processor.base.ProcessingParameters` + instance describing the operation. + panel_str: ``"signal"`` or ``"image"``. + save_state: If True, capture the workspace state for replay. + output_uuids: Optional list of UUIDs of the data objects produced + by this action (see :meth:`add_compute_entry`). + plugin_origin: Optional plugin origin descriptor (see + :meth:`add_compute_entry`). + **extras: Additional history-only kwargs (``obj2_uuids``, + ``obj2_name``, ``pairwise``, ``params``, ``func_names``…). + + Returns: + The created :class:`HistoryAction`, or ``None`` if recording is + disabled. + """ + hist_pattern = pp.pattern.replace("-", "_") + kwargs: dict[str, Any] = {} + if pp.param is not None and "param" not in extras and "params" not in extras: + kwargs["param"] = pp.param + kwargs.update(extras) + return panel.add_compute_entry( + action_title, + panel_str=panel_str, + func_name=pp.func_name, + pattern=hist_pattern, + save_state=save_state, + output_uuids=output_uuids, + plugin_origin=plugin_origin, + **kwargs, + ) + + +def register_action_outputs( + panel: HistoryPanel, action: HistoryAction, output_uuids: list[str] +) -> None: + """Register the data objects produced by ``action``. + + Maintains the bijective ``action → outputs`` and ``output → action`` + mappings. May be called multiple times for a given action (later calls + replace earlier ones, e.g. after a cascade recompute). + + Args: + action: The history action that produced the outputs. + output_uuids: UUIDs of the produced data objects (empty for + ``1_to_0`` analysis patterns and for UI actions that did not + create new objects). + """ + # Drop previous outputs for this action from the reverse index. + previous = panel._action_output_uuids.get(action.uuid, []) + for prev_uuid in previous: + if panel._output_to_action.get(prev_uuid) == action.uuid: + panel._output_to_action.pop(prev_uuid, None) + new_outputs = list(output_uuids) + # Ownership transfer: if an output_uuid already belongs to a + # *different* action, remove it from that action's output list so the + # forward mapping stays consistent. The HistoryAction object's + # ``output_uuids`` attribute is NOT updated here because traversing all + # sessions to locate the object would be expensive; the panel-level + # dicts are the source of truth. + for out_uuid in new_outputs: + old_action_uuid = panel._output_to_action.get(out_uuid) + if old_action_uuid is not None and old_action_uuid != action.uuid: + old_list = panel._action_output_uuids.get(old_action_uuid) + if old_list is not None: + try: + old_list.remove(out_uuid) + except ValueError: + pass + if not old_list: + del panel._action_output_uuids[old_action_uuid] + _logger.debug( + "Output %s transferred from action %s to %s", + out_uuid, + old_action_uuid, + action.uuid, + ) + action.output_uuids = list(new_outputs) + panel._action_output_uuids[action.uuid] = new_outputs + for out_uuid in new_outputs: + panel._output_to_action[out_uuid] = action.uuid + + +@contextmanager +def capture_outputs( + panel: HistoryPanel, action: HistoryAction | None +) -> Generator[None, None, None]: + """Context manager: snapshot panel object IDs and record diffs as outputs. + + Use around any compute call when the produced UUIDs are not known + upfront. On exit, every newly-added object (signal or image) is + registered as an output of ``action`` via + :meth:`register_action_outputs`. No-op when ``action`` is ``None`` + (recording disabled). + + Args: + action: The history action being processed, or ``None``. + """ + if action is None: + yield + return + panels = (panel.mainwindow.signalpanel, panel.mainwindow.imagepanel) + before = {p.PANEL_STR_ID: set(p.objmodel.get_object_ids()) for p in panels} + try: + yield + finally: + new_uuids: list[str] = [] + for p in panels: + before_p = before[p.PANEL_STR_ID] + for uid in p.objmodel.get_object_ids(): + if uid not in before_p: + new_uuids.append(uid) + panel.register_action_outputs(action, new_uuids) + + +def add_ui_entry( + panel: HistoryPanel, + action_title: str, + target: str, + method_name: str, + save_state: bool = True, + **kwargs: Any, +) -> None: + """Record a *UI* action in the current history session. + + Args: + action_title: Title shown in the history tree. + target: One of ``"mainwindow"``, ``"signalpanel"``, ``"imagepanel"``, + ``"historypanel"`` -- attribute path on the main window. + method_name: Method name to call on ``target`` at replay time. + save_state: If True, capture the workspace state for replay. + **kwargs: Method keyword arguments. ``DataSet`` instances are + serialised as JSON; other values must be HDF5-friendly primitives. + """ + if not panel.record_mode_enabled or panel.is_replaying(): + return + state = WorkspaceState() + if save_state: + state.save(panel.mainwindow) + # Deep-copy kwargs to ensure independent parameter ownership + # (same rationale as in add_compute_entry). + action = HistoryAction( + title=action_title, + kind=HistoryAction.KIND_UI, + target=target, + method_name=method_name, + kwargs=deepcopy(kwargs), + state=state, + ) + panel.add_object(action) + + +def add_entry( + panel: HistoryPanel, + action_title: str, + save_state: bool, + func: Callable, + **kwargs, +) -> None: + """Legacy entry-point kept as a compatibility shim. + + Most call sites have been migrated to :meth:`add_compute_entry` or + :meth:`add_ui_entry`. The remaining paths -- and the + :func:`add_to_history` decorator -- still call ``add_entry`` with a + bound method; we infer the ``(target, method_name)`` from the bound + ``func.__self__`` and route to :meth:`add_ui_entry`. + """ + if not panel.record_mode_enabled or panel.is_replaying(): + return + target = None + if hasattr(func, "__self__"): + target = _resolve_self_target(func.__self__) + if target is None: + # Cannot route safely -- skip rather than pickle a Callable. + return + panel.add_ui_entry( + action_title, + target=target, + method_name=func.__name__, + save_state=save_state, + **kwargs, + ) + + +def add_object(panel: HistoryPanel, obj: HistoryAction) -> None: + """Add object to panel""" + if not panel.history_sessions: + panel.create_new_session() + panel.history_sessions[-1].add_action(obj) + panel.tree.add_action_to_tree(obj) + panel.tree.rearrange_tree() + panel.refresh_compatibility_items() + panel.update_actions_state() diff --git a/datalab/gui/historytools_ops.py b/datalab/gui/historytools_ops.py new file mode 100644 index 000000000..3e326df92 --- /dev/null +++ b/datalab/gui/historytools_ops.py @@ -0,0 +1,456 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +"""Helpers for History panel session tools.""" + +from __future__ import annotations + +from copy import deepcopy +from typing import TYPE_CHECKING +from uuid import uuid4 + +from qtpy import QtWidgets as QW + +from datalab.config import _ +from datalab.env import execenv +from datalab.gui.processor.base import ( + PROCESSING_PARAMETERS_OPTION, + ProcessingParameters, +) +from datalab.history import HistoryAction, HistorySession +from datalab.objectmodel import get_uuid + +if TYPE_CHECKING: + from datalab.gui.panel.history import HistoryPanel + + +def duplicate_selected_entries(panel: HistoryPanel) -> None: + """Duplicate selected sessions (with their data) into new independent sessions. + + For each selected session (or the parent session of a selected action), + all referenced data objects are deep-copied into a new group and the + session is duplicated with all UUID references rewritten to the clones. + The result is an independent, editable and replayable session. + """ + selected = panel.tree.get_selected_actions_or_sessions(panel.history_sessions) + if not selected: + return + # Normalise: resolve individual actions to their parent session, deduplicate. + sessions_to_dup: list[HistorySession] = [] + seen: set[int] = set() + for item in selected: + if isinstance(item, HistorySession): + session = item + else: + session = panel.find_parent_session(item) + if session is None: + continue + if id(session) not in seen: + seen.add(id(session)) + sessions_to_dup.append(session) + + copy_suffix = _("Copy") + new_sessions: list[HistorySession] = [] + panel_map = { + "signal": panel.mainwindow.signalpanel, + "image": panel.mainwindow.imagepanel, + } + + for session in sessions_to_dup: + # 1. Collect all UUIDs referenced by this session + uuids_by_panel: dict[str, set[str]] = {} + for action in session.actions: + for pstr, uuids in action.state.selection.items(): + uuids_by_panel.setdefault(pstr, set()).update(uuids) + for pstr, metadata in action.state.object_metadata.items(): + uuids_by_panel.setdefault(pstr, set()).update(metadata.keys()) + obj2 = action.kwargs.get("obj2_uuids") + if obj2: + pstr = action.panel_str or "" + if isinstance(obj2, str): + obj2 = [obj2] + uuids_by_panel.setdefault(pstr, set()).update(obj2) + # Output UUIDs produced by this action (e.g. result of a + # compute step). Without this, the last action's outputs + # would be missing because no subsequent state captures them. + if action.output_uuids: + pstr = action.panel_str or "" + uuids_by_panel.setdefault(pstr, set()).update(action.output_uuids) + + # 2. Clone objects and build uuid_remap + uuid_remap: dict[str, dict[str, str]] = {} + clones_by_pstr: dict[str, list] = {} + group_title = f"{copy_suffix} - {session.title}" + for pstr, uuids in uuids_by_panel.items(): + data_panel = panel_map.get(pstr) + if data_panel is None: + continue + uuid_remap[pstr] = {} + existing_ids = set(data_panel.objmodel.get_object_ids()) + clones = [] + # Iterate in panel order (not set order) to preserve + # the topological object ordering in the duplicated group. + ordered_ids = [ + u for u in data_panel.objmodel.get_object_ids() if u in uuids + ] + for old_uuid in ordered_ids: + if old_uuid not in existing_ids: + continue + obj = data_panel.objmodel[old_uuid] + clone = deepcopy(obj) + new_uuid = str(uuid4()) + # SignalObj/ImageObj store UUID via metadata option + try: + clone.set_metadata_option("uuid", new_uuid) + except AttributeError: + clone.uuid = new_uuid + uuid_remap[pstr][old_uuid] = new_uuid + clones.append(clone) + clones_by_pstr[pstr] = clones + if clones: + group_id = get_uuid(data_panel.add_group(group_title)) + for clone in clones: + data_panel.add_object(clone, group_id=group_id) + + # Second pass: remap source UUIDs in cloned objects' + # processing_parameters so reprocessing in the Processing tab + # uses the cloned source, not the original. + for pstr_inner, clones_inner in clones_by_pstr.items(): + pmap = uuid_remap.get(pstr_inner, {}) + if not pmap: + continue + for clone in clones_inner: + try: + pp_dict = clone.get_metadata_option(PROCESSING_PARAMETERS_OPTION) + except (AttributeError, ValueError): + continue + if not pp_dict: + continue + try: + pp = ProcessingParameters.from_dict(pp_dict) + except (TypeError, ValueError, AttributeError): + continue + changed = False + if pp.source_uuid is not None and pp.source_uuid in pmap: + pp.source_uuid = pmap[pp.source_uuid] + changed = True + if pp.source_uuids is not None: + new_src = [pmap.get(u, u) for u in pp.source_uuids] + if new_src != pp.source_uuids: + pp.source_uuids = new_src + changed = True + if changed: + try: + clone.set_metadata_option( + PROCESSING_PARAMETERS_OPTION, pp.to_dict() + ) + except (AttributeError, ValueError): + pass + + # 3. Build the new session with remapped UUIDs + panel.session_increment += 1 + title = f"{session.title} {copy_suffix}" + new_session = session.copy_with_uuid_remap(title=title, uuid_remap=uuid_remap) + new_session.number = panel.session_increment + new_sessions.append(new_session) + + # Register output mappings for cloned actions so that + # _resolve_target_outputs / get_downstream_actions work on + # the duplicated session (same logic as read_h5_data). + for action in new_session.actions: + if action.output_uuids: + panel._action_output_uuids[action.uuid] = list(action.output_uuids) + for out_uuid in action.output_uuids: + panel._output_to_action[out_uuid] = action.uuid + + # Insert each duplicated session immediately after its original. + offset = 0 + for original_session, new_session in zip(sessions_to_dup, new_sessions): + idx = panel.history_sessions.index(original_session) + panel.history_sessions.insert(idx + 1 + offset, new_session) + offset += 1 + panel.tree.populate_tree(panel.history_sessions) + panel.select_sessions(new_sessions) + panel.refresh_compatibility_items() + panel.update_actions_state() + + +def generate_macro(panel: HistoryPanel) -> None: + """Generate a standalone Python script from selected history entries. + + The generated script uses sigima functions directly with proper variable + chaining. Object references (UUIDs) are resolved to variable names so + that 2-to-1 operations reference the correct intermediate result. + The script is copied to the clipboard and the user is notified. + """ + selected = panel.tree.get_selected_actions_or_sessions(panel.history_sessions) + actions: list[HistoryAction] = [] + if not selected: + for session in panel.history_sessions: + actions.extend(session.actions) + else: + for item in selected: + if isinstance(item, HistorySession): + actions.extend(item.actions) + else: + actions.append(item) + if not actions: + return + + # Filter to compute-only actions for the pipeline + compute_actions = [a for a in actions if a.kind == HistoryAction.KIND_COMPUTE] + if not compute_actions: + if not execenv.unattended: + QW.QMessageBox.information( + panel.mainwindow, + _("Generate macro"), + _("No compute actions to export."), + ) + return + + # Determine input type from first action + first_panel = compute_actions[0].panel_str + if first_panel == "signal": + obj_type = "SignalObj" + obj_import = "from sigima.objects import SignalObj" + else: + obj_type = "ImageObj" + obj_import = "from sigima.objects import ImageObj" + + imports: set[str] = set() + imports.add(obj_import) + body_lines: list[str] = [] + + # UUID → variable mapping for resolving object references. + # Populated with input UUIDs ("src", "src_2", ...) and enriched + # with each step's output UUID after code generation. + uuid_to_var: dict[str, str] = {} + + # Extra input parameters discovered during generation (second + # operands that are not produced by any previous step). + extra_inputs: list[str] = [] + + # Seed the mapping with the first action's input selection. + first_sel = compute_actions[0].state.selection.get(compute_actions[0].panel_str, []) + for i, uuid in enumerate(first_sel): + var = "src" if i == 0 else f"src_{i + 1}" + uuid_to_var[uuid] = var + + step = 0 + current_var = "src" + + for action in compute_actions: + step += 1 + + # Resolve input variable from the action's selection UUIDs. + sel_uuids = action.state.selection.get(action.panel_str or "", []) + if sel_uuids and sel_uuids[0] in uuid_to_var: + input_var = uuid_to_var[sel_uuids[0]] + else: + input_var = current_var + + # Resolve second operand for 2-to-1 patterns. + obj2_var: str | None = None + if action.pattern == "2_to_1": + obj2_uuids = action.kwargs.get("obj2_uuids", []) + if isinstance(obj2_uuids, str): + obj2_uuids = [obj2_uuids] + if obj2_uuids: + obj2_uuid = obj2_uuids[0] + if obj2_uuid in uuid_to_var: + obj2_var = uuid_to_var[obj2_uuid] + else: + # External input — add as function parameter. + obj2_var = f"obj2_{step}" + uuid_to_var[obj2_uuid] = obj2_var + extra_inputs.append(obj2_var) + + code_lines, output_var = action.to_macro_code( + step, input_var, imports, obj2_var=obj2_var + ) + body_lines.extend(code_lines) + body_lines.append("") + + if output_var is not None: + current_var = output_var + # Map the output UUID so subsequent steps can reference it. + output_uuid = panel.action_output_uuid(action) + if output_uuid: + uuid_to_var[output_uuid] = output_var + # Also register any new UUIDs from the action's selection + # that we haven't seen yet (secondary selections). + for uuid in sel_uuids[1:]: + if uuid not in uuid_to_var: + uuid_to_var[uuid] = input_var + + # Build the function signature with extra inputs. + params_str = f"src: {obj_type}" + for extra in extra_inputs: + params_str += f", {extra}: {obj_type}" + + # Assemble the full script + sorted_imports = sorted(imports) + script_lines: list[str] = [ + '"""', + "DataLab — standalone processing pipeline", + f"Generated from history ({len(compute_actions)} steps)", + '"""', + "", + ] + script_lines.extend(sorted_imports) + script_lines.append("") + script_lines.append("") + script_lines.append(f"def process({params_str}) -> {obj_type}:") + script_lines.append(' """Apply the recorded processing pipeline."""') + for line in body_lines: + script_lines.append(f" {line}" if line else "") + script_lines.append(f" return {current_var}") + script_lines.append("") + script_lines.append("") + script_lines.append('if __name__ == "__main__":') + script_lines.append(" # Standalone execution: run from DataLab's Macro panel.") + script_lines.append(" # Operates on the current object of the target panel.") + script_lines.append(" from datalab.control.proxy import RemoteProxy") + script_lines.append("") + script_lines.append(" proxy = RemoteProxy()") + panel_str = compute_actions[0].panel_str or ( + "signal" if obj_type == "SignalObj" else "image" + ) + script_lines.append(f' proxy.set_current_panel("{panel_str}")') + script_lines.append(" src = proxy.get_object()") + script_lines.append(" if src is None:") + script_lines.append( + f' raise RuntimeError("No current object in panel: {panel_str}")' + ) + if extra_inputs: + n_extra = len(extra_inputs) + script_lines.append( + " _uuids = [u for u in proxy.get_sel_object_uuids() if u != src.uuid]" + ) + script_lines.append(f" if len(_uuids) < {n_extra}:") + script_lines.append(" raise RuntimeError(") + script_lines.append( + f' "Pipeline needs {n_extra} extra selected' + ' object(s) besides the current one"' + ) + script_lines.append(" )") + for idx, extra in enumerate(extra_inputs): + script_lines.append( + f' {extra} = proxy.get_object(_uuids[{idx}], "{panel_str}")' + ) + extra_args = "".join(f", {e}" for e in extra_inputs) + script_lines.append(f" result = process(src{extra_args})") + script_lines.append(" proxy.add_object(result)") + script_lines.append(' print(f"Pipeline applied: {result.title}")') + script_lines.append("") + + script = "\n".join(script_lines) + QW.QApplication.clipboard().setText(script) + if not execenv.unattended: + QW.QMessageBox.information( + panel.mainwindow, + _("Generate macro"), + _("Macro script copied to clipboard (%d actions).") % len(compute_actions), + ) + + +def delete_selected(panel: HistoryPanel) -> None: + """Delete the selected actions or sessions (with confirmation). + + When a top-level session is selected, the entire session is deleted. + When individual actions are selected, they and all subsequent actions + in their parent session are removed. After deletion, the first + available item in the tree is selected automatically. + """ + selected = panel.tree.get_selected_actions_or_sessions(panel.history_sessions) + if not selected: + return + has_individual_actions = any(isinstance(item, HistoryAction) for item in selected) + if has_individual_actions: + msg = _( + "Do you really want to delete the selected items?\n\n" + "Note: deleting an action also removes all subsequent " + "actions in the same session." + ) + else: + msg = _("Do you really want to delete the selected items?") + reply = ( + QW.QMessageBox.Yes + if execenv.unattended + else QW.QMessageBox.question( + panel.mainwindow, + _("Delete"), + msg, + QW.QMessageBox.Yes | QW.QMessageBox.No, + QW.QMessageBox.No, + ) + ) + if reply != QW.QMessageBox.Yes: + return + sessions_to_remove: set[int] = set() + for item in selected: + if isinstance(item, HistorySession): + sessions_to_remove.add(id(item)) + else: + # Individual action: remove from its parent session + for session in panel.history_sessions: + if item in session.actions: + session.remove_action(item) + if not session.actions: + sessions_to_remove.add(id(session)) + break + panel.history_sessions = [ + s for s in panel.history_sessions if id(s) not in sessions_to_remove + ] + panel.tree.populate_tree(panel.history_sessions) + panel.refresh_compatibility_items() + panel.update_actions_state() + # Auto-select the first available item after deletion + if panel.tree.topLevelItemCount() > 0: + first = panel.tree.topLevelItem(0) + panel.tree.setCurrentItem(first) + first.setSelected(True) + + +def remove_incompatible_actions(panel: HistoryPanel) -> None: + """Remove all actions whose workspace state is incompatible. + + Shows a confirmation dialog listing how many actions will be removed, + then purges them from their sessions. Empty sessions are also removed. + """ + incompatible: list[tuple[HistorySession, HistoryAction]] = [] + for session in panel.history_sessions: + for action in session.actions: + if not action.is_current_state_compatible( + panel.mainwindow, restore_selection=True + ): + incompatible.append((session, action)) + if not incompatible: + if not execenv.unattended: + QW.QMessageBox.information( + panel.mainwindow, + _("Remove incompatible"), + _("All actions are compatible with the current workspace."), + ) + return + reply = ( + QW.QMessageBox.Yes + if execenv.unattended + else QW.QMessageBox.question( + panel.mainwindow, + _("Remove incompatible"), + _("%d incompatible action(s) will be removed. Continue?") + % len(incompatible), + QW.QMessageBox.Yes | QW.QMessageBox.No, + QW.QMessageBox.No, + ) + ) + if reply != QW.QMessageBox.Yes: + return + for session, action in incompatible: + if action in session.actions: + session.actions.remove(action) + # Remove empty sessions + panel.history_sessions = [s for s in panel.history_sessions if s.actions] + panel.tree.populate_tree(panel.history_sessions) + panel.refresh_compatibility_items() + panel.update_actions_state() diff --git a/datalab/gui/panel/history.py b/datalab/gui/panel/history.py deleted file mode 100644 index 9d0f45715..000000000 --- a/datalab/gui/panel/history.py +++ /dev/null @@ -1,4933 +0,0 @@ -# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. - -""" -.. History panel (see parent package :mod:`datalab.gui.panel`) -""" - -# pylint: disable=invalid-name # Allows short reference names like x, y, ... - -from __future__ import annotations - -import functools -import html -import inspect -import json -import logging -import os -import os.path as osp -import warnings -from contextlib import contextmanager -from copy import deepcopy -from typing import TYPE_CHECKING, Any, Callable, Generator -from uuid import uuid4 - -import numpy as np -import sigima.proc.image -import sigima.proc.signal -from guidata.configtools import get_icon -from guidata.dataset.conv import dataset_to_json, json_to_dataset -from guidata.dataset.datatypes import DataSet -from guidata.qthelpers import add_actions, create_action -from guidata.widgets.dockable import DockableWidgetMixin -from qtpy import QtCore as QC -from qtpy import QtGui as QG -from qtpy import QtWidgets as QW -from qtpy.compat import getopenfilename, getsavefilename -from sigima.objects import ImageObj, SignalObj - -from datalab.config import Conf, _ -from datalab.gui import ObjItf -from datalab.gui.panel.base import AbstractPanel -from datalab.objectmodel import get_uuid -from datalab.utils.qthelpers import qt_try_loadsave_file, save_restore_stds - -if TYPE_CHECKING: - import guidata.dataset as gds - - from datalab.gui.main import DLMainWindow - from datalab.gui.panel.base import BaseDataPanel - from datalab.gui.processor.base import BaseProcessor, FeatureNotFoundError - from datalab.h5.native import NativeH5Reader, NativeH5Writer - - -# Keys used in the kwargs dict to mark DataSet payloads, so that the -# serialization layer can round-trip them as JSON strings instead of pickling -# arbitrary Python objects. -HISTORY_SCHEMA_VERSION = 1 -# Per-action schema. Bumped to 4 to persist the ``_saved_kwargs`` snapshot -# used by the Edit mode Restore feature: persisting it across save/reload -# lets the user revert edits even after closing and re-opening the session, -# as long as Edit mode has not been definitively committed (toggled off). -# Schema version 3 introduced the ``plugin_origin`` field used to track the -# originating plugin of a compute action (see ``BaseProcessor.add_feature``). -# Sessions/actions with ``schema_version <= 2`` are still supported: the -# loader leaves ``plugin_origin`` as ``None`` and missing-plugin replay -# simply produces a generic ``FeatureNotFoundError`` instead of a -# plugin-aware warning. Schema version 2 introduced the ``output_uuids`` -# field used by the bijective action ↔ output mapping (see -# ``HistoryPanel._output_to_action``). Sessions/actions with -# ``schema_version <= 3`` leave ``_saved_kwargs`` as ``None`` on load -# (no pending edits to restore). -HISTORY_ACTION_SCHEMA_VERSION = 4 -_DATASET_MARKER = "__dataset_json__" -_DATASET_LIST_MARKER = "__dataset_list_json__" -_ROI_MARKER = "__roi_json__" - -_logger = logging.getLogger(__name__) - - -def _numpy_to_json_safe(obj: Any) -> Any: - """Recursively convert numpy arrays to lists for JSON serialization.""" - if isinstance(obj, np.ndarray): - return obj.tolist() - if isinstance(obj, dict): - return {k: _numpy_to_json_safe(v) for k, v in obj.items()} - if isinstance(obj, list): - return [_numpy_to_json_safe(i) for i in obj] - return obj - - -def _encode_roi(roi: Any) -> str: - """Encode a sigima ROI object to a JSON string via ``to_dict()``.""" - from sigima.objects.base import BaseROI # local to avoid circular import - - if not isinstance(roi, BaseROI): - raise TypeError(f"Expected BaseROI instance, got {type(roi)!r}") - roi_dict = _numpy_to_json_safe(roi.to_dict()) - # Store the concrete class so we can reconstruct on decode. - payload = { - "module": type(roi).__module__, - "class": type(roi).__qualname__, - "data": roi_dict, - } - return json.dumps(payload) - - -def _decode_roi(encoded: str) -> Any: - """Decode a JSON string back to a sigima ROI object. - - Only classes from trusted ``sigima.`` modules that are actual - :class:`sigima.objects.base.BaseROI` subclasses are allowed. - - Raises: - ValueError: If the module is not a trusted sigima module or the - resolved class is not a BaseROI subclass. - """ - import importlib - - from sigima.objects.base import BaseROI # local to avoid circular import - - _TRUSTED_ROI_MODULE_PREFIX = "sigima." - - payload = json.loads(encoded) - module_name = payload["module"] - class_name = payload["class"] - - if not module_name.startswith(_TRUSTED_ROI_MODULE_PREFIX): - raise ValueError( - f"Untrusted ROI module {module_name!r}: " - f"only modules under {_TRUSTED_ROI_MODULE_PREFIX!r} are allowed" - ) - - mod = importlib.import_module(module_name) - cls = getattr(mod, class_name) - - if not (isinstance(cls, type) and issubclass(cls, BaseROI)): - raise ValueError( - f"{module_name}.{class_name} is not a BaseROI subclass" - ) - - return cls.from_dict(payload["data"]) - - -def _encode_kwargs(kwargs: dict[str, Any]) -> dict[str, Any]: - """Encode kwargs for HDF5 storage: replace ``DataSet``, ``list[DataSet]``, - and sigima ROI values with marker dicts holding their JSON representation. - - All other values must already be HDF5-friendly primitives (str, int, float, - bool, list/tuple of the same). - - Args: - kwargs: Raw kwargs dict (may contain ``DataSet`` or ROI instances). - - Returns: - A new dict with special values wrapped in marker dicts. - """ - from sigima.objects.base import BaseROI # local to avoid circular import - - encoded: dict[str, Any] = {} - for key, value in kwargs.items(): - if value is None: - continue - if isinstance(value, DataSet): - encoded[key] = {_DATASET_MARKER: dataset_to_json(value)} - elif isinstance(value, BaseROI): - encoded[key] = {_ROI_MARKER: _encode_roi(value)} - elif ( - isinstance(value, list) - and value - and all(isinstance(item, DataSet) for item in value) - ): - encoded[key] = { - _DATASET_LIST_MARKER: [dataset_to_json(item) for item in value] - } - else: - encoded[key] = value - return encoded - - -def _decode_kwargs(kwargs: dict[str, Any]) -> dict[str, Any]: - """Inverse of :func:`_encode_kwargs`.""" - decoded: dict[str, Any] = {} - for key, value in kwargs.items(): - if isinstance(value, dict) and _DATASET_MARKER in value: - try: - decoded[key] = json_to_dataset(value[_DATASET_MARKER]) - except Exception: # pylint: disable=broad-except - warnings.warn( - _("Failed to deserialize history DataSet kwarg %r.") % key - ) - decoded[key] = None - elif isinstance(value, dict) and _ROI_MARKER in value: - try: - decoded[key] = _decode_roi(value[_ROI_MARKER]) - except Exception as exc: - raise ValueError( - f"Failed to deserialize history ROI kwarg {key!r}: {exc}" - ) from exc - elif isinstance(value, dict) and _DATASET_LIST_MARKER in value: - try: - decoded[key] = [ - json_to_dataset(item) for item in value[_DATASET_LIST_MARKER] - ] - except Exception: # pylint: disable=broad-except - warnings.warn( - _("Failed to deserialize history DataSet-list kwarg %r.") % key - ) - decoded[key] = [] - else: - decoded[key] = value - return decoded - - -def _copy_history_value(value: Any) -> Any: - """Return an independent copy of a history-serializable value.""" - from sigima.objects.base import BaseROI # local to avoid circular import - - if callable(value): - raise TypeError("History duplication does not support callable kwargs") - if isinstance(value, DataSet): - return json_to_dataset(dataset_to_json(value)) - if isinstance(value, BaseROI): - return _decode_roi(_encode_roi(value)) - if isinstance(value, dict): - return {key: _copy_history_value(item) for key, item in value.items()} - if isinstance(value, list): - return [_copy_history_value(item) for item in value] - if isinstance(value, tuple): - return tuple(_copy_history_value(item) for item in value) - return deepcopy(value) - - -def get_datetime_str() -> str: - """Return current date and time as a string""" - return QC.QDateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss") - - -def add_to_history(kwargs_names: list[str] | None = None, title: str | None = None): - """Method decorator to add the method call to the history panel as a UI entry. - - Args: - kwargs_names: List of keyword arguments to add to the history action. - Defaults to None. - title: Title of the history action. Defaults to None. - """ - if kwargs_names is None: - kwargs_names = [] - - def add_to_history_decorator(func): - """Decorator function""" - - @functools.wraps(func) - def method_wrapper(*args, **kwargs): - """Decorator wrapper function""" - self: BaseDataPanel | BaseProcessor = args[0] - history: HistoryPanel = self.mainwindow.historypanel - histkwargs = {k: kwargs[k] for k in kwargs_names if k in kwargs} - target = _resolve_self_target(self) - if target is not None: - history.add_ui_entry( - kwargs.get("title", title) or func.__name__, - target=target, - method_name=func.__name__, - save_state=kwargs.get("save_state", True), - **histkwargs, - ) - return func(*args, **kwargs) - - return method_wrapper - - return add_to_history_decorator - - -def _resolve_self_target(self_obj: Any) -> str | None: - """Resolve a 'self' instance to a string target understood by replay. - - Used by the legacy ``@add_to_history`` decorator. Returns None when no - safe routing is possible (in which case the entry is skipped). - """ - panel_str = getattr(self_obj, "PANEL_STR_ID", None) - if panel_str == "signal": - return "signalpanel" - if panel_str == "image": - return "imagepanel" - return None - - -# --------------------------------------------------------------------------- -# HistoryAction -# --------------------------------------------------------------------------- - - -class HistoryAction(ObjItf): - """Object representing an action in the history panel. - - An action is a serialisable description of either a *compute* call (resolved - via the panel processor's feature registry) or a *UI* call (resolved as a - method on a known target -- ``mainwindow``/``signalpanel``/``imagepanel``). - - No Python ``Callable`` is ever pickled: a compute action is identified by - ``(panel_str, func_name, pattern)`` and a UI action by ``(target, - method_name)``. ``DataSet`` payloads inside ``kwargs`` are serialised with - :func:`guidata.dataset.conv.dataset_to_json`. - """ - - KIND_COMPUTE = "compute" - KIND_UI = "ui" - - FUNC_EDIT_MODE = "edit" # Name of the function parameter to enable edit mode - # Methods that create new data objects. During non-persistent (output-suppressed) - # replay, these UI actions are skipped so the panel object count stays stable. - UI_CREATION_METHODS: frozenset[str] = frozenset({"new_object"}) - - def __init__( - self, - title: str = "", - kind: str = KIND_UI, - # --- compute-only -------------------------------------------------- - panel_str: str | None = None, - func_name: str | None = None, - pattern: str | None = None, - # --- ui-only ------------------------------------------------------- - target: str | None = None, - method_name: str | None = None, - # --- common -------------------------------------------------------- - kwargs: dict[str, Any] | None = None, - state: WorkspaceState | None = None, - plugin_origin: dict[str, Any] | None = None, - ) -> None: - super().__init__() - self.__title = title or "" - self.kind = kind - # Compute kind: - self.panel_str = panel_str - self.func_name = func_name - self.pattern = pattern - # UI kind: - self.target = target - self.method_name = method_name - # Common: - self.kwargs: dict[str, Any] = ( - {} if kwargs is None else {k: v for k, v in kwargs.items() if v is not None} - ) - self.state = WorkspaceState() if state is None else state - self.dtstr: str = get_datetime_str() - self.uuid: str = str(uuid4()) - self.schema_version: int = HISTORY_ACTION_SCHEMA_VERSION - # UUIDs of the data objects produced by this action (bijective mapping - # maintained by :class:`HistoryPanel`). Populated post-compute via - # :meth:`HistoryPanel.register_action_outputs`. Empty for ``1_to_0`` - # patterns, for UI actions, and for legacy (schema_version=1) sessions - # loaded from disk (the heuristic fallback then takes over). - self.output_uuids: list[str] = [] - # Plugin origin descriptor for compute actions (None for built-in - # Sigima/DataLab features). Populated at registration time by - # :meth:`BaseProcessor.add_feature` and propagated through - # ``add_compute_entry_from_pp``. See - # :func:`datalab.gui.processor.base._detect_plugin_origin` for shape. - # Persisted as a JSON string in HDF5 (schema_version >= 3). - self.plugin_origin: dict[str, Any] | None = plugin_origin - # Transient flag (NOT serialized): set during a cascade recompute to - # display a "stale" visual marker in the tree. Cleared once the - # action has been recomputed. - self.is_stale: bool = False - # Snapshot of original kwargs before edit-mode modification. - # Set lazily when the first edit-mode change touches this action. - # Persisted to HDF5 (schema_version >= 4) so that the Restore - # action still works after a save/reload cycle while Edit mode is - # active. Cleared by ``discard_snapshot`` (definitive commit when - # toggling Edit mode off) or ``restore_kwargs`` (Restore button). - self._saved_kwargs: dict[str, Any] | None = None - - def snapshot_kwargs(self) -> None: - """Save a copy of the current kwargs as the pre-edit baseline. - - No-op if a snapshot already exists (preserves the original baseline - across multiple edit-mode replays). - """ - if self._saved_kwargs is None: - self._saved_kwargs = { - key: _copy_history_value(value) - for key, value in self.kwargs.items() - } - - def restore_kwargs(self) -> None: - """Restore kwargs from the saved snapshot and clear the snapshot.""" - if self._saved_kwargs is not None: - self.kwargs = self._saved_kwargs - self._saved_kwargs = None - - def discard_snapshot(self) -> None: - """Discard the saved snapshot (accept current kwargs as definitive).""" - self._saved_kwargs = None - - @property - def has_pending_edits(self) -> bool: - """Return True if this action has unsaved edit-mode changes.""" - return self._saved_kwargs is not None - - def regenerate_uuid(self): - """Regenerate UUID after loading from a file (no-op: per-action UUID).""" - - def copy(self, title_suffix: str | None = None) -> HistoryAction: - """Return an independent copy of this history action.""" - state = self.state.copy() - title = self.title - if title_suffix: - title = f"{title} {title_suffix}" - new_action = HistoryAction( - title=title, - kind=self.kind, - panel_str=self.panel_str, - func_name=self.func_name, - pattern=self.pattern, - target=self.target, - method_name=self.method_name, - kwargs={ - key: _copy_history_value(value) - for key, value in self.kwargs.items() - }, - state=state, - ) - new_action.output_uuids = list(self.output_uuids) - # Note: _saved_kwargs is intentionally NOT propagated to the copy. - # Copying an action acts as an implicit commit (no pending edits). - return new_action - - def copy_with_uuid_remap( - self, uuid_remap: dict[str, dict[str, str]] - ) -> HistoryAction: - """Return a copy of this action with all captured UUIDs rewritten. - - Args: - uuid_remap: Per-panel mapping ``{panel_str: {old_uuid: new_uuid}}`` - used to translate captured UUIDs to the cloned objects created by - the Duplicate operation. - - Returns: - A new independent :class:`HistoryAction` with remapped UUIDs. - """ - new_action = self.copy() - # Rewrite state.selection - for pstr, uuids in new_action.state.selection.items(): - pmap = uuid_remap.get(pstr, {}) - new_action.state.selection[pstr] = [pmap.get(u, u) for u in uuids] - # Rewrite state.object_metadata keys - for pstr, metadata in new_action.state.object_metadata.items(): - pmap = uuid_remap.get(pstr, {}) - new_action.state.object_metadata[pstr] = { - pmap.get(uuid, uuid): val for uuid, val in metadata.items() - } - # Rewrite obj2_uuids in kwargs - obj2 = new_action.kwargs.get("obj2_uuids") - if obj2: - if isinstance(obj2, str): - obj2 = [obj2] - pstr = new_action.panel_str or "" - pmap = uuid_remap.get(pstr, {}) - rewritten = [pmap.get(u, u) for u in obj2] - new_action.kwargs["obj2_uuids"] = ( - rewritten[0] if len(rewritten) == 1 else rewritten - ) - # Rewrite output_uuids — they reference the target panel. - if new_action.output_uuids: - pstr = new_action.panel_str or "" - pmap = uuid_remap.get(pstr, {}) - new_action.output_uuids = [ - pmap.get(u, u) for u in new_action.output_uuids - ] - return new_action - - @property - def title(self) -> str: - """Return object title""" - return self.__title - - # ------------------------------------------------------------------ - # Description rendering (used by the tree view) - # ------------------------------------------------------------------ - - def __iter_param_kwargs(self) -> Generator[Any, None, None]: - """Yield kwargs values whose name ends with ``param`` (typically DataSets).""" - for kwname, value in self.kwargs.items(): - if kwname.endswith("param") and value is not None: - yield value - - @property - def description(self) -> str: - """Return object description (string representing function parameters)""" - desc = "" - no_parameters = True - for param in self.__iter_param_kwargs(): - if desc: - desc += os.linesep - desc += str(param) - no_parameters = False - if desc or no_parameters: - if desc: - return desc - # Fall back to a textual hint of the resolved callable - return self.__fallback_doc() - - def __fallback_doc(self) -> str: - """Return a single-line docstring for the underlying call, if available.""" - try: - func = self._resolve_callable() - except Exception: # pylint: disable=broad-except - return "" - doc = getattr(func, "__doc__", None) or "" - return doc.splitlines()[0] if doc else "" - - @property - def description_summary(self) -> str: - """Return a short, single-line summary of the description (collapsed view). - - For DataSet parameters, uses the dataset title followed by a compact - representation of its public fields ("name=value, ..."). Falls back to - the first non-empty line of the full description when no DataSet is - present. - """ - summaries: list[str] = [] - for param in self.__iter_param_kwargs(): - if isinstance(param, DataSet): - title = param.get_title() or "" - # Collect "name=value" for each non-private item of the DataSet. - pairs: list[str] = [] - for item in param.get_items(): - name = item.get_name() - if name.startswith("_"): - continue - try: - value = item.get_value(param) - except Exception: # pylint: disable=broad-except - continue - # Format floats compactly, leave other reprs as-is - if isinstance(value, float): - value_str = f"{value:g}" - else: - value_str = str(value) - pairs.append(f"{name}={value_str}") - if pairs: - summaries.append( - f"{title}: {', '.join(pairs)}" if title else ", ".join(pairs) - ) - elif title: - summaries.append(title) - if summaries: - return " | ".join(summaries) - for line in self.description.splitlines(): - stripped = line.strip() - if stripped: - return stripped - return "" - - @property - def description_html(self) -> str: - """Return rich-text (HTML) description used for the expanded view.""" - # Normal path - parts: list[str] = [] - no_parameters = True - for param in self.__iter_param_kwargs(): - no_parameters = False - if isinstance(param, DataSet): - parts.append(param.to_html()) - else: - parts.append(html.escape(str(param)).replace("\n", "<br>")) - if parts: - return "<br><br>".join(parts) - if no_parameters: - text = self.description - if not text: - return "" - return html.escape(text).replace("\n", "<br>") - return "" - - def to_macro_code( - self, - step_index: int, - input_var: str, - imports: set[str], - obj2_var: str | None = None, - ) -> tuple[list[str], str | None]: - """Return Python source lines for this action as a standalone sigima call. - - Args: - step_index: Step number for variable naming. - input_var: Name of the input variable from the previous step. - imports: Mutable set of import statements accumulated by the caller. - obj2_var: Resolved variable name for the second operand (2-to-1 - pattern). When ``None``, the second operand is left as a - placeholder. - - Returns: - Tuple of (code_lines, output_var_name). ``output_var_name`` is - ``None`` for UI-kind actions (no data output). - """ - if self.kind != self.KIND_COMPUTE: - return [f"# (UI) {self.title} [skipped]"], None - - lines: list[str] = [] - output_var = f"result_{step_index}" - - # Determine the sigima module alias - if self.panel_str == "signal": - mod_alias = "sips" - imports.add("import sigima.proc.signal as sips") - elif self.panel_str == "image": - mod_alias = "sipi" - imports.add("import sigima.proc.image as sipi") - else: - lines.append( - f"# {self.title} [unknown panel: {self.panel_str}]" - ) - return lines, None - - lines.append(f"# Step {step_index}: {self.title}") - - param = self.kwargs.get("param") - param_var: str | None = None - - if param is not None and isinstance(param, DataSet): - param_var = f"param_{step_index}" - param_class = type(param).__qualname__ - param_module = type(param).__module__ - imports.add(f"from {param_module} import {param_class}") - lines.append(f"{param_var} = {param_class}()") - # Reconstruct each attribute - for item in param._items: # noqa: SLF001 - attr_name = item._name # noqa: SLF001 - value = getattr(param, attr_name, None) - if value is not None: - lines.append( - f"{param_var}.{attr_name} = {value!r}" - ) - - # Build the function call - func_call = f"{mod_alias}.{self.func_name}" - if self.pattern in ("1_to_1", "1_to_0"): - if param_var: - lines.append( - f"{output_var} = {func_call}" - f"({input_var}, {param_var})" - ) - else: - lines.append( - f"{output_var} = {func_call}({input_var})" - ) - elif self.pattern == "n_to_1": - if param_var: - lines.append( - f"{output_var} = {func_call}" - f"([{input_var}], {param_var})" - ) - else: - lines.append( - f"{output_var} = {func_call}([{input_var}])" - ) - elif self.pattern == "2_to_1": - second = obj2_var or "... # TODO: provide second operand" - if param_var: - lines.append( - f"{output_var} = {func_call}" - f"({input_var}, {second}, {param_var})" - ) - else: - lines.append( - f"{output_var} = {func_call}" - f"({input_var}, {second})" - ) - elif self.pattern == "1_to_n": - lines.append( - f"{output_var} = {func_call}({input_var})" - ) - else: - lines.append(f"# Unknown pattern {self.pattern!r}") - return lines, None - - return lines, output_var - - # ------------------------------------------------------------------ - # Workspace-state delegation - # ------------------------------------------------------------------ - - def is_current_state_compatible( - self, mainwindow: DLMainWindow, restore_selection: bool - ) -> bool: - """Check if the current workspace state is compatible with the saved state.""" - return self.state.is_current_state_compatible(mainwindow, restore_selection) - - def restore(self, mainwindow: DLMainWindow) -> None: - """Restore the associated workspace state.""" - self.state.restore(mainwindow) - - # ------------------------------------------------------------------ - # Replay - # ------------------------------------------------------------------ - - def _resolve_target(self, mainwindow: DLMainWindow) -> Any: - """Resolve the target object (UI kind) from the mainwindow.""" - attr = self.target or "mainwindow" - if attr == "mainwindow": - return mainwindow - return getattr(mainwindow, attr) - - def _resolve_panel(self, mainwindow: DLMainWindow): - """Resolve the data panel for a compute action.""" - if self.panel_str == "signal": - return mainwindow.signalpanel - if self.panel_str == "image": - return mainwindow.imagepanel - raise ValueError( - f"Unknown panel_str {self.panel_str!r} for compute history action" - ) - - def _resolve_callable(self) -> Callable | None: - """Best-effort lookup of the underlying callable, for description only.""" - if self.kind == self.KIND_COMPUTE and self.func_name: - for module in (sigima.proc.signal, sigima.proc.image): - func = getattr(module, self.func_name, None) - if callable(func): - return func - return None - - def _resolve_obj_by_uuid(self, mainwindow: DLMainWindow, uuid: str) -> Any | None: - """Look up an object by UUID across both data panels.""" - for panel in (mainwindow.signalpanel, mainwindow.imagepanel): - try: - return panel.objmodel[uuid] - except KeyError: - continue - return None - - def replay( - self, - mainwindow: DLMainWindow, - restore_selection: bool, - edit: bool, - uuid_remap: dict[str, dict[str, str]] | None = None, - ) -> None: - """Replay the action. - - Args: - mainwindow: DataLab's main window - restore_selection: True to restore the workspace selection before replaying - a UI-kind action. Ignored for compute-kind actions: their semantics - depends on which objects are selected (e.g. ``n_to_1`` aggregators - such as ``average`` require their captured multi-object selection), - so the captured selection is always restored before running the - computation. - edit: if True, always open the dialog boxes to edit parameters; if False, - use the parameters captured when the action was recorded - uuid_remap: optional per-panel mapping ``{panel_str: {old_uuid: new_uuid}}`` - used during full-session replay to translate captured UUIDs to the - freshly-created ones. Defaults to an empty (identity) mapping. - """ - if uuid_remap is None: - uuid_remap = {} - # Suppress history capture during replay to avoid recording - # synthetic entries when the processor re-executes features. - # The context manager is reentrant, so nesting with - # HistoryPanel.replay_restore_actions() is safe. - hpanel = getattr(mainwindow, "historypanel", None) - if hpanel is not None: - ctx = hpanel.replaying() - else: - from contextlib import nullcontext - - ctx = nullcontext() - with ctx: - self._replay_inner(mainwindow, restore_selection, edit, uuid_remap) - - def _replay_inner( - self, - mainwindow: DLMainWindow, - restore_selection: bool, - edit: bool, - uuid_remap: dict[str, dict[str, str]], - ) -> None: - """Inner replay logic, always called under the replaying guard.""" - if self.kind == self.KIND_COMPUTE: - # Compute actions are selection-driven: restore the captured - # selection (translated through ``uuid_remap`` for session - # replays) whenever it is still resolvable so chained replays - # (especially ``n_to_1`` / ``2_to_1`` / ``1_to_n`` patterns) - # operate on the original input objects rather than on whatever - # the previous action left selected. When the captured UUIDs no - # longer exist (e.g. heuristic remap missed an object), fall - # back to the current selection -- replay may still fail - # downstream, but with the native processor error rather than - # an opaque ``WorkspaceState`` incompatibility. - translated = self._translate_state(uuid_remap) - if translated.is_current_state_compatible(mainwindow, False): - translated.restore(mainwindow) - self._replay_compute(mainwindow, edit, uuid_remap) - else: - if restore_selection: - self.state.restore(mainwindow) - self._replay_ui(mainwindow, edit) - - def _translate_state(self, uuid_remap: dict[str, dict[str, str]]) -> WorkspaceState: - """Return a copy of ``self.state`` whose captured UUIDs have been - translated through ``uuid_remap`` (identity when no mapping).""" - if not uuid_remap: - return self.state - translated = WorkspaceState() - for panel_str, uuids in self.state.selection.items(): - panel_map = uuid_remap.get(panel_str, {}) - translated.selection[panel_str] = [panel_map.get(u, u) for u in uuids] - translated.states = dict(self.state.states) - translated.titles = dict(self.state.titles) - for panel_str, metadata in self.state.object_metadata.items(): - panel_map = uuid_remap.get(panel_str, {}) - translated.object_metadata[panel_str] = { - panel_map.get(uuid, uuid): dict(signature) - for uuid, signature in metadata.items() - } - return translated - - def _replay_compute( - self, - mainwindow: DLMainWindow, - edit: bool, - uuid_remap: dict[str, dict[str, str]] | None = None, - ) -> None: - """Replay a compute-kind action via ``processor.run_feature``.""" - if self.pattern == "multiple_1_to_1": - raise NotImplementedError( - _("Replaying compound 'multiple_1_to_1' actions is not supported yet.") - ) - panel = self._resolve_panel(mainwindow) - processor = panel.processor - feature = processor.get_feature(self.func_name) - run_kwargs: dict[str, Any] = {self.FUNC_EDIT_MODE: edit} - - param = self.kwargs.get("param") - if self.pattern in {"1_to_1", "1_to_0", "n_to_1"}: - if param is not None: - run_kwargs["param"] = param - if self.pattern == "n_to_1" and "pairwise" in self.kwargs: - run_kwargs["pairwise"] = self.kwargs["pairwise"] - elif self.pattern == "2_to_1": - uuids = self.kwargs.get("obj2_uuids") or [] - if isinstance(uuids, str): - uuids = [uuids] - # Translate captured UUIDs through ``uuid_remap`` (session replay). - # ``uuid_remap`` keys are ``panel.PANEL_STR_ID`` (matches - # ``WorkspaceState.selection`` keys and - # ``HistoryAction.panel_str``). - panel_map = (uuid_remap or {}).get(panel.PANEL_STR_ID, {}) - uuids = [panel_map.get(u, u) for u in uuids] - objs2 = [ - obj - for obj in (self._resolve_obj_by_uuid(mainwindow, u) for u in uuids) - if obj is not None - ] - if not objs2: - raise ValueError( - _("Cannot replay 2-to-1 action: source object(s) missing.") - ) - run_kwargs["obj2"] = objs2[0] if len(objs2) == 1 else objs2 - if param is not None: - run_kwargs["param"] = param - if "pairwise" in self.kwargs: - run_kwargs["pairwise"] = self.kwargs["pairwise"] - elif self.pattern == "1_to_n": - params = self.kwargs.get("params") or [] - run_kwargs["params"] = params - else: - raise ValueError(f"Unknown compute pattern: {self.pattern!r}") - processor.run_feature(feature, **run_kwargs) - - def _replay_ui(self, mainwindow: DLMainWindow, edit: bool) -> None: - """Replay a UI-kind action by calling ``target.method_name(**kwargs)``.""" - hpanel = mainwindow.historypanel - if ( - hpanel is not None - and hpanel.is_output_suppressed() - and self.method_name in self.UI_CREATION_METHODS - ): - return # Skip creation UI during non-persistent replay - target = self._resolve_target(mainwindow) - # Safety guard for destructive UI actions: if the action would delete - # objects but the captured selection no longer resolves to existing - # UUIDs in the target panel, skip the call rather than delete whatever - # is currently selected (which would silently destroy unrelated data). - DESTRUCTIVE_METHODS = {"remove_object", "remove_group", "delete_all_objects"} - if self.method_name in DESTRUCTIVE_METHODS: - if target is None: - _logger.warning( - "Skipping destructive replay '%s': target '%s' not found", - self.method_name, self.target, - ) - return - panel_str = getattr(target, "PANEL_STR_ID", None) - if panel_str and self.state and self.state.selection.get(panel_str): - existing_uuids = { - get_uuid(o) - for o in getattr(target, "objmodel", []) - if o is not None - } - captured = set(self.state.selection.get(panel_str, [])) - if not (captured & existing_uuids): - _logger.warning( - "Skipping destructive replay '%s': none of the captured " - "UUIDs %s exist in panel '%s' anymore", - self.method_name, list(captured), panel_str, - ) - return - method = getattr(target, self.method_name) - call_kwargs = dict(self.kwargs) - # Inject edit mode if the method supports it - try: - sig = inspect.signature(method) - if self.FUNC_EDIT_MODE in sig.parameters: - call_kwargs[self.FUNC_EDIT_MODE] = edit - except (TypeError, ValueError): - pass - method(**call_kwargs) - - # ------------------------------------------------------------------ - # Serialisation -- no Callable is ever pickled - # ------------------------------------------------------------------ - - def serialize(self, writer: NativeH5Writer) -> None: - """Serialize this action.""" - with writer.group("schema_version"): - writer.write(self.schema_version) - with writer.group("kind"): - writer.write(self.kind) - with writer.group("title"): - writer.write(self.__title) - if self.panel_str is not None: - with writer.group("panel_str"): - writer.write(self.panel_str) - if self.func_name is not None: - with writer.group("func_name"): - writer.write(self.func_name) - if self.pattern is not None: - with writer.group("pattern"): - writer.write(self.pattern) - if self.target is not None: - with writer.group("target"): - writer.write(self.target) - if self.method_name is not None: - with writer.group("method_name"): - writer.write(self.method_name) - encoded = _encode_kwargs(self.kwargs) - if encoded: - with writer.group("kwargs"): - writer.write_dict(encoded) - # ``saved_kwargs`` (schema_version >= 4): persisted Edit mode - # snapshot so the Restore button keeps working after save/reload. - # Skipped (group omitted) when no pending edits exist, keeping the - # on-disk layout byte-identical to schema v3 in the common case. - if self._saved_kwargs is not None: - encoded_saved = _encode_kwargs(self._saved_kwargs) - # Write the group unconditionally (even when empty) so that the - # round-trip preserves the distinction between None (no pending - # edits) and {} (degenerate empty snapshot, keeps has_pending_edits). - with writer.group("saved_kwargs"): - writer.write_dict(encoded_saved) - # Only emit ``output_uuids`` when non-empty: the schema_version field - # already distinguishes v2 (with bijective mapping) from legacy v1. - # Empty lists are skipped to avoid h5py edge cases with empty arrays. - if self.output_uuids: - with writer.group("output_uuids"): - writer.write(list(self.output_uuids)) - # ``plugin_origin`` (schema_version >= 3): stored as a JSON string so - # the HDF5 schema stays trivially round-trippable. Skipped when None - # to keep built-in-only sessions byte-identical to schema v2. - if self.plugin_origin is not None: - with writer.group("plugin_origin"): - writer.write(json.dumps(self.plugin_origin)) - with writer.group("state"): - self.state.serialize(writer) - with writer.group("dtstr"): - writer.write(self.dtstr) - - def deserialize(self, reader: NativeH5Reader) -> None: - """Deserialize this action.""" - self.schema_version = reader.read( - "schema_version", default=HISTORY_SCHEMA_VERSION - ) - with reader.group("kind"): - self.kind = reader.read_any() - with reader.group("title"): - self.__title = reader.read_any() - # Optional descriptors are written conditionally; check existence in - # the underlying HDF5 group before reading to avoid leaking ``__seq`` - # frames on the option stack via guidata's read_any fallback path. - current = reader.h5 - for option in reader.option: - current = current.require_group(option) - for attr in ("panel_str", "func_name", "pattern", "target", "method_name"): - if attr in current.attrs or attr in current: - with reader.group(attr): - setattr(self, attr, reader.read_any()) - else: - setattr(self, attr, None) - if "kwargs" in current.attrs or "kwargs" in current: - with reader.group("kwargs"): - raw = reader.read_dict() - self.kwargs = _decode_kwargs(raw) - else: - self.kwargs = {} - # ``saved_kwargs`` was introduced in schema_version=4. Legacy - # actions (v1, v2, v3) leave it as ``None`` — no Edit mode - # snapshot to restore. - if "saved_kwargs" in current.attrs or "saved_kwargs" in current: - with reader.group("saved_kwargs"): - raw_saved = reader.read_dict() - self._saved_kwargs = _decode_kwargs(raw_saved) - else: - self._saved_kwargs = None - # ``output_uuids`` was introduced in schema_version=2. Legacy actions - # leave it empty; consumers fall back to the heuristic matcher. - if "output_uuids" in current.attrs or "output_uuids" in current: - with reader.group("output_uuids"): - raw_outputs = reader.read_any() - if raw_outputs is None: - self.output_uuids = [] - else: - self.output_uuids = [str(u) for u in raw_outputs] - else: - self.output_uuids = [] - # ``plugin_origin`` was introduced in schema_version=3. Legacy actions - # (v1, v2) leave it as ``None``: a subsequent replay of a missing - # plugin function will then surface a generic ``FeatureNotFoundError`` - # instead of the richer plugin-aware warning. - if "plugin_origin" in current.attrs or "plugin_origin" in current: - with reader.group("plugin_origin"): - raw_origin = reader.read_any() - if raw_origin in (None, ""): - self.plugin_origin = None - else: - try: - self.plugin_origin = json.loads(raw_origin) - except (TypeError, ValueError): - _logger.warning( - "Failed to decode plugin_origin for action %s; " - "falling back to None.", - self.uuid, - ) - self.plugin_origin = None - else: - self.plugin_origin = None - with reader.group("state"): - self.state.deserialize(reader) - with reader.group("dtstr"): - self.dtstr = reader.read_any() - - -class WorkspaceState: - """Object representing the workspace state at a given time. - - The workspace state stores the per-panel selection of objects by **UUID** - (robust against reordering, renaming or interleaved insertions). For - informative display, it also retains the data shape and title of each - selected object at the time of capture. - """ - - def __init__(self) -> None: - """Create a new workspace state""" - # The selection is stored as a dictionary where the key is the panel name - # and the value is the list of UUIDs of selected objects. - self.selection: dict[str, list[str]] = {} - # The states are stored as a dictionary where the key is the panel name - # and the value is the list of states (str) of the objects in the panel. The - # state is a string containing the object data shape (kept for informative - # display only -- not used for selection matching anymore). - self.states: dict[str, list[str]] = {} - # The titles are stored as a dictionary where the key is the panel name and the - # value is the list of titles of the objects in the panel. The title is only - # informative and is not used to determine if two objects have the same state. - self.titles: dict[str, list[str]] = {} - # Structured data signatures of selected objects, keyed by panel name and UUID. - # This is the current schema used for compatibility checks. Missing metadata - # means a pre-Gate-2 history and falls back to UUID-existence validation. - self.object_metadata: dict[str, dict[str, dict[str, Any]]] = {} - - def copy(self) -> WorkspaceState: - """Return an independent copy of this workspace state.""" - state = WorkspaceState() - state.selection = deepcopy(self.selection) - state.states = deepcopy(self.states) - state.titles = deepcopy(self.titles) - state.object_metadata = deepcopy(self.object_metadata) - return state - - def serialize(self, writer: NativeH5Writer) -> None: - """Serialize this workspace state - - Args: - writer: Writer - """ - with writer.group("selection"): - writer.write_dict(self.selection) - with writer.group("states"): - writer.write_dict(self.states) - with writer.group("titles"): - writer.write_dict(self.titles) - with writer.group("object_metadata"): - writer.write_dict(self.object_metadata) - - def deserialize(self, reader: NativeH5Reader) -> None: - """Deserialize this workspace state - - Args: - reader: Reader - """ - with reader.group("selection"): - self.selection = reader.read_dict() - with reader.group("states"): - self.states = reader.read_dict() - with reader.group("titles"): - self.titles = reader.read_dict() - current = reader.h5 - for option in reader.option: - current = current[option] - if "object_metadata" in current.attrs or "object_metadata" in current: - with reader.group("object_metadata"): - self.object_metadata = reader.read_dict() - else: - self.object_metadata = {} - # Normalize legacy translated keys to stable panel identifiers. - self.selection = self._normalize_panel_keys(self.selection) - self.states = self._normalize_panel_keys(self.states) - self.titles = self._normalize_panel_keys(self.titles) - self.object_metadata = self._normalize_panel_keys(self.object_metadata) - - def get_current_selection(self, mainwindow: DLMainWindow) -> dict[str, list[str]]: - """Get the current selection in the workspace, keyed by panel name and - valued by the list of selected object UUIDs. - - Args: - mainwindow: DataLab's main window - - Returns: - Current selection in the workspace, by panel name → list of UUIDs. - """ - selection: dict[str, list[str]] = {} - for panel in (mainwindow.signalpanel, mainwindow.imagepanel): - selection[panel.PANEL_STR_ID] = [ - get_uuid(obj) - for obj in panel.objview.get_sel_objects(include_groups=True) - ] - return selection - - @staticmethod - def get_object_metadata(obj: Any) -> dict[str, Any]: - """Return a stable data signature for an object.""" - data = getattr(obj, "data", None) - shape = getattr(data, "shape", None) - if shape is None: - return {} - shape = [int(size) for size in shape] - ndim = getattr(data, "ndim", len(shape)) - return {"shape": shape, "ndim": int(ndim)} - - @staticmethod - def _normalize_object_metadata(metadata: dict[str, Any]) -> dict[str, Any]: - """Normalize object metadata loaded from HDF5 for comparison.""" - shape = metadata.get("shape") - if shape is None: - return {} - shape = [int(size) for size in shape] - ndim = metadata.get("ndim", len(shape)) - return {"shape": shape, "ndim": int(ndim)} - - # Mapping from legacy translated panel keys to stable identifiers. - # Covers the English translations; other locales are handled by the - # catch-all ``"signal"``/``"image"`` substring heuristic below. - _LEGACY_PANEL_KEY_MAP: dict[str, str] = { - "Signal Panel": "signal", - "Image Panel": "image", - } - - @classmethod - def _normalize_panel_key(cls, key: str) -> str: - """Map a potentially translated panel key to its stable identifier.""" - if key in ("signal", "image"): - return key - mapped = cls._LEGACY_PANEL_KEY_MAP.get(key) - if mapped is not None: - return mapped - # Heuristic for non-English translations: look for the stable ID - # substring in the key (e.g. "Panneau signal" → "signal"). - lowered = key.lower() - for stable_id in ("signal", "image"): - if stable_id in lowered: - return stable_id - return key - - @classmethod - def _normalize_panel_keys(cls, d: dict) -> dict: - """Return *d* with all top-level keys normalized to stable panel IDs.""" - return {cls._normalize_panel_key(k): v for k, v in d.items()} - - def save(self, mainwindow: DLMainWindow) -> None: - """Save the current workspace state - - Args: - mainwindow: DataLab's main window - """ - self.selection = self.get_current_selection(mainwindow) - self.object_metadata = {} - for panel in (mainwindow.signalpanel, mainwindow.imagepanel): - sel_uuids = self.selection[panel.PANEL_STR_ID] - self.states[panel.PANEL_STR_ID] = [ - str(obj.data.shape) - for obj in panel.objmodel - if get_uuid(obj) in sel_uuids - ] - self.titles[panel.PANEL_STR_ID] = [ - obj.title for obj in panel.objmodel if get_uuid(obj) in sel_uuids - ] - # Store metadata for ALL panel objects (not just selected) so that - # the dict key order captures the full panel ordering. During - # session replay the key order lets us sort old UUIDs by their - # original panel position, which prevents non-commutative 2_to_1 - # operand swaps in the positional-fallback code path. - # ``is_current_state_compatible`` only checks *selected* UUIDs, so - # the extra entries are harmless for compatibility validation. - self.object_metadata[panel.PANEL_STR_ID] = { - get_uuid(obj): self.get_object_metadata(obj) - for obj in panel.objmodel - } - - def is_current_state_compatible( # pylint: disable=unused-argument - self, mainwindow: DLMainWindow, restore_selection: bool - ) -> bool: - """Check if the current workspace state is compatible with the saved state. - - Compatibility means that **every** UUID recorded in the saved selection - still exists in the corresponding panel. When structured object metadata - is available (current schema), each selected object's data shape and - dimensions must also match the saved signature. Histories without this - metadata fall back to legacy UUID-existence validation. - - Args: - mainwindow: DataLab's main window - restore_selection: Unused (kept for API symmetry). With UUID-based - identity, the compatibility check no longer depends on the current - selection -- it only depends on object existence. - - Returns: - True if every saved UUID still exists in its panel and saved - metadata, when available, still matches. - """ - if not self.selection: - return True - for panel in (mainwindow.signalpanel, mainwindow.imagepanel): - saved_uuids = self.selection.get(panel.PANEL_STR_ID, []) - existing_uuids = set(panel.objmodel.get_object_ids()) - saved_metadata = self.object_metadata.get(panel.PANEL_STR_ID, {}) - for uuid in saved_uuids: - if uuid not in existing_uuids: - return False - if uuid in saved_metadata: - current = self.get_object_metadata(panel.objmodel[uuid]) - current = self._normalize_object_metadata(current) - saved = self._normalize_object_metadata(saved_metadata[uuid]) - if saved and current != saved: - return False - return True - - def restore(self, mainwindow: DLMainWindow) -> None: - """Restore the workspace state by selecting the recorded UUIDs. - - Args: - mainwindow: DataLab's main window - - Raises: - ValueError: If at least one of the saved UUIDs no longer exists in - its panel. - """ - if not self.selection: - return - if not self.is_current_state_compatible(mainwindow, False): - raise ValueError( - "Current workspace state is not compatible with saved state" - ) - for panel in (mainwindow.signalpanel, mainwindow.imagepanel): - uuids = self.selection.get(panel.PANEL_STR_ID, []) - if uuids: - panel.objview.select_objects(uuids) - - -class HistorySession: - """Object representing a history session, i.e. a list of actions. - - A history session is a list of actions that can be replayed in the same order - as they were added to the history session. The history session can be saved to - a file and loaded from a file. - - Args: - title: Title of the history session - number: Number of the history session - """ - - def __init__(self, title: str = "", number: int = 0) -> None: - """Create a new history session""" - prefix = _("Session") - self.title = title if title else f"{prefix} {number:03d}" - self.number = number - self.dtstr: str = get_datetime_str() - self.actions: list[HistoryAction] = [] - self.schema_version: int = HISTORY_SCHEMA_VERSION - - def add_action(self, action: HistoryAction) -> None: - """Add an action to the history session - - Args: - action: Action to add - """ - self.actions.append(action) - - def copy( - self, title: str | None = None, action_title_suffix: str | None = None - ) -> HistorySession: - """Return an independent copy of this history session.""" - session = HistorySession(title=title or self.title, number=self.number) - session.actions = [ - action.copy(title_suffix=action_title_suffix) for action in self.actions - ] - return session - - def copy_with_uuid_remap( - self, title: str, uuid_remap: dict[str, dict[str, str]] - ) -> HistorySession: - """Return a copy of this session with all UUIDs rewritten via ``uuid_remap``. - - Used by the Duplicate operation to build an independent session whose - captured object references point to the cloned data objects. - - Args: - title: Title for the new session. - uuid_remap: Per-panel mapping ``{panel_str: {old_uuid: new_uuid}}``. - - Returns: - A new :class:`HistorySession` with all captured UUIDs remapped. - """ - session = HistorySession(title=title, number=self.number) - session.actions = [ - action.copy_with_uuid_remap(uuid_remap) for action in self.actions - ] - return session - - def is_current_state_compatible( - self, mainwindow: DLMainWindow, restore_selection: bool - ) -> bool: - """Check if the current workspace state is compatible with the saved state - - Args: - mainwindow: DataLab's main window - restore_selection: True to restore the selection before checking the state - - Returns: - bool: True if the current workspace state is compatible with the saved state - """ - if self.actions: - return self.actions[0].is_current_state_compatible( - mainwindow, restore_selection - ) - return True - - def restore(self, mainwindow: DLMainWindow) -> None: - """Restore the state of the workspace associated to the first action of session - - Args: - mainwindow: DataLab's main window - """ - if self.actions: - self.actions[0].restore(mainwindow) - - def replay( - self, mainwindow: DLMainWindow, restore_selection: bool, edit: bool - ) -> None: - """Replay the history session - - Args: - mainwindow: DataLab's main window - restore_selection: True to restore the workspace selection before replaying - edit: if True, always open the dialog boxes to edit parameters, if False, - use the parameters passed when creating the action - """ - # Per-panel ``{old_uuid: new_uuid}`` mapping, populated as UI actions - # create new objects. Used by compute actions to translate their - # captured selection (and ``obj2_uuids``) into the freshly-created - # UUIDs of the current replay, so chained ``n_to_1`` / ``2_to_1`` / - # ``1_to_n`` actions operate on the correct inputs. Keys are - # ``panel.PANEL_STR_ID`` (matches ``WorkspaceState.selection`` keys). - panels = (mainwindow.signalpanel, mainwindow.imagepanel) - uuid_remap: dict[str, dict[str, str]] = {p.PANEL_STR_ID: {} for p in panels} - # FIFO of newly-created UUIDs not yet claimed by a remap entry -- - # required because most creation UI actions (e.g. ``new_signal``) - # are recorded with ``save_state=False`` (empty captured selection), - # so we cannot pair captured-vs-new UUIDs by position at UI time. - # Subsequent compute actions claim from this queue on demand. - unclaimed: dict[str, list[str]] = {p.PANEL_STR_ID: [] for p in panels} - def _claim_unmapped( - pstr: str, - old_uuids: list[str], - action: HistoryAction, - ) -> None: - """Claim unclaimed new UUIDs for *old_uuids* not yet in uuid_remap. - - Uses title matching (scanning the full unclaimed queue) followed by - panel-order index alignment to deterministically pair old UUIDs - to the correct new UUIDs, regardless of creation order. - """ - # Collect unmapped UUIDs (deduplicated, preserving first-seen order). - all_unmapped: list[str] = [] - seen: set[str] = set() - for u in old_uuids: - if u not in seen and u not in uuid_remap.get(pstr, {}): - all_unmapped.append(u) - seen.add(u) - if not all_unmapped: - return - # Re-sort by recorded panel position when available. - panel_order = list( - action.state.object_metadata.get(pstr, {}).keys() - ) - if panel_order and all(u in panel_order for u in all_unmapped): - all_unmapped.sort(key=panel_order.index) - queue = unclaimed.get(pstr) or [] - if not queue: - return - # Build old UUID → title from captured state and object_metadata. - sel_uuids = action.state.selection.get(pstr, []) - sel_titles = action.state.titles.get(pstr, []) - old_titles: dict[str, str] = {} - for _u, _t in zip(sel_uuids, sel_titles): - if _u in seen: - old_titles[_u] = _t - obj_meta = action.state.object_metadata.get(pstr, {}) - for _u in all_unmapped: - if _u not in old_titles and _u in obj_meta: - meta = obj_meta[_u] - if isinstance(meta, dict) and "title" in meta: - old_titles[_u] = meta["title"] - # Build new UUID → title from the live panel (full queue). - new_titles: dict[str, str] = {} - panel_obj = None - for p in panels: - if p.PANEL_STR_ID == pstr: - panel_obj = p - break - if panel_obj is not None: - for nu in queue: - try: - new_titles[nu] = panel_obj.objmodel[nu].title - except KeyError: - pass - # Phase 1: title matching against the FULL queue. - assigned_old: set[str] = set() - assigned_new: set[str] = set() - for ou in all_unmapped: - if ou not in old_titles: - continue - title = old_titles[ou] - candidates = [ - nu - for nu in queue - if nu not in assigned_new - and new_titles.get(nu) == title - ] - if len(candidates) == 1: - uuid_remap.setdefault(pstr, {})[ou] = candidates[0] - assigned_old.add(ou) - assigned_new.add(candidates[0]) - # Phase 2: positional fallback using panel-order alignment. - # Two modes depending on whether the remaining queue covers all - # free recorded panel slots: - # - # A) Absolute index alignment (len(rem_queue) == len(free_indices)): - # Each free panel_order index maps 1-to-1 to a queue slot. - # This ensures e.g. the second-created object maps to the - # second queue entry even when only a subset of old UUIDs - # needs claiming. - # - # B) Relative order fallback (queue is a strict subset): - # The queue only contains later compute-created objects while - # earlier full-panel entries are absent. Absolute alignment - # would leave non-first old UUIDs unmapped. Instead, zip - # rem_old (already sorted by panel order) with rem_queue - # sequentially. - rem_old = [u for u in all_unmapped if u not in assigned_old] - if rem_old and panel_order: - rem_queue = [u for u in queue if u not in assigned_new] - # Find which panel_order indices are "free" (unclaimed). - free_indices: list[int] = [] - for idx, po_uuid in enumerate(panel_order): - if po_uuid not in uuid_remap.get(pstr, {}): - if po_uuid not in assigned_old: - free_indices.append(idx) - if len(rem_queue) == len(free_indices): - # Mode A: absolute index alignment. - idx_to_new: dict[int, str] = {} - for qi, fi in enumerate(free_indices): - if qi < len(rem_queue): - idx_to_new[fi] = rem_queue[qi] - for ou in rem_old: - if ou in panel_order: - idx = panel_order.index(ou) - if idx in idx_to_new: - nu = idx_to_new[idx] - uuid_remap.setdefault(pstr, {})[ou] = nu - assigned_new.add(nu) - else: - # Mode B: relative order fallback. - for ou, nu in zip(rem_old, rem_queue): - uuid_remap.setdefault(pstr, {})[ou] = nu - assigned_new.add(nu) - elif rem_old: - # No panel_order available: sequential fallback. - rem_queue = [u for u in queue if u not in assigned_new] - for ou, nu in zip(rem_old, rem_queue): - uuid_remap.setdefault(pstr, {})[ou] = nu - assigned_new.add(nu) - # Remove all assigned new UUIDs from the unclaimed queue. - if assigned_new: - unclaimed[pstr] = [u for u in queue if u not in assigned_new] - - for action in self.actions[:]: - before = {p.PANEL_STR_ID: set(p.objmodel.get_object_ids()) for p in panels} - if action.kind == HistoryAction.KIND_COMPUTE: - # Lazy-resolve any captured UUIDs missing from the remap by - # claiming from ``unclaimed`` (deterministic: title + panel-order). - pstr = action.panel_str or "" - captured = action.state.selection.get(pstr, []) - if action.pattern == "2_to_1": - # For 2_to_1: collect ALL unmapped old UUIDs from both - # captured selection and obj2_uuids in one batch so - # operand order is preserved by the helper. - obj2 = action.kwargs.get("obj2_uuids") or [] - if isinstance(obj2, str): - obj2 = [obj2] - _claim_unmapped(pstr, list(obj2) + list(captured), action) - else: - # For all other compute patterns (1_to_1, n_to_1, etc.): - # use the same deterministic helper. - _claim_unmapped(pstr, list(captured), action) - action.replay( - mainwindow, - restore_selection=restore_selection, - edit=edit, - uuid_remap=uuid_remap, - ) - # Post-action bookkeeping: track new/removed UUIDs for *every* - # action kind so that later actions consuming compute-created - # outputs can resolve them through ``uuid_remap`` / ``unclaimed``. - for panel in panels: - pstr = panel.PANEL_STR_ID - current_ids = set(panel.objmodel.get_object_ids()) - new_uuids = [ - u - for u in panel.objmodel.get_object_ids() - if u not in before[pstr] - ] - # Drop vanished UUIDs from the unclaimed queue and the - # reverse remap entries (e.g. ``Remove selected objects``): - # this keeps the FIFO claim in sync with the live panel - # contents during chained creation/removal replays. - removed_uuids = before[pstr] - current_ids - if removed_uuids: - unclaimed[pstr] = [ - u for u in unclaimed.get(pstr, []) if u not in removed_uuids - ] - panel_map = uuid_remap.get(pstr, {}) - for old_key in [ - k for k, v in panel_map.items() if v in removed_uuids - ]: - panel_map.pop(old_key, None) - if not new_uuids: - continue - if action.kind == HistoryAction.KIND_UI: - captured = action.state.selection.get(pstr, []) - if captured: - # Captured post-action selection available: pair - # captured UUIDs with new UUIDs by position. - for old_uuid, new_uuid in zip(captured, new_uuids): - uuid_remap.setdefault(pstr, {})[old_uuid] = new_uuid - # Any extra newly-created UUIDs go to the queue. - unclaimed.setdefault(pstr, []).extend( - new_uuids[len(captured) :] - ) - else: - # No captured selection (typical of ``new_signal``): - # queue all new UUIDs for lazy claiming. - unclaimed.setdefault(pstr, []).extend(new_uuids) - else: - # Compute actions: queue all newly-created UUIDs so - # later actions can lazily claim them. Do NOT map - # captured input UUIDs to output UUIDs — compute - # inputs and outputs are semantically different. - unclaimed.setdefault(pstr, []).extend(new_uuids) - - # Visually close the replay: select the output of the last compute - # action so the user sees the final result highlighted in the panel. - # Without this, the very last action's output is never selected - # (intermediate actions are implicitly "closed" by the next - # iteration's input restore). - if self.actions: - last = self.actions[-1] - if last.kind == HistoryAction.KIND_COMPUTE: - hpanel = getattr(mainwindow, "historypanel", None) - if hpanel is not None: - output_uuid = hpanel._action_output_uuid(last) - if output_uuid: - panel_str = last.panel_str or "" - panel_map = uuid_remap.get(panel_str, {}) - mapped_uuid = panel_map.get(output_uuid, output_uuid) - for panel in panels: - if panel.PANEL_STR_ID == panel_str: - try: - panel.objview.select_objects([mapped_uuid]) - except KeyError: - pass - break - - def serialize(self, writer: NativeH5Writer) -> None: - """Serialize this history session - - Args: - writer: Writer - """ - with writer.group("schema_version"): - writer.write(self.schema_version) - with writer.group("title"): - writer.write(self.title) - with writer.group("number"): - writer.write(self.number) - with writer.group("dtstr"): - writer.write(self.dtstr) - writer.write_object_list(self.actions, "actions") - - def deserialize(self, reader: NativeH5Reader) -> None: - """Deserialize this history session - - Args: - reader: Reader - """ - self.schema_version = reader.read( - "schema_version", default=HISTORY_SCHEMA_VERSION - ) - with reader.group("title"): - self.title = reader.read_any() - with reader.group("number"): - self.number = reader.read_any() - with reader.group("dtstr"): - self.dtstr = reader.read_any() - self.actions = reader.read_object_list("actions", HistoryAction) - - def remove_action(self, action: HistoryAction) -> None: - """Remove an action from the history session - - This implies removing all subsequent actions. If action is not found, this - fails silently. - - Args: - action: Action to remove - """ - if action in self.actions: - index = self.actions.index(action) - self.actions = self.actions[:index] - - -class CollapsibleDescriptionWidget(QW.QWidget): - """Compact, expandable cell widget for the history Description column. - - Shows a single-line summary by default; a chevron toggle reveals the full - HTML description (mirroring the *Properties* tab rendering). - """ - - toggled = QC.Signal(bool) - - def __init__( - self, - summary: str, - html_text: str, - expanded: bool = False, - parent: QW.QWidget | None = None, - ) -> None: - super().__init__(parent) - self._summary = summary - self._html = html_text - self._expanded = expanded - - self._toggle = QW.QToolButton(self) - self._toggle.setAutoRaise(True) - self._toggle.setCheckable(True) - self._toggle.setFocusPolicy(QC.Qt.NoFocus) - self._toggle.setArrowType(QC.Qt.RightArrow) - self._toggle.setToolTip(_("Show details")) - - self._label = QW.QLabel(self) - self._label.setTextFormat(QC.Qt.RichText) - self._label.setWordWrap(True) - self._label.setTextInteractionFlags(QC.Qt.TextSelectableByMouse) - self._label.setAlignment(QC.Qt.AlignTop | QC.Qt.AlignLeft) - - layout = QW.QHBoxLayout(self) - layout.setContentsMargins(0, 0, 0, 0) - layout.setSpacing(2) - layout.addWidget(self._toggle, 0, QC.Qt.AlignTop) - layout.addWidget(self._label, 1) - - # Hide the toggle when there is nothing more to show than the summary. - if not self._html or self._html_matches_summary(): - self._toggle.setVisible(False) - - self._toggle.toggled.connect(self._on_toggled) - self._refresh() - - def _html_matches_summary(self) -> bool: - """Return True when the HTML rendering would not add information.""" - return self._html.strip() == html.escape(self._summary).strip() - - def _on_toggled(self, checked: bool) -> None: - self._expanded = checked - self._refresh() - self.toggled.emit(checked) - - def _refresh(self) -> None: - if self._expanded: - self._toggle.setArrowType(QC.Qt.DownArrow) - self._toggle.setToolTip(_("Hide details")) - self._label.setText(self._html or html.escape(self._summary)) - else: - self._toggle.setArrowType(QC.Qt.RightArrow) - self._toggle.setToolTip(_("Show details")) - self._label.setText(html.escape(self._summary)) - self.updateGeometry() - - def is_expanded(self) -> bool: - """Return current expanded state.""" - return self._expanded - - def set_expanded(self, expanded: bool) -> None: - """Programmatically set the expanded state.""" - if expanded == self._expanded: - return - self._toggle.setChecked(expanded) - - -class HistoryTree(QW.QTreeWidget): - """Tree widget for the history panel""" - - DESCRIPTION_COLUMN = 2 - COMPATIBILITY_ROLE = QC.Qt.UserRole + 1 - - def __init__(self, parent: QW.QWidget) -> None: - """Create a new history tree widget""" - super().__init__(parent) - self.setHeaderLabels([_("Title"), _("Date and time"), _("Description")]) - self.setContextMenuPolicy(QC.Qt.CustomContextMenu) - self.setSelectionMode(QW.QAbstractItemView.ContiguousSelection) - self.setUniformRowHeights(False) - header = self.header() - header.setSectionResizeMode(self.DESCRIPTION_COLUMN, QW.QHeaderView.Stretch) - # Per-action expanded state, preserved across repopulate (delete/replay). - self.__expanded_state: dict[str, bool] = {} - - def __on_description_toggled(self, uuid: str, expanded: bool) -> None: - """Remember the expanded state of a description cell.""" - self.__expanded_state[uuid] = expanded - # Force the tree to recompute row heights now that the label content - # has changed. - self.scheduleDelayedItemsLayout() - - def __install_description_widget( - self, item: QW.QTreeWidgetItem, action: HistoryAction - ) -> None: - """Attach the collapsible description widget to ``item`` (column 2). - - The item must already be inserted in the tree before calling this. - """ - expanded = self.__expanded_state.get(action.uuid, False) - widget = CollapsibleDescriptionWidget( - action.description_summary, - action.description_html, - expanded=expanded, - parent=self, - ) - widget.toggled.connect( - lambda checked, uuid=action.uuid: self.__on_description_toggled( - uuid, checked - ) - ) - # Clear any text the item may carry for that column to avoid double - # rendering behind the widget. - item.setText(self.DESCRIPTION_COLUMN, "") - self.setItemWidget(item, self.DESCRIPTION_COLUMN, widget) - - @classmethod - def action_to_tree_item(cls, action: HistoryAction) -> QW.QTreeWidgetItem: - """Convert an action to a tree item - - Args: - action: Action to convert - - Returns: - QW.QTreeWidgetItem: Tree item - """ - # Description column is left empty: a CollapsibleDescriptionWidget is - # installed by ``HistoryTree`` once the item is inserted in the tree. - item = QW.QTreeWidgetItem([action.title, action.dtstr, ""]) - item.setData(0, QC.Qt.UserRole, action.uuid) - item.setData(0, cls.COMPATIBILITY_ROLE, True) - return item - - def update_compatibility_states( - self, history_sessions: list[HistorySession], mainwindow: DLMainWindow - ) -> None: - """Update action item visual state from workspace compatibility.""" - default_brush = QG.QBrush() - disabled_brush = QG.QBrush( - self.palette().color(QG.QPalette.Disabled, QG.QPalette.Text) - ) - compatible_tip = _("Action is compatible with the current workspace state.") - incompatible_tip = _( - "Action is not compatible with the current workspace state." - ) - for i in range(self.topLevelItemCount()): - session_item = self.topLevelItem(i) - for j in range(session_item.childCount()): - child = session_item.child(j) - uuid = child.data(0, QC.Qt.UserRole) - action = self.get_action_from_uuid(uuid, history_sessions) - compatible = action.is_current_state_compatible( - mainwindow, restore_selection=True - ) - child.setData(0, self.COMPATIBILITY_ROLE, compatible) - brush = default_brush if compatible else disabled_brush - icon = get_icon("apply.svg") if compatible else get_icon("delete.svg") - child.setIcon(0, icon) - for col in range(self.columnCount()): - child.setForeground(col, brush) - child.setToolTip( - col, compatible_tip if compatible else incompatible_tip - ) - - def __forget_orphan_expanded_states( - self, history_sessions: list[HistorySession] - ) -> None: - """Drop expanded-state entries for actions that no longer exist.""" - live_uuids = { - action.uuid for session in history_sessions for action in session.actions - } - self.__expanded_state = { - uuid: state - for uuid, state in self.__expanded_state.items() - if uuid in live_uuids - } - - def populate_tree(self, history_sessions: list[HistorySession]) -> None: - """Populate the history tree widget - - Args: - history_sessions: List of history sessions - """ - self.__forget_orphan_expanded_states(history_sessions) - self.clear() - for session in history_sessions: - ritem = QW.QTreeWidgetItem([session.title, session.dtstr]) - ritem.setData(0, self.COMPATIBILITY_ROLE, True) - self.addTopLevelItem(ritem) - for action in session.actions: - child = self.action_to_tree_item(action) - ritem.addChild(child) - self.__install_description_widget(child, action) - self.expandAll() - for col in (0, 1): - self.resizeColumnToContents(col) - - def rearrange_tree(self) -> None: - """Rearrange the history tree widget""" - self.expandAll() - for col in (0, 1): - self.resizeColumnToContents(col) - - def add_action_to_tree(self, action: HistoryAction) -> None: - """Add an action to the history tree widget - - Args: - action: Action to add - """ - item = self.action_to_tree_item(action) - ritem = self.topLevelItem(self.topLevelItemCount() - 1) - ritem.addChild(item) - self.__install_description_widget(item, action) - - def refresh_action_item(self, action: HistoryAction) -> None: - """Refresh the tree item corresponding to ``action``. - - Re-installs the description widget so it reflects the current - ``action.kwargs`` (e.g. after the user edited a ``param`` via the - Processing tab of the Signal/Image panel). Also applies a light - orange background when ``action.is_stale`` is True, to signal that - the action is currently being recomputed in a cascade. - """ - target_uuid = action.uuid - stale_brush = QG.QBrush(QG.QColor(255, 220, 150)) # light orange - normal_brush = QG.QBrush() - iterator = QW.QTreeWidgetItemIterator(self) - while iterator.value(): - item = iterator.value() - if item.data(0, QC.Qt.UserRole) == target_uuid: - # Remove and re-install the collapsible description widget so - # it reflects the mutated ``action.kwargs``. - self.removeItemWidget(item, self.DESCRIPTION_COLUMN) - self.__install_description_widget(item, action) - brush = stale_brush if action.is_stale else normal_brush - for col in range(self.columnCount()): - item.setBackground(col, brush) - self.scheduleDelayedItemsLayout() - return - iterator += 1 - - def get_action_from_uuid( - self, uuid: str, history_sessions: list[HistorySession] - ) -> HistoryAction: - """Get the action from its UUID - - Args: - uuid: Action UUID - history_sessions: List of history sessions - - Returns: - HistoryAction: Action - """ - for session in history_sessions: - for action in session.actions: - if action.uuid == uuid: - return action - raise ValueError("Action not found") - - def get_selected_actions_or_sessions( - self, history_sessions: list[HistorySession] - ) -> list[HistoryAction | HistorySession]: - """Get the selected actions or sessions - - Args: - history_sessions: List of history sessions - - Returns: - list[HistoryAction | HistorySession]: List of selected actions or sessions - """ - selected: list[HistoryAction | HistorySession] = [] - for item in self.selectedItems(): - if item.parent() is None: - index = self.indexOfTopLevelItem(item) - selected.append(history_sessions[index]) - else: - uuid = item.data(0, QC.Qt.UserRole) - selected.append(self.get_action_from_uuid(uuid, history_sessions)) - return selected - - def get_selected_actions( - self, history_sessions: list[HistorySession] - ) -> list[HistoryAction]: - """Get the selected actions - - Args: - history_sessions: List of history sessions - - Returns: - list[HistoryAction]: List of selected actions - """ - selected: list[HistoryAction] = [] - for item in self.selectedItems(): - if item.parent() is not None: - uuid = item.data(0, QC.Qt.UserRole) - selected.append(self.get_action_from_uuid(uuid, history_sessions)) - return selected - - -class WorkspaceStateWidget(QW.QWidget): - """Side-by-side tables showing the workspace state captured by a history action. - - Left table: signals (title + data shape). - Right table: images (title + data shape/dimensions). - """ - - def __init__(self, parent: QW.QWidget | None = None) -> None: - super().__init__(parent) - self._signal_table = QW.QTableWidget(0, 2, self) - self._signal_table.setHorizontalHeaderLabels([_("Signal"), _("Shape")]) - self._signal_table.horizontalHeader().setStretchLastSection(True) - self._signal_table.setEditTriggers(QW.QAbstractItemView.NoEditTriggers) - self._signal_table.setSelectionMode(QW.QAbstractItemView.NoSelection) - self._signal_table.verticalHeader().hide() - - self._image_table = QW.QTableWidget(0, 2, self) - self._image_table.setHorizontalHeaderLabels([_("Image"), _("Dimensions")]) - self._image_table.horizontalHeader().setStretchLastSection(True) - self._image_table.setEditTriggers(QW.QAbstractItemView.NoEditTriggers) - self._image_table.setSelectionMode(QW.QAbstractItemView.NoSelection) - self._image_table.verticalHeader().hide() - - splitter = QW.QSplitter(QC.Qt.Horizontal, self) - splitter.addWidget(self._signal_table) - splitter.addWidget(self._image_table) - layout = QW.QVBoxLayout(self) - layout.setContentsMargins(0, 0, 0, 0) - layout.addWidget(splitter) - - def update_from_state(self, state: WorkspaceState | None) -> None: - """Populate tables from a WorkspaceState.""" - self._signal_table.setRowCount(0) - self._image_table.setRowCount(0) - if state is None: - return - self._populate_table(self._signal_table, state, "signal") - self._populate_table(self._image_table, state, "image") - - @staticmethod - def _populate_table( - table: QW.QTableWidget, state: WorkspaceState, panel_key: str - ) -> None: - """Fill a table from the state for a given panel key.""" - titles = state.titles.get(panel_key, []) - shapes = state.states.get(panel_key, []) - metadata = state.object_metadata.get(panel_key, {}) - uuids = state.selection.get(panel_key, []) - # Use metadata keyed by UUID when available - rows: list[tuple[str, str]] = [] - for i, uuid in enumerate(uuids): - title = titles[i] if i < len(titles) else uuid[:8] - meta = metadata.get(uuid, {}) - shape = meta.get("shape") - if shape is not None: - shape_str = " × ".join(str(s) for s in shape) - elif i < len(shapes): - shape_str = shapes[i] - else: - shape_str = "—" - rows.append((title, shape_str)) - table.setRowCount(len(rows)) - for row_idx, (title, shape_str) in enumerate(rows): - table.setItem(row_idx, 0, QW.QTableWidgetItem(title)) - table.setItem(row_idx, 1, QW.QTableWidgetItem(shape_str)) - - -class HistoryPanel(AbstractPanel, DockableWidgetMixin): - """History panel""" - - LOCATION = QC.Qt.RightDockWidgetArea - PANEL_STR = _("History panel") - - H5_PREFIX = "DataLab_His" - - SIG_OBJECT_MODIFIED = QC.Signal() - - FILE_FILTERS = f"{_('History files')} (*.dlhist)" - - def __init__(self, parent: DLMainWindow) -> None: - super().__init__(parent) - self.setWindowTitle(self.PANEL_STR) - self.setWindowIcon(get_icon("history.svg")) - self.setOrientation(QC.Qt.Vertical) - - self.__record_mode = False - self.__edit_mode = False - # When `__replaying` is True, calls to `add_entry` are silently - # ignored. This prevents replay/recompute paths from polluting the - # history with synthetic entries triggered by their own internal - # `compute_*` calls. Use `replaying()` as a context manager. - self.__replaying = False - self.__output_suppressed = False - # Guard flag used by `__sync_panel_selection` to prevent re-entry - # while the data panels are being updated programmatically. - self.__syncing = False - self._cascade_in_progress = False - self.__delete_action: QW.QAction | None = None - self.__duplicate_action: QW.QAction | None = None - self.__step_prev_action: QW.QAction | None = None - self.__step_next_action: QW.QAction | None = None - self.__restore_selection_action: QW.QAction | None = None - self.__edit_action: QW.QAction | None = None - self.__menu_actions: list[QW.QAction] = self.__create_menu_actions() - - self.mainwindow = parent - self.tree = HistoryTree(self) - self.tree.customContextMenuRequested.connect(self.show_context_menu) - self.tree.itemDoubleClicked.connect(self.replay_restore_actions) - self.tree.itemSelectionChanged.connect(self.__sync_panel_selection) - self.tree.itemSelectionChanged.connect(self.__update_actions_state) - self.tree.itemSelectionChanged.connect(self.__update_state_widget) - - self.__state_widget = WorkspaceStateWidget(self) - - toolbar = QW.QToolBar(self) - add_actions(toolbar, self.__menu_actions) - widget = QW.QWidget(self) - layout = QW.QVBoxLayout() - layout.addWidget(toolbar) - layout.addWidget(self.tree) - layout.addWidget(self.__state_widget) - layout.setContentsMargins(0, 0, 0, 0) - widget.setLayout(layout) - - self.addWidget(widget) - - self.__history_sessions: list[HistorySession] = [] - self.__session_increment = 0 - # Bijective action ↔ output mapping (C1). Both dicts are kept in sync - # by :meth:`register_action_outputs` and pruned by - # :meth:`_prune_output_mapping` when objects are removed from a panel. - # Reconstructed at HDF5 load time from each action's ``output_uuids``. - self._action_output_uuids: dict[str, list[str]] = {} - self._output_to_action: dict[str, str] = {} - # Warnings collected during ``recompute_cascade`` (and the helpers - # it dispatches to). Aggregated into a single user-facing dialog - # at the end of the cascade so deleted output objects / missing - # sources / unsupported patterns do not spam the user. - self._cascade_warnings: list[str] = [] - # Actions detected as broken (missing plugin) during a cascade run. - # Transient — intentionally not persisted: recalculated from scratch - # on each cascade run, similar to ``is_stale``. - # The visual stale marker is *not* cleared for these so the user - # sees them flagged in the tree until the plugin is reinstalled and - # the cascade is re-run successfully. - self._broken_actions: set[str] = set() - # Re-entrancy guard for :meth:`_reconnect_chain_after_removal` (see - # method docstring): ``recompute_cascade`` pumps the event loop and - # could deliver a queued ``SIG_OBJECT_REMOVED`` mid-reconnection. - self.__reconnecting = False - for panel in (self.mainwindow.signalpanel, self.mainwindow.imagepanel): - panel.SIG_OBJECT_ADDED.connect(self.refresh_compatibility_items) - panel.SIG_OBJECT_ADDED.connect(self.__refresh_obj_ids_snapshot) - panel.SIG_OBJECT_REMOVED.connect(self.refresh_compatibility_items) - panel.SIG_OBJECT_REMOVED.connect( - functools.partial(self._reconnect_chain_after_removal, panel) - ) - panel.SIG_OBJECT_REMOVED.connect(self._prune_output_mapping) - panel.SIG_OBJECT_MODIFIED.connect(self.refresh_compatibility_items) - self.__refresh_obj_ids_snapshot() - self.__update_actions_state() - self.refresh_compatibility_items() - - def __refresh_obj_ids_snapshot(self) -> None: - """Cache the current object ids of both data panels. - - ``SIG_OBJECT_REMOVED`` carries no payload, so the set of just-deleted - objects is recovered by diffing this snapshot against the live model - inside :meth:`_reconnect_chain_after_removal`. - """ - self.__obj_ids_snapshot = { - self.mainwindow.signalpanel.PANEL_STR_ID: set( - self.mainwindow.signalpanel.objmodel.get_object_ids() - ), - self.mainwindow.imagepanel.PANEL_STR_ID: set( - self.mainwindow.imagepanel.objmodel.get_object_ids() - ), - } - - def __update_actions_state(self) -> None: - """Update the enabled state of menu actions depending on history content.""" - has_history = len(self) > 0 - for action in ( - self.__delete_action, - self.__duplicate_action, - ): - if action is not None: - action.setEnabled(has_history) - if self.__step_prev_action is not None: - self.__step_prev_action.setEnabled(self.__can_step_prev()) - if self.__step_next_action is not None: - self.__step_next_action.setEnabled(self.__can_step_next()) - if self.__restore_selection_action is not None: - self.__restore_selection_action.setEnabled( - self.__edit_mode or self._has_any_pending_edits() - ) - - def _has_any_pending_edits(self) -> bool: - """Return True if any action across all sessions has a pending - Edit mode snapshot (i.e. uncommitted edits that Restore can revert). - """ - return any( - action.has_pending_edits - for session in self.__history_sessions - for action in session.actions - ) - - def __update_state_widget(self) -> None: - """Update the workspace state widget from the currently selected action.""" - action = self.__current_action() - if action is not None: - self.__state_widget.update_from_state(action.state) - else: - self.__state_widget.update_from_state(None) - - def __create_menu_actions(self) -> list[QW.QAction]: - """Create menu actions for the history panel - - Returns: - list[QW.QAction]: List of menu actions - """ - edit_action = create_action( - self, - _("Edit mode"), - toggled=self.toggle_edit_mode, - icon=get_icon("edit_mode.svg"), - ) - edit_action.setChecked(self.__edit_mode) - self.__edit_action = edit_action - record_action = create_action( - self, - _("Record mode"), - toggled=self.toggle_record_mode, - icon=get_icon("record.svg"), - ) - record_action.setChecked(self.__record_mode) - new_session_action = create_action( - self, - _("New session"), - self.create_new_session, - icon=get_icon("libre-gui-add.svg"), - tip=_("Start a new history session"), - ) - open_action = create_action( - self, - _("Open history file..."), - triggered=lambda checked=False: self.open_dlhist_file(), - icon=get_icon("fileopen_h5.svg"), - tip=_("Open history from a standalone .dlhist file"), - ) - save_action = create_action( - self, - _("Save history file..."), - triggered=lambda checked=False: self.save_to_dlhist_file(), - icon=get_icon("filesave_h5.svg"), - tip=_("Save history to a standalone .dlhist file"), - ) - self.__delete_action = create_action( - self, - _("Delete"), - self.delete_selected, - icon=get_icon("delete.svg"), - ) - self.__duplicate_action = create_action( - self, - _("Duplicate"), - self.duplicate_selected_entries, - icon=get_icon("duplicate.svg"), - tip=_("Duplicate selected history action/session"), - ) - self.__step_prev_action = create_action( - self, - _("Previous step"), - triggered=self._step_prev, - icon=get_icon("libre-gui-arrow-left.svg"), - tip=_("Select the previous action in the current session"), - shortcut=QG.QKeySequence("Ctrl+Left"), - ) - self.__step_next_action = create_action( - self, - _("Next step"), - triggered=self._step_next, - icon=get_icon("libre-gui-arrow-right.svg"), - tip=_("Select the next action in the current session"), - shortcut=QG.QKeySequence("Ctrl+Right"), - ) - generate_macro_action = create_action( - self, - _("Generate macro"), - self.generate_macro, - icon=get_icon("console.svg"), - tip=_("Generate a Python macro script from history"), - ) - remove_incompatible_action = create_action( - self, - _("Remove incompatible"), - self.remove_incompatible_actions, - icon=get_icon("edit/delete_all.svg"), - tip=_("Remove actions incompatible with the current workspace"), - ) - self.__restore_selection_action = create_action( - self, - _("Restore parameters"), - lambda: self.replay_restore_actions( - restore_selection=True, replay=False - ), - icon=get_icon("restore_selection.svg"), - tip=_("Restore original parameters (discard edit-mode changes)"), - ) - return [ - record_action, - new_session_action, - None, - open_action, - save_action, - None, - self.__step_prev_action, - self.__step_next_action, - None, - create_action( - self, - _("Replay"), - lambda: self.replay_restore_actions(restore_selection=False), - icon=get_icon("replay.svg"), - ), - self.__restore_selection_action, - edit_action, - None, - self.__duplicate_action, - generate_macro_action, - None, - remove_incompatible_action, - self.__delete_action, - ] - - def toggle_edit_mode(self, checked: bool) -> None: - """Toggle edit mode. - - Toggling Edit mode off is a **definitive commit**: all parameter - changes performed during the session become permanent and Restore - is no longer available for them. When pending edits exist, the - user is asked to confirm; refusing leaves Edit mode enabled. - - Args: - checked: True if the edit mode is checked, False otherwise. - """ - if not checked and self._has_any_pending_edits(): - reply = QW.QMessageBox.question( - self.mainwindow, - _("Commit edit mode changes?"), - _( - "You are about to exit Edit mode.\n\n" - "All parameter changes made during this session will be " - "permanently kept.\n" - "This action cannot be undone — Restore will no longer " - "be available.\n\n" - "Do you want to continue?" - ), - QW.QMessageBox.Yes | QW.QMessageBox.No, - QW.QMessageBox.No, - ) - if reply != QW.QMessageBox.Yes: - # Re-check the action without triggering toggle_edit_mode - # again (blockSignals prevents recursion). - if self.__edit_action is not None: - self.__edit_action.blockSignals(True) - self.__edit_action.setChecked(True) - self.__edit_action.blockSignals(False) - return - self.__edit_mode = checked - if not checked: - # Exiting edit mode: accept all pending edits (discard snapshots) - for session in self.__history_sessions: - for action in session.actions: - action.discard_snapshot() - self.__update_actions_state() - - def toggle_record_mode(self, checked: bool) -> None: - """Toggle record mode - - Args: - checked: True if the record mode is checked, False otherwise - """ - self.__record_mode = checked - - def is_edit_mode(self) -> bool: - """Return True when the History panel is in edit (parameter testing) mode.""" - return self.__edit_mode - - @contextmanager - def replaying(self) -> Generator[None, None, None]: - """Context manager suppressing history capture during its scope. - - Used by replay / recompute paths to avoid double-capture: the - generic ``compute_*`` methods of the processor would otherwise - register synthetic entries every time recompute or replay - triggers them. - """ - previous = self.__replaying - self.__replaying = True - try: - yield - finally: - self.__replaying = previous - - def is_replaying(self) -> bool: - """Return True when an external replay/recompute is in progress.""" - return self.__replaying - - @contextmanager - def output_suppressed(self) -> Generator[None, None, None]: - """Context manager suppressing compute outputs during its scope. - - When active, :meth:`BaseProcessor._add_object_to_appropriate_panel` - and :meth:`BaseProcessor._create_group_for_result` become no-ops so - that History Panel replay can execute computations without altering - Signal/Image panel object counts. Reentrant-safe. - """ - previous = self.__output_suppressed - self.__output_suppressed = True - try: - yield - finally: - self.__output_suppressed = previous - - def is_output_suppressed(self) -> bool: - """Return True when compute outputs must not be added to panels.""" - return self.__output_suppressed - - def show_context_menu(self, pos: QC.QPoint) -> None: - """Show the context menu - - Args: - pos: Position of the context menu - """ - self.refresh_compatibility_items() - menu = QW.QMenu() - add_actions(menu, self.__menu_actions) - menu.exec_(self.tree.mapToGlobal(pos)) - - def get_action_from_uuid(self, uuid: str) -> HistoryAction: - """Get the action from its UUID - - Args: - uuid: Action UUID - - Returns: - HistoryAction: Action - """ - for session in self.__history_sessions: - for action in session.actions: - if action.uuid == uuid: - return action - raise ValueError("Action not found") - - def replay_restore_actions( - self, replay: bool = True, restore_selection: bool = True - ) -> None: - """Replay and/or restore selection for the selected actions. - - When nothing is selected in the tree, replays the entire last session. - Replay is non-persistent: compute actions run but their outputs are - NOT added to Signal/Image panels. UI-creation actions are always - skipped during replay because source objects already exist. - """ - self.refresh_compatibility_items() - selected = self.tree.get_selected_actions_or_sessions(self.__history_sessions) - if not selected: - if not self.__history_sessions: - return - # Nothing selected → replay the last session - selected = [self.__history_sessions[-1]] - for session_or_action in selected: - # B4: if a stale action is Played, recompute its cascade in-place - # instead of running the standard non-persistent replay. - if ( - isinstance(session_or_action, HistoryAction) - and session_or_action.is_stale - ): - self.recompute_cascade(session_or_action) - continue - if not session_or_action.is_current_state_compatible( - self.mainwindow, restore_selection=restore_selection - ): - QW.QMessageBox.critical( - self.mainwindow, - _("Error"), - _("The current workspace state is not compatible with the action."), - ) - return - if replay: - if self.__edit_mode and isinstance( - session_or_action, HistoryAction - ): - self._edit_mode_replay(session_or_action) - elif self.__edit_mode and isinstance( - session_or_action, HistorySession - ): - self._view_only_session_replay( - session_or_action, restore_selection - ) - else: - with self.replaying(), self.output_suppressed(): - session_or_action.replay( - self.mainwindow, - restore_selection=restore_selection, - edit=self.__edit_mode, - ) - elif restore_selection: - # Restore button (replay=False, restore_selection=True): - # if Edit mode is active OR there are persisted pending - # edits (e.g. after a save/reload), revert the parameter - # snapshots in place. Otherwise behave as a workspace - # selection restore. - if self.__edit_mode or self._has_any_pending_edits(): - self._restore_action_params(session_or_action) - else: - session_or_action.restore(self.mainwindow) - - def _prompt_edit_action_params(self, action: HistoryAction) -> bool | None: - """Open the parameter dialog for *action* according to its pattern. - - Returns: - ``True`` – user accepted; ``action.kwargs`` mutated, snapshot taken. - ``False`` – user cancelled the dialog. - ``None`` – nothing to edit (no param/params, or unsupported pattern). - """ - import copy # pylint: disable=import-outside-toplevel - - pattern = action.pattern - if pattern in {"1_to_1", "1_to_0", "n_to_1", "2_to_1"}: - param = action.kwargs.get("param") - if param is None: - return None - edited = copy.deepcopy(param) - if not edited.edit(parent=self.mainwindow): - return False - action.snapshot_kwargs() - action.kwargs["param"] = edited - return True - if pattern == "1_to_n": - params = action.kwargs.get("params") or [] - if not params: - return None - edited_params = [copy.deepcopy(p) for p in params] - # Local import: ``gds`` is not used elsewhere in this module. - import guidata.dataset as gds # pylint: disable=import-outside-toplevel - - group = gds.DataSetGroup(edited_params, title=_("Parameters")) - if not group.edit(parent=self.mainwindow): - return False - action.snapshot_kwargs() - action.kwargs["params"] = edited_params - return True - # multiple_1_to_1 or any unknown pattern: nothing to edit. - return None - - def _edit_mode_replay(self, action: HistoryAction) -> None: - """Replay a single action in edit mode: open param dialog, update - kwargs on accept, recompute in-place and cascade downstream. - - Supports every compute pattern (1_to_1, 1_to_n, n_to_1, 2_to_1, - 1_to_0). ``multiple_1_to_1`` is currently not supported: the dialog - is skipped for that action but the rest of the chain is still - processed. - - UI actions and pattern-less entries fall back to normal replay. - - The parameter dialog is opened for the root action AND for every - downstream action in the cascade, in topological order. If the - user cancels ANY dialog, all snapshots already created in this - pass are rolled back and nothing is recomputed. - """ - if action.kind != HistoryAction.KIND_COMPUTE or action.pattern is None: - with self.replaying(), self.output_suppressed(): - action.replay(self.mainwindow, restore_selection=True, edit=True) - return - - chain: list[HistoryAction] = [action] + self.get_downstream_actions( - action - ) - edited_actions: list[HistoryAction] = [] - for a in chain: - result = self._prompt_edit_action_params(a) - if result is False: - # User cancelled – rollback every snapshot taken so far. - for done in edited_actions: - done.restore_kwargs() - self.tree.refresh_action_item(done) - return - if result is True: - edited_actions.append(a) - - for a in edited_actions: - self.tree.refresh_action_item(a) - - # Recompute root in-place, then cascade with the pre-computed - # descendants list. Re-using the chain avoids a second call to - # ``get_downstream_actions`` whose result could diverge after the - # root output's metadata has been rewritten by the root recompute. - downstream = chain[1:] - self._recompute_action_in_place(action) - self.recompute_cascade(action, descendants=downstream) - - # Belt-and-suspenders refresh: ensure the tree description widgets - # and the Signal/Image panels reflect the final state for every - # action in the chain (root included). - for a in chain: - self.tree.refresh_action_item(a) - QW.QApplication.processEvents() - - def _show_readonly_param_dialog( - self, dataset: gds.DataSet | gds.DataSetGroup - ) -> None: - """Show a parameter dialog identical to the edit dialog but read-only. - - Builds the same guidata dialog as edit mode (``DataSetEditDialog`` for a - single dataset, ``DataSetGroupEditDialog`` for a group) so the appearance - and title match exactly, then disables every input field (and its label) - so the parameters are displayed but cannot be modified. The OK button is - kept so the dialog can be dismissed. - - Args: - dataset: The dataset (or dataset group) whose parameters are shown. - """ - # Local import: not used elsewhere in this module. - import guidata.dataset as gds # pylint: disable=import-outside-toplevel - from guidata.dataset.qtwidgets import ( # pylint: disable=import-outside-toplevel - DataSetEditDialog, - DataSetGroupEditDialog, - ) - - # A DataSetGroup (1_to_n) needs the tabbed group dialog; a single - # DataSet uses the standard edit dialog. Both expose ``edit_layout``. - if isinstance(dataset, gds.DataSetGroup): - dialog = DataSetGroupEditDialog(dataset, parent=self.mainwindow) - else: - dialog = DataSetEditDialog(dataset, parent=self.mainwindow) - for edl in dialog.edit_layout: - for widget in edl.widgets: - if widget.group is not None: - widget.group.setEnabled(False) - if widget.label is not None: - widget.label.setEnabled(False) - dialog.exec() - - def _view_only_session_replay( - self, - session: HistorySession, - restore_selection: bool, - ) -> None: - """Replay a session in edit mode with read-only parameter dialogs. - - When edit mode is active and a full session is replayed, editable - dialogs would be misleading because modifications cannot be propagated - through the cascade. Instead, show each compute action's parameters in - a dialog that looks identical to the edit dialog but whose fields are - disabled, and keep the History tree and the data panel synchronized with - the action being shown. The session is then replayed with ``edit=False``. - """ - import copy # pylint: disable=import-outside-toplevel - - # Local import: ``gds`` is not used elsewhere in this module. - import guidata.dataset as gds # pylint: disable=import-outside-toplevel - - for action in session.actions: - if action.kind != HistoryAction.KIND_COMPUTE: - continue - pattern = action.pattern - # Sync the History tree and the data panel to this action so the - # user follows the replay step by step (same behaviour as edit mode). - self.__select_action_in_tree(action) - QW.QApplication.processEvents() - if pattern in {"1_to_1", "1_to_0", "n_to_1", "2_to_1"}: - param = action.kwargs.get("param") - if param is not None: - self._show_readonly_param_dialog(copy.deepcopy(param)) - elif pattern == "1_to_n": - params = action.kwargs.get("params") or [] - if params: - group = gds.DataSetGroup( - [copy.deepcopy(p) for p in params], - title=_("Parameters"), - ) - self._show_readonly_param_dialog(group) - - with self.replaying(), self.output_suppressed(): - session.replay( - self.mainwindow, - restore_selection=restore_selection, - edit=False, - ) - - def _restore_action_params( - self, item: HistoryAction | HistorySession - ) -> None: - """Restore original kwargs from snapshot and recompute in-place. - - Used by the Restore action in edit mode to discard parameter - changes and revert to the pre-edit state. - """ - actions: list[HistoryAction] - if isinstance(item, HistorySession): - actions = [ - a for a in item.actions if a.kind == HistoryAction.KIND_COMPUTE - ] - else: - actions = [item] - for action in actions: - if not action.has_pending_edits: - continue - action.restore_kwargs() - self.tree.refresh_action_item(action) - self._recompute_action_in_place(action) - self.recompute_cascade(action) - # Snapshots may have been consumed: refresh button states so the - # Restore action disables itself once no pending edits remain - # (relevant outside Edit mode after a save/reload restore). - self.__update_actions_state() - - def _find_parent_session(self, action: HistoryAction) -> HistorySession | None: - """Return the session that contains ``action``, or None if not found. - - Args: - action: Action to search for. - - Returns: - Parent :class:`HistorySession`, or ``None``. - """ - for session in self.__history_sessions: - if action in session.actions: - return session - return None - - # ------------------------------------------------------------------ - # Sync History tree selection → Signal/Image panel (B1) - # ------------------------------------------------------------------ - - def __resolve_panel_for_action( - self, action: HistoryAction - ) -> BaseDataPanel | None: - """Return the data panel targeted by ``action``, or ``None``.""" - if action.kind != HistoryAction.KIND_COMPUTE: - return None - if action.panel_str == "signal": - return self.mainwindow.signalpanel - if action.panel_str == "image": - return self.mainwindow.imagepanel - return None - - def __find_output_object_uuid( - self, panel: BaseDataPanel, action: HistoryAction - ) -> str | None: - """Find the UUID of the output object produced by ``action`` in ``panel``. - - Primary path: consult the bijective ``_action_output_uuids`` mapping - populated when the action was recorded (or rebuilt from HDF5 at load). - Returns the first registered output that still exists in ``panel``. - - Fallback path (legacy v1 sessions, or actions whose outputs were - re-created without registration): search the panel for an object whose - ``processing_parameters`` metadata has ``source_uuid`` matching one of - the action's recorded selection UUIDs and whose ``func_name`` equals - the action's ``func_name``. - """ - # Primary: bijective mapping (C1). - registered = self._action_output_uuids.get(action.uuid) - if registered: - existing_ids = set(panel.objmodel.get_object_ids()) - for out_uuid in registered: - if out_uuid in existing_ids: - return out_uuid - # Fallback heuristic for legacy sessions. - if action.func_name is None: - return None - from datalab.gui.processor.base import ( # pylint: disable=import-outside-toplevel - extract_processing_parameters, - ) - - recorded_uuids = set(action.state.selection.get(panel.PANEL_STR_ID, [])) - if not recorded_uuids: - return None - for obj in panel.objmodel: - pp = extract_processing_parameters(obj) - if pp is None or pp.func_name != action.func_name: - continue - if pp.source_uuid is not None and pp.source_uuid in recorded_uuids: - return get_uuid(obj) - if pp.source_uuids is not None and recorded_uuids.intersection( - pp.source_uuids - ): - return get_uuid(obj) - return None - - def find_action_for_output( - self, output_uuid: str, func_name: str - ) -> HistoryAction | None: - """Find the :class:`HistoryAction` that produced ``output_uuid``. - - Primary path: consult the bijective ``_output_to_action`` mapping. This - is exact and resolves the ambiguity of repeated applications of the - same ``func_name`` on the same source. - - Fallback path: searches all sessions (most-recent first) using the - heuristic ``(func_name, source_uuid)`` matching for legacy v1 sessions - without a registered output mapping. - - Args: - output_uuid: UUID of the output object (signal or image). - func_name: Processing function name expected on the action. - - Returns: - The matching action, or ``None`` if no match is found. - """ - if not self.__history_sessions: - return None - # Primary: bijective mapping (C1). - action_uuid = self._output_to_action.get(output_uuid) - if action_uuid is not None: - for session in self.__history_sessions: - for action in session.actions: - if action.uuid == action_uuid: - # Sanity check: func_name must still match. - if action.func_name == func_name: - return action - return None - # Fallback heuristic for legacy sessions. - from datalab.gui.processor.base import ( # pylint: disable=import-outside-toplevel - extract_processing_parameters, - ) - - # Find which panel contains output_uuid - panel: BaseDataPanel | None = None - output_obj = None - for p in (self.mainwindow.signalpanel, self.mainwindow.imagepanel): - try: - output_obj = p.objmodel[output_uuid] - panel = p - break - except KeyError: - continue - if panel is None or output_obj is None: - return None - pp = extract_processing_parameters(output_obj) - if pp is None or pp.func_name != func_name: - return None - target_source_uuid = pp.source_uuid - if target_source_uuid is None: - return None - # Search every session (most-recent first) instead of only [-1]. - # Uniqueness is guaranteed by target_source_uuid (remapped per-session - # during duplication). - for current_session in reversed(self.__history_sessions): - for action in reversed(current_session.actions): - if action.kind != HistoryAction.KIND_COMPUTE: - continue - if action.func_name != func_name: - continue - if action.panel_str != panel.PANEL_STR_ID: - continue - captured = action.state.selection.get(panel.PANEL_STR_ID, []) - if captured and captured[0] == target_source_uuid: - return action - return None - - def refresh_action(self, action: HistoryAction) -> None: - """Refresh the tree display for ``action`` after its kwargs were mutated. - - Used by :meth:`ObjectProp.apply_processing_parameters` to update the - Description column when the user edits a ``param`` from the Processing - tab of the Signal/Image panel. - """ - self.tree.refresh_action_item(action) - - # ------------------------------------------------------------------ - # B4: Cascade recompute of downstream actions after a param edit - # ------------------------------------------------------------------ - - def _get_session_of(self, action: HistoryAction) -> HistorySession | None: - """Return the session that contains ``action``, or None.""" - for session in self.__history_sessions: - if action in session.actions: - return session - return None - - def _action_output_uuid(self, action: HistoryAction) -> str | None: - """Return the UUID of the object produced by ``action``, or ``None``. - - Scans the target panel's object model for an object whose - :class:`ProcessingParameters` metadata matches the action's - ``func_name`` and one of its captured source UUIDs. - """ - panel = self.__resolve_panel_for_action(action) - if panel is None: - return None - return self.__find_output_object_uuid(panel, action) - - def _action_consumes_any( - self, action: HistoryAction, uuids: set[str] - ) -> bool: - """Return True if ``action``'s input UUIDs intersect ``uuids``.""" - if action.kind != HistoryAction.KIND_COMPUTE: - return False - pstr = action.panel_str or "" - captured: set[str] = set(action.state.selection.get(pstr, [])) - obj2 = action.kwargs.get("obj2_uuids") - if obj2: - if isinstance(obj2, str): - captured.add(obj2) - else: - captured.update(obj2) - return bool(captured & uuids) - - def _collect_downstream_uuids(self, action: HistoryAction) -> set[str]: - """Return the transitive closure of output UUIDs descending from - ``action`` within the current session (excluding ``action`` itself). - """ - if not self.__history_sessions: - return set() - current = self._get_session_of(action) - if current is None: - return set() - root_out = self._action_output_uuid(action) - if root_out is None: - return set() - closure: set[str] = {root_out} - # Walk only actions positioned strictly after ``action`` in the - # current session, in chronological order. - idx = current.actions.index(action) - for downstream in current.actions[idx + 1 :]: - if downstream.kind != HistoryAction.KIND_COMPUTE: - continue - if not self._action_consumes_any(downstream, closure): - continue - out_uuid = self._action_output_uuid(downstream) - if out_uuid is not None: - closure.add(out_uuid) - closure.discard(root_out) - return closure - - def get_downstream_actions( - self, action: HistoryAction - ) -> list[HistoryAction]: - """Return the actions of the current session that depend (transitively) - on ``action``'s output, in topological order (direct children first). - """ - if not self.__history_sessions: - return [] - current = self._get_session_of(action) - if current is None: - return [] - root_out = self._action_output_uuid(action) - if root_out is None: - return [] - closure: set[str] = {root_out} - downstream: list[HistoryAction] = [] - idx = current.actions.index(action) - for candidate in current.actions[idx + 1 :]: - if candidate.kind != HistoryAction.KIND_COMPUTE: - continue - if not self._action_consumes_any(candidate, closure): - continue - downstream.append(candidate) - out_uuid = self._action_output_uuid(candidate) - if out_uuid is not None: - closure.add(out_uuid) - return downstream - - # ------------------------------------------------------------------ - # In-place recompute dispatcher (C2): one helper per pattern. - # - # All helpers retrieve the existing output object(s) via the bijective - # ``_action_output_uuids`` mapping (C1), recompute via the processor's - # ``recompute_*`` methods (which do not register history nor add to the - # panel), then update the existing object in place (data + title + - # metadata) and refresh the view. Missing output objects (deleted by - # the user) are reported via :attr:`_cascade_warnings`. - # ------------------------------------------------------------------ - - def _resolve_target_outputs( - self, panel: BaseDataPanel, action: HistoryAction - ) -> tuple[list[str], list[str]]: - """Return ``(existing, missing)`` UUIDs registered for ``action``. - - Args: - panel: Data panel owning the action's outputs. - action: History action whose outputs must be resolved. - - Returns: - A pair of UUID lists: those still present in ``panel`` (in - registration order) and those that were deleted. - """ - registered = list(self._action_output_uuids.get(action.uuid, [])) - existing_ids = set(panel.objmodel.get_object_ids()) - existing: list[str] = [u for u in registered if u in existing_ids] - missing: list[str] = [u for u in registered if u not in existing_ids] - return existing, missing - - def _update_obj_in_place( - self, - target_obj: SignalObj | ImageObj, - new_obj: SignalObj | ImageObj, - ) -> None: - """Copy data + title + metadata from ``new_obj`` onto ``target_obj``. - - Preserves the target's identity (UUID, panel position, references) - while reflecting all user-visible changes produced by a recompute. - - Args: - target_obj: Existing object to mutate in place. - new_obj: Fresh object produced by a ``recompute_*`` call. - """ - target_obj.title = new_obj.title - if isinstance(target_obj, SignalObj): - target_obj.xydata = new_obj.xydata - else: - target_obj.data = new_obj.data - target_obj.invalidate_maskdata_cache() - # Replace compute-related metadata with the fresh set. In Edit mode - # the object is updated in place (not recreated), so stale analysis - # result keys (Geometry_*, Table_*) or obsolete metadata options from - # the previous compute would persist with a simple ``update()``. - # We clear and repopulate, but preserve the target's ``__uuid`` which - # is its identity key managed by the object model. - try: - saved_uuid = target_obj.metadata.get("__uuid") - saved_number = target_obj.metadata.get("__number") - target_obj.metadata.clear() - target_obj.metadata.update(new_obj.metadata) - if saved_uuid is not None: - target_obj.metadata["__uuid"] = saved_uuid - if saved_number is not None: - target_obj.metadata["__number"] = saved_number - except AttributeError: - pass - - def _refresh_target( - self, panel: BaseDataPanel, output_uuid: str - ) -> None: - """Refresh tree item + plot for ``output_uuid`` in ``panel``. - - Also updates the Properties panel when the refreshed object is - currently selected, marks the object as freshly processed so the - Processing tab is shown, and emits ``SIG_OBJECT_MODIFIED`` so - that compatibility icons are refreshed. - """ - panel.objview.update_item(output_uuid) - panel.refresh_plot(output_uuid, update_items=True, force=True) - - # Update the Properties panel if the recomputed object is selected - try: - obj = panel.objmodel[output_uuid] - except KeyError: - obj = None - if obj is not None: - if obj is panel.objview.get_current_object(): - panel.objprop.update_properties_from(obj, force_tab="processing") - else: - # Mark as freshly processed so the Processing tab opens on select - panel.objprop.mark_as_freshly_processed(obj) - - # Notify listeners (e.g. compatibility icons in history tree) - panel.SIG_OBJECT_MODIFIED.emit() - - def _record_missing_outputs( - self, action: HistoryAction, missing: list[str] - ) -> None: - """Log + queue a user-facing warning for deleted output objects.""" - if not missing: - return - name = action.func_name or action.title or action.uuid - _logger.warning( - "Cascade recompute: %d output(s) missing for action %s (%s).", - len(missing), - action.uuid, - name, - ) - self._cascade_warnings.append( - _( - "Action %s has been edited but its target output object(s) " - "no longer exist — skipping." - ) - % name - ) - - def _recompute_action_in_place(self, action: HistoryAction) -> None: - """Re-run ``action`` on the existing output object(s) (same UUIDs). - - Dispatches to a per-pattern helper. Missing target outputs are - recorded in :attr:`_cascade_warnings` and silently skipped so the - rest of the cascade can keep running. - - When the underlying processor feature is missing (e.g. the originating - plugin was uninstalled), :class:`FeatureNotFoundError` is caught here - and the action is flagged as broken (``is_stale`` left at ``True`` - beyond the cascade so the visual marker persists). A localised warning - including the plugin origin and required parameter class is appended - to :attr:`_cascade_warnings`. The cascade continues with the remaining - actions. - - Args: - action: History action to recompute in place. - """ - if action.kind != HistoryAction.KIND_COMPUTE: - return - method = { - "1_to_1": self._recompute_1_to_1_in_place, - "1_to_n": self._recompute_1_to_n_in_place, - "n_to_1": self._recompute_n_to_1_in_place, - "2_to_1": self._recompute_2_to_1_in_place, - "1_to_0": self._recompute_1_to_0_in_place, - }.get(action.pattern or "") - if method is None: - _logger.warning( - "Cascade recompute: unsupported pattern %r for action %s.", - action.pattern, - action.uuid, - ) - self._cascade_warnings.append( - _("Action %s uses pattern %r which is not recomputable yet.") - % (action.func_name or action.uuid, action.pattern) - ) - return - from datalab.gui.processor.base import ( # pylint: disable=import-outside-toplevel - FeatureNotFoundError, - ) - - try: - method(action) - except FeatureNotFoundError as exc: - self._handle_missing_feature(action, exc) - except Exception as exc: # pylint: disable=broad-except - _logger.exception( - "Cascade recompute failed for action %s (%s): %s", - action.uuid, - action.func_name, - exc, - ) - self._cascade_warnings.append( - _("Recompute failed for action %s: %s") - % (action.func_name or action.uuid, exc) - ) - - def _handle_missing_feature( - self, action: HistoryAction, exc: "FeatureNotFoundError" - ) -> None: - """Flag ``action`` as broken (missing plugin) and queue a user warning. - - Args: - action: Action whose feature could not be resolved. - exc: The raised :class:`FeatureNotFoundError`. - ``action.plugin_origin`` is the authoritative source. - ``exc.plugin_origin`` is kept only as a safety net for future - paths where ``get_feature`` might be called without forwarding - the action's ``plugin_origin``. - """ - action.is_stale = True - self._broken_actions.add(action.uuid) - plugin_origin = action.plugin_origin or exc.plugin_origin or {} - directory = (plugin_origin.get("directory") if plugin_origin else None) or "?" - param = action.kwargs.get("param") - paramclass = ( - exc.paramclass_name - or (type(param).__name__ if param is not None else "—") - ) - func_name = action.func_name or exc.func_name or action.uuid - # Format validated with the operator: "{directory}/plugins:{func_name}" - location = f"{directory}/plugins:{func_name}" - _logger.warning( - "Cascade recompute: plugin missing for action %s (%s) — %s.", - action.uuid, - func_name, - location, - ) - self._cascade_warnings.append( - _( - "Action %(name)s skipped: plugin '%(loc)s' is missing.\n" - "Required parameter class: %(param)s\n" - "Reinstall the plugin to re-enable this action." - ) - % {"name": func_name, "loc": location, "param": paramclass} - ) - - def _recompute_1_to_1_in_place(self, action: HistoryAction) -> None: - """Recompute a single 1-to-1 action in place.""" - panel = self.__resolve_panel_for_action(action) - if panel is None: - return - from datalab.gui.processor.base import ( # pylint: disable=import-outside-toplevel - ProcessingParameters, - extract_processing_parameters, - insert_processing_parameters, - ) - - existing, missing = self._resolve_target_outputs(panel, action) - # Fall back to legacy heuristic when bijective mapping is unavailable. - if not existing and not missing: - legacy = self.__find_output_object_uuid(panel, action) - if legacy is not None: - existing = [legacy] - self._record_missing_outputs(action, missing) - if not existing: - return - output_uuid = existing[0] - try: - output_obj = panel.objmodel[output_uuid] - except KeyError: - return - pp = extract_processing_parameters(output_obj) - if pp is None or pp.source_uuid is None: - return - try: - source_obj = panel.objmodel[pp.source_uuid] - except KeyError: - self._cascade_warnings.append( - _("Action %s: source object was deleted — skipping.") - % (action.func_name or action.uuid) - ) - return - param = action.kwargs.get("param") - new_obj = panel.processor.recompute_1_to_1( - action.func_name, source_obj, param, - plugin_origin=action.plugin_origin, - ) - if new_obj is None: - return - self._update_obj_in_place(output_obj, new_obj) - insert_processing_parameters( - output_obj, - ProcessingParameters( - func_name=pp.func_name, - pattern=pp.pattern, - param=param if param is not None else pp.param, - source_uuid=pp.source_uuid, - ), - ) - panel.processor.auto_recompute_analysis(output_obj) - self._refresh_target(panel, output_uuid) - - def _recompute_1_to_n_in_place(self, action: HistoryAction) -> None: - """Recompute a 1-to-n action in place: replace each of the N outputs.""" - panel = self.__resolve_panel_for_action(action) - if panel is None: - return - from datalab.gui.processor.base import ( # pylint: disable=import-outside-toplevel - ProcessingParameters, - extract_processing_parameters, - insert_processing_parameters, - ) - - existing, missing = self._resolve_target_outputs(panel, action) - self._record_missing_outputs(action, missing) - if not existing: - return - # All outputs of a 1_to_n share the same source. - try: - first_obj = panel.objmodel[existing[0]] - except KeyError: - return - pp = extract_processing_parameters(first_obj) - if pp is None or pp.source_uuid is None: - return - try: - source_obj = panel.objmodel[pp.source_uuid] - except KeyError: - self._cascade_warnings.append( - _("Action %s: source object was deleted — skipping.") - % (action.func_name or action.uuid) - ) - return - params = action.kwargs.get("params") or [] - if not params: - return - new_objs = panel.processor.recompute_1_to_n( - action.func_name, source_obj, params, - plugin_origin=action.plugin_origin, - ) - if not new_objs: - return - # Map each output to its (re)computed counterpart by index. If the - # cardinality changed (e.g. function now produces fewer outputs), - # we update what we can and report the rest as missing. - n = min(len(existing), len(new_objs)) - for idx in range(n): - out_uuid = existing[idx] - try: - out_obj = panel.objmodel[out_uuid] - except KeyError: - continue - new_obj = new_objs[idx] - self._update_obj_in_place(out_obj, new_obj) - new_param = params[idx] if idx < len(params) else None - insert_processing_parameters( - out_obj, - ProcessingParameters( - func_name=action.func_name, - pattern="1-to-n", - param=new_param, - source_uuid=pp.source_uuid, - ), - ) - panel.processor.auto_recompute_analysis(out_obj) - self._refresh_target(panel, out_uuid) - if len(new_objs) != len(existing): - _logger.warning( - "1-to-n cardinality changed for action %s: %d outputs, %d existing.", - action.uuid, - len(new_objs), - len(existing), - ) - - def _recompute_n_to_1_in_place(self, action: HistoryAction) -> None: - """Recompute an n-to-1 action in place.""" - panel = self.__resolve_panel_for_action(action) - if panel is None: - return - from datalab.gui.processor.base import ( # pylint: disable=import-outside-toplevel - ProcessingParameters, - extract_processing_parameters, - insert_processing_parameters, - ) - - existing, missing = self._resolve_target_outputs(panel, action) - self._record_missing_outputs(action, missing) - if not existing: - return - output_uuid = existing[0] - try: - output_obj = panel.objmodel[output_uuid] - except KeyError: - return - pp = extract_processing_parameters(output_obj) - source_uuids: list[str] = [] - if pp is not None and pp.source_uuids: - source_uuids = list(pp.source_uuids) - else: - source_uuids = list( - action.state.selection.get(panel.PANEL_STR_ID, []) - ) - src_objs: list[SignalObj | ImageObj] = [] - for uuid in source_uuids: - try: - src_objs.append(panel.objmodel[uuid]) - except KeyError: - continue - if not src_objs: - self._cascade_warnings.append( - _("Action %s: all source objects were deleted — skipping.") - % (action.func_name or action.uuid) - ) - return - param = action.kwargs.get("param") - new_obj = panel.processor.recompute_n_to_1( - action.func_name, src_objs, param, - plugin_origin=action.plugin_origin, - ) - if new_obj is None: - return - self._update_obj_in_place(output_obj, new_obj) - insert_processing_parameters( - output_obj, - ProcessingParameters( - func_name=action.func_name, - pattern="n-to-1", - param=param, - source_uuids=[get_uuid(o) for o in src_objs], - ), - ) - panel.processor.auto_recompute_analysis(output_obj) - self._refresh_target(panel, output_uuid) - - def _recompute_2_to_1_in_place(self, action: HistoryAction) -> None: - """Recompute a 2-to-1 action in place (single or pairwise).""" - panel = self.__resolve_panel_for_action(action) - if panel is None: - return - from datalab.gui.processor.base import ( # pylint: disable=import-outside-toplevel - ProcessingParameters, - extract_processing_parameters, - insert_processing_parameters, - ) - - existing, missing = self._resolve_target_outputs(panel, action) - self._record_missing_outputs(action, missing) - if not existing: - return - param = action.kwargs.get("param") - obj2_uuids = action.kwargs.get("obj2_uuids") or [] - if isinstance(obj2_uuids, str): - obj2_uuids = [obj2_uuids] - pairwise = bool(action.kwargs.get("pairwise")) - # In pairwise mode, expect one output per (obj1, obj2) pair. - # In single-operand mode, every output uses the same obj2. - recorded_inputs = list(action.state.selection.get(panel.PANEL_STR_ID, [])) - for idx, out_uuid in enumerate(existing): - try: - output_obj = panel.objmodel[out_uuid] - except KeyError: - continue - pp = extract_processing_parameters(output_obj) - src_uuids = ( - list(pp.source_uuids) - if pp is not None and pp.source_uuids - else (recorded_inputs[idx : idx + 1] + obj2_uuids[idx : idx + 1] - if pairwise - else recorded_inputs[idx : idx + 1] + obj2_uuids[:1]) - ) - if len(src_uuids) < 2: - self._cascade_warnings.append( - _("Action %s: missing source(s) for output #%d — skipping.") - % (action.func_name or action.uuid, idx + 1) - ) - continue - try: - obj1 = panel.objmodel[src_uuids[0]] - obj2 = panel.objmodel[src_uuids[1]] - except KeyError: - self._cascade_warnings.append( - _("Action %s: source object(s) were deleted — skipping.") - % (action.func_name or action.uuid) - ) - continue - new_obj = panel.processor.recompute_2_to_1( - action.func_name, obj1, obj2, param, - plugin_origin=action.plugin_origin, - ) - if new_obj is None: - continue - self._update_obj_in_place(output_obj, new_obj) - insert_processing_parameters( - output_obj, - ProcessingParameters( - func_name=action.func_name, - pattern="2-to-1", - param=param, - source_uuids=[get_uuid(obj1), get_uuid(obj2)], - ), - ) - panel.processor.auto_recompute_analysis(output_obj) - self._refresh_target(panel, out_uuid) - - def _recompute_1_to_0_in_place(self, action: HistoryAction) -> None: - """Recompute a 1-to-0 analysis on each source object in place.""" - panel = self.__resolve_panel_for_action(action) - if panel is None: - return - # 1-to-0 produces no data object; recompute on each captured source - # so analysis metadata stays consistent with the (possibly updated) - # data of upstream actions. - sources = list(action.state.selection.get(panel.PANEL_STR_ID, [])) - if not sources: - return - param = action.kwargs.get("param") - missing: list[str] = [] - for uuid in sources: - try: - src_obj = panel.objmodel[uuid] - except KeyError: - missing.append(uuid) - continue - panel.processor.recompute_1_to_0( - action.func_name, src_obj, param, - plugin_origin=action.plugin_origin, - ) - self._refresh_target(panel, uuid) - if missing: - self._cascade_warnings.append( - _("Action %s: %d analysed object(s) were deleted — skipping.") - % (action.func_name or action.uuid, len(missing)) - ) - - def recompute_cascade( - self, - root_action: HistoryAction, - descendants: list[HistoryAction] | None = None, - ) -> None: - """Recompute ``root_action``'s descendants in the current session - in-place (on existing UUIDs). - - Each action involved is flagged ``is_stale`` (light-orange background - in the tree) for the duration of the recompute, then cleared. The - root action itself is normally NOT recomputed here (the caller has - already updated its output object). For a stale Play, ``root_action`` - is included so its own flag is cleared. - - Every supported pattern (``1_to_1``, ``1_to_n``, ``n_to_1``, - ``2_to_1``, ``1_to_0``) is dispatched through - :meth:`_recompute_action_in_place`. Missing or unsupported items - are reported via a single end-of-cascade warning dialog. - - Actions whose underlying processor feature is missing (e.g. plugin - uninstalled) keep ``is_stale = True`` after the cascade completes, - so the visual marker persists until the plugin is reinstalled. - - Args: - root_action: Root action whose descendants must be recomputed. - descendants: Pre-computed downstream actions. When ``None`` - (default), :meth:`get_downstream_actions` is called - internally. Passing a pre-computed list avoids a redundant - graph traversal when the caller has already resolved the - chain (e.g. :meth:`_edit_mode_replay`). - """ - if descendants is None: - descendants = self.get_downstream_actions(root_action) - if root_action.is_stale: - descendants = [root_action] + descendants - # Re-entrancy guard. - if getattr(self, "_cascade_in_progress", False): - self._flush_cascade_warnings() - return - if not descendants: - # Still surface any warnings accumulated by a prior standalone - # ``_recompute_action_in_place`` call (e.g. root recompute in - # ``_edit_mode_replay``) before bailing out. - self._flush_cascade_warnings() - return - # Reset the broken set: only the current cascade's outcomes count. - self._broken_actions.clear() - self._cascade_in_progress = True - try: - for action in descendants: - action.is_stale = True - self.tree.refresh_action_item(action) - QW.QApplication.processEvents() - for action in descendants: - try: - self._recompute_action_in_place(action) - finally: - # Keep the stale marker for actions flagged as broken - # (missing plugin) so the user can spot them in the tree. - if action.uuid not in self._broken_actions: - action.is_stale = False - self.tree.refresh_action_item(action) - QW.QApplication.processEvents() - finally: - for action in descendants: - if action.is_stale and action.uuid not in self._broken_actions: - action.is_stale = False - self.tree.refresh_action_item(action) - self._cascade_in_progress = False - self._flush_cascade_warnings() - - def _flush_cascade_warnings(self) -> None: - """Show + clear accumulated cascade warnings (no-op when empty).""" - if self._cascade_warnings: - QW.QMessageBox.warning( - self.mainwindow, - _("Cascade recompute"), - _("Some downstream actions could not be recomputed:") - + "\n\n• " - + "\n• ".join(self._cascade_warnings), - ) - self._cascade_warnings = [] - - - def __existing_input_uuids( - self, panel: BaseDataPanel, action: HistoryAction - ) -> list[str]: - """Return recorded input UUIDs that still exist in ``panel``.""" - recorded = action.state.selection.get(panel.PANEL_STR_ID, []) - existing: list[str] = [] - for uuid in recorded: - try: - panel.objmodel[uuid] - except KeyError: - continue - existing.append(uuid) - return existing - - def __sync_panel_selection(self) -> None: - """Sync data panel selection from the currently selected tree item.""" - if self.__replaying or self.__syncing: - return - item = self.tree.currentItem() - if item is None or not item.isSelected(): - return - if item.parent() is None: - # Session-level selection: peek the first compute action - index = self.tree.indexOfTopLevelItem(item) - if index < 0 or index >= len(self.__history_sessions): - return - session = self.__history_sessions[index] - action = next( - (a for a in session.actions if a.kind == HistoryAction.KIND_COMPUTE), - None, - ) - if action is None: - return - else: - uuid = item.data(0, QC.Qt.UserRole) - try: - action = self.tree.get_action_from_uuid( - uuid, self.__history_sessions - ) - except ValueError: - return - - panel = self.__resolve_panel_for_action(action) - if panel is None: - return - - target_uuids: list[str] = [] - output_uuid = self.__find_output_object_uuid(panel, action) - if output_uuid is not None: - target_uuids = [output_uuid] - else: - target_uuids = self.__existing_input_uuids(panel, action) - - if not target_uuids: - return - - self.__syncing = True - try: - with QC.QSignalBlocker(panel.objview): - panel.objview.select_objects(target_uuids) - self.mainwindow.set_current_panel(panel) - finally: - self.__syncing = False - - # ------------------------------------------------------------------ - # Step-by-step navigation (B2) - # ------------------------------------------------------------------ - - def __current_action(self) -> HistoryAction | None: - """Return the action currently selected in the tree, or ``None``.""" - item = self.tree.currentItem() - if item is None or item.parent() is None: - return None - uuid = item.data(0, QC.Qt.UserRole) - try: - return self.tree.get_action_from_uuid(uuid, self.__history_sessions) - except ValueError: - return None - - def __current_session(self) -> HistorySession | None: - """Return the session relevant for step navigation.""" - item = self.tree.currentItem() - if item is not None: - if item.parent() is None: - index = self.tree.indexOfTopLevelItem(item) - if 0 <= index < len(self.__history_sessions): - return self.__history_sessions[index] - else: - action = self.__current_action() - if action is not None: - return self._find_parent_session(action) - if self.__history_sessions: - return self.__history_sessions[-1] - return None - - def __can_step_prev(self) -> bool: - """Return True if a previous action exists in the current session.""" - session = self.__current_session() - if session is None or not session.actions: - return False - action = self.__current_action() - if action is None or action not in session.actions: - return False - return session.actions.index(action) > 0 - - def __can_step_next(self) -> bool: - """Return True if a next action exists in the current session.""" - session = self.__current_session() - if session is None or not session.actions: - return False - action = self.__current_action() - if action is None or action not in session.actions: - # No action selected — Next would land on the first one. - return True - return session.actions.index(action) < len(session.actions) - 1 - - def __select_action_in_tree(self, action: HistoryAction) -> None: - """Select ``action`` in the tree (triggers `__sync_panel_selection`).""" - for i in range(self.tree.topLevelItemCount()): - sess_item = self.tree.topLevelItem(i) - for j in range(sess_item.childCount()): - child = sess_item.child(j) - if child.data(0, QC.Qt.UserRole) == action.uuid: - self.tree.clearSelection() - self.tree.setCurrentItem(child) - child.setSelected(True) - return - - def _step_prev(self) -> None: - """Select the previous action in the current session.""" - if not self.__can_step_prev(): - return - session = self.__current_session() - action = self.__current_action() - idx = session.actions.index(action) - self.__select_action_in_tree(session.actions[idx - 1]) - self.__update_actions_state() - - def _step_next(self) -> None: - """Select the next action in the current session.""" - if not self.__can_step_next(): - return - session = self.__current_session() - action = self.__current_action() - if action is None or action not in session.actions: - target = session.actions[0] - else: - target = session.actions[session.actions.index(action) + 1] - self.__select_action_in_tree(target) - self.__update_actions_state() - - def duplicate_selected_entries(self) -> None: - """Duplicate selected sessions (with their data) into new independent sessions. - - For each selected session (or the parent session of a selected action), - all referenced data objects are deep-copied into a new group and the - session is duplicated with all UUID references rewritten to the clones. - The result is an independent, editable and replayable session. - """ - selected = self.tree.get_selected_actions_or_sessions(self.__history_sessions) - if not selected: - return - # Normalise: resolve individual actions to their parent session, deduplicate. - sessions_to_dup: list[HistorySession] = [] - seen: set[int] = set() - for item in selected: - if isinstance(item, HistorySession): - session = item - else: - session = self._find_parent_session(item) - if session is None: - continue - if id(session) not in seen: - seen.add(id(session)) - sessions_to_dup.append(session) - - copy_suffix = _("Copy") - new_sessions: list[HistorySession] = [] - panel_map = { - "signal": self.mainwindow.signalpanel, - "image": self.mainwindow.imagepanel, - } - - for session in sessions_to_dup: - # 1. Collect all UUIDs referenced by this session - uuids_by_panel: dict[str, set[str]] = {} - for action in session.actions: - for pstr, uuids in action.state.selection.items(): - uuids_by_panel.setdefault(pstr, set()).update(uuids) - for pstr, metadata in action.state.object_metadata.items(): - uuids_by_panel.setdefault(pstr, set()).update(metadata.keys()) - obj2 = action.kwargs.get("obj2_uuids") - if obj2: - pstr = action.panel_str or "" - if isinstance(obj2, str): - obj2 = [obj2] - uuids_by_panel.setdefault(pstr, set()).update(obj2) - # Output UUIDs produced by this action (e.g. result of a - # compute step). Without this, the last action's outputs - # would be missing because no subsequent state captures them. - if action.output_uuids: - pstr = action.panel_str or "" - uuids_by_panel.setdefault(pstr, set()).update( - action.output_uuids - ) - - # 2. Clone objects and build uuid_remap - uuid_remap: dict[str, dict[str, str]] = {} - clones_by_pstr: dict[str, list] = {} - group_title = f"{copy_suffix} - {session.title}" - for pstr, uuids in uuids_by_panel.items(): - panel = panel_map.get(pstr) - if panel is None: - continue - uuid_remap[pstr] = {} - existing_ids = set(panel.objmodel.get_object_ids()) - clones = [] - # Iterate in panel order (not set order) to preserve - # the topological object ordering in the duplicated group. - ordered_ids = [ - u for u in panel.objmodel.get_object_ids() if u in uuids - ] - for old_uuid in ordered_ids: - if old_uuid not in existing_ids: - continue - obj = panel.objmodel[old_uuid] - clone = deepcopy(obj) - new_uuid = str(uuid4()) - # SignalObj/ImageObj store UUID via metadata option - try: - clone.set_metadata_option("uuid", new_uuid) - except AttributeError: - clone.uuid = new_uuid - uuid_remap[pstr][old_uuid] = new_uuid - clones.append(clone) - clones_by_pstr[pstr] = clones - if clones: - group_id = get_uuid(panel.add_group(group_title)) - for clone in clones: - panel.add_object(clone, group_id=group_id) - - # Second pass: remap source UUIDs in cloned objects' - # processing_parameters so reprocessing in the Processing tab - # uses the cloned source, not the original. - from datalab.gui.processor.base import ( # pylint: disable=import-outside-toplevel - PROCESSING_PARAMETERS_OPTION, - ProcessingParameters, - ) - - for pstr_inner, clones_inner in clones_by_pstr.items(): - pmap = uuid_remap.get(pstr_inner, {}) - if not pmap: - continue - for clone in clones_inner: - try: - pp_dict = clone.get_metadata_option( - PROCESSING_PARAMETERS_OPTION - ) - except (AttributeError, ValueError): - continue - if not pp_dict: - continue - try: - pp = ProcessingParameters.from_dict(pp_dict) - except Exception: # pylint: disable=broad-except - continue - changed = False - if pp.source_uuid is not None and pp.source_uuid in pmap: - pp.source_uuid = pmap[pp.source_uuid] - changed = True - if pp.source_uuids is not None: - new_src = [pmap.get(u, u) for u in pp.source_uuids] - if new_src != pp.source_uuids: - pp.source_uuids = new_src - changed = True - if changed: - try: - clone.set_metadata_option( - PROCESSING_PARAMETERS_OPTION, pp.to_dict() - ) - except (AttributeError, ValueError): - pass - - # 3. Build the new session with remapped UUIDs - self.__session_increment += 1 - title = f"{session.title} {copy_suffix}" - new_session = session.copy_with_uuid_remap( - title=title, uuid_remap=uuid_remap - ) - new_session.number = self.__session_increment - new_sessions.append(new_session) - - # Register output mappings for cloned actions so that - # _resolve_target_outputs / get_downstream_actions work on - # the duplicated session (same logic as read_h5_data). - for action in new_session.actions: - if action.output_uuids: - self._action_output_uuids[action.uuid] = list( - action.output_uuids - ) - for out_uuid in action.output_uuids: - self._output_to_action[out_uuid] = action.uuid - - # Insert each duplicated session immediately after its original. - offset = 0 - for original_session, new_session in zip(sessions_to_dup, new_sessions): - idx = self.__history_sessions.index(original_session) - self.__history_sessions.insert(idx + 1 + offset, new_session) - offset += 1 - self.tree.populate_tree(self.__history_sessions) - self.__select_sessions(new_sessions) - self.refresh_compatibility_items() - self.__update_actions_state() - - def generate_macro(self) -> None: - """Generate a standalone Python script from selected history entries. - - The generated script uses sigima functions directly with proper variable - chaining. Object references (UUIDs) are resolved to variable names so - that 2-to-1 operations reference the correct intermediate result. - The script is copied to the clipboard and the user is notified. - """ - selected = self.tree.get_selected_actions_or_sessions( - self.__history_sessions - ) - actions: list[HistoryAction] = [] - if not selected: - for session in self.__history_sessions: - actions.extend(session.actions) - else: - for item in selected: - if isinstance(item, HistorySession): - actions.extend(item.actions) - else: - actions.append(item) - if not actions: - return - - # Filter to compute-only actions for the pipeline - compute_actions = [ - a for a in actions if a.kind == HistoryAction.KIND_COMPUTE - ] - if not compute_actions: - QW.QMessageBox.information( - self.mainwindow, - _("Generate macro"), - _("No compute actions to export."), - ) - return - - # Determine input type from first action - first_panel = compute_actions[0].panel_str - if first_panel == "signal": - obj_type = "SignalObj" - obj_import = "from sigima.objects import SignalObj" - else: - obj_type = "ImageObj" - obj_import = "from sigima.objects import ImageObj" - - imports: set[str] = set() - imports.add(obj_import) - body_lines: list[str] = [] - - # UUID → variable mapping for resolving object references. - # Populated with input UUIDs ("src", "src_2", ...) and enriched - # with each step's output UUID after code generation. - uuid_to_var: dict[str, str] = {} - - # Extra input parameters discovered during generation (second - # operands that are not produced by any previous step). - extra_inputs: list[str] = [] - - # Seed the mapping with the first action's input selection. - first_sel = compute_actions[0].state.selection.get( - compute_actions[0].panel_str, [] - ) - for i, uuid in enumerate(first_sel): - var = "src" if i == 0 else f"src_{i + 1}" - uuid_to_var[uuid] = var - - step = 0 - current_var = "src" - - for action in compute_actions: - step += 1 - - # Resolve input variable from the action's selection UUIDs. - sel_uuids = action.state.selection.get( - action.panel_str or "", [] - ) - if sel_uuids and sel_uuids[0] in uuid_to_var: - input_var = uuid_to_var[sel_uuids[0]] - else: - input_var = current_var - - # Resolve second operand for 2-to-1 patterns. - obj2_var: str | None = None - if action.pattern == "2_to_1": - obj2_uuids = action.kwargs.get("obj2_uuids", []) - if isinstance(obj2_uuids, str): - obj2_uuids = [obj2_uuids] - if obj2_uuids: - obj2_uuid = obj2_uuids[0] - if obj2_uuid in uuid_to_var: - obj2_var = uuid_to_var[obj2_uuid] - else: - # External input — add as function parameter. - obj2_var = f"obj2_{step}" - uuid_to_var[obj2_uuid] = obj2_var - extra_inputs.append(obj2_var) - - code_lines, output_var = action.to_macro_code( - step, input_var, imports, obj2_var=obj2_var - ) - body_lines.extend(code_lines) - body_lines.append("") - - if output_var is not None: - current_var = output_var - # Map the output UUID so subsequent steps can reference it. - output_uuid = self._action_output_uuid(action) - if output_uuid: - uuid_to_var[output_uuid] = output_var - # Also register any new UUIDs from the action's selection - # that we haven't seen yet (secondary selections). - for uuid in sel_uuids[1:]: - if uuid not in uuid_to_var: - uuid_to_var[uuid] = input_var - - # Build the function signature with extra inputs. - params_str = f"src: {obj_type}" - for extra in extra_inputs: - params_str += f", {extra}: {obj_type}" - - # Assemble the full script - sorted_imports = sorted(imports) - script_lines: list[str] = [ - '"""', - "DataLab — standalone processing pipeline", - f"Generated from history ({len(compute_actions)} steps)", - '"""', - "", - ] - script_lines.extend(sorted_imports) - script_lines.append("") - script_lines.append("") - script_lines.append( - f"def process({params_str}) -> {obj_type}:" - ) - script_lines.append( - ' """Apply the recorded processing pipeline."""' - ) - for line in body_lines: - script_lines.append(f" {line}" if line else "") - script_lines.append(f" return {current_var}") - script_lines.append("") - script_lines.append("") - script_lines.append('if __name__ == "__main__":') - script_lines.append( - " # Standalone execution: run from DataLab's Macro panel." - ) - script_lines.append(" # Operates on the current object of the target panel.") - script_lines.append( - " from datalab.control.proxy import RemoteProxy" - ) - script_lines.append("") - script_lines.append(" proxy = RemoteProxy()") - panel_str = compute_actions[0].panel_str or ( - "signal" if obj_type == "SignalObj" else "image" - ) - script_lines.append(f' proxy.set_current_panel("{panel_str}")') - script_lines.append(" src = proxy.get_object()") - script_lines.append(" if src is None:") - script_lines.append( - f' raise RuntimeError("No current object in panel: {panel_str}")' - ) - if extra_inputs: - n_extra = len(extra_inputs) - script_lines.append( - " _uuids = [u for u in proxy.get_sel_object_uuids()" - " if u != src.uuid]" - ) - script_lines.append(f" if len(_uuids) < {n_extra}:") - script_lines.append( - " raise RuntimeError(" - ) - script_lines.append( - f' "Pipeline needs {n_extra} extra selected' - ' object(s) besides the current one"' - ) - script_lines.append(" )") - for idx, extra in enumerate(extra_inputs): - script_lines.append( - f" {extra} = proxy.get_object(" - f'_uuids[{idx}], "{panel_str}")' - ) - extra_args = "".join(f", {e}" for e in extra_inputs) - script_lines.append(f" result = process(src{extra_args})") - script_lines.append(" proxy.add_object(result)") - script_lines.append(' print(f"Pipeline applied: {result.title}")') - script_lines.append("") - - script = "\n".join(script_lines) - QW.QApplication.clipboard().setText(script) - QW.QMessageBox.information( - self.mainwindow, - _("Generate macro"), - _("Macro script copied to clipboard (%d actions).") - % len(compute_actions), - ) - - def __select_sessions(self, sessions: list[HistorySession]) -> None: - """Select top-level tree items matching ``sessions``.""" - self.tree.clearSelection() - for session in sessions: - index = self.__history_sessions.index(session) - item = self.tree.topLevelItem(index) - item.setSelected(True) - self.tree.setCurrentItem(item) - - def delete_selected(self) -> None: - """Delete the selected actions or sessions (with confirmation). - - When a top-level session is selected, the entire session is deleted. - When individual actions are selected, they and all subsequent actions - in their parent session are removed. After deletion, the first - available item in the tree is selected automatically. - """ - selected = self.tree.get_selected_actions_or_sessions(self.__history_sessions) - if not selected: - return - has_individual_actions = any( - isinstance(item, HistoryAction) for item in selected - ) - if has_individual_actions: - msg = _( - "Do you really want to delete the selected items?\n\n" - "Note: deleting an action also removes all subsequent " - "actions in the same session." - ) - else: - msg = _("Do you really want to delete the selected items?") - reply = QW.QMessageBox.question( - self.mainwindow, - _("Delete"), - msg, - QW.QMessageBox.Yes | QW.QMessageBox.No, - QW.QMessageBox.No, - ) - if reply != QW.QMessageBox.Yes: - return - sessions_to_remove: set[int] = set() - for item in selected: - if isinstance(item, HistorySession): - sessions_to_remove.add(id(item)) - else: - # Individual action: remove from its parent session - for session in self.__history_sessions: - if item in session.actions: - session.remove_action(item) - if not session.actions: - sessions_to_remove.add(id(session)) - break - self.__history_sessions = [ - s for s in self.__history_sessions if id(s) not in sessions_to_remove - ] - self.tree.populate_tree(self.__history_sessions) - self.refresh_compatibility_items() - self.__update_actions_state() - # Auto-select the first available item after deletion - if self.tree.topLevelItemCount() > 0: - first = self.tree.topLevelItem(0) - self.tree.setCurrentItem(first) - first.setSelected(True) - - def remove_incompatible_actions(self) -> None: - """Remove all actions whose workspace state is incompatible. - - Shows a confirmation dialog listing how many actions will be removed, - then purges them from their sessions. Empty sessions are also removed. - """ - incompatible: list[tuple[HistorySession, HistoryAction]] = [] - for session in self.__history_sessions: - for action in session.actions: - if not action.is_current_state_compatible( - self.mainwindow, restore_selection=True - ): - incompatible.append((session, action)) - if not incompatible: - QW.QMessageBox.information( - self.mainwindow, - _("Remove incompatible"), - _("All actions are compatible with the current workspace."), - ) - return - reply = QW.QMessageBox.question( - self.mainwindow, - _("Remove incompatible"), - _("%d incompatible action(s) will be removed. Continue?") - % len(incompatible), - QW.QMessageBox.Yes | QW.QMessageBox.No, - QW.QMessageBox.No, - ) - if reply != QW.QMessageBox.Yes: - return - for session, action in incompatible: - if action in session.actions: - session.actions.remove(action) - # Remove empty sessions - self.__history_sessions = [ - s for s in self.__history_sessions if s.actions - ] - self.tree.populate_tree(self.__history_sessions) - self.refresh_compatibility_items() - self.__update_actions_state() - - def save_to_dlhist_file(self, filename: str | None = None) -> bool: - """Save the History Panel content to a standalone ``.dlhist`` file. - - Args: - filename: History filename. If None, a file dialog is opened. - - Returns: - True if the history was saved, False if the operation was canceled. - """ - if filename is None: - basedir = Conf.main.base_dir.get() - with save_restore_stds(): - filename, _filt = getsavefilename( - self, _("Save history file"), basedir, self.FILE_FILTERS - ) - if not filename: - return False - if osp.splitext(filename)[1] == "": - filename += ".dlhist" - with qt_try_loadsave_file(self.parentWidget(), filename, "save"): - Conf.main.base_dir.set(filename) - from datalab.h5.native import NativeH5Writer # pylint: disable=C0415 - - with NativeH5Writer(filename) as writer: - # Make the .dlhist file self-contained: store the signal and - # image panel objects (all of them) alongside the history, so - # that reopening restores both the data objects and the history - # that references them. Each section is read back by its own - # H5_PREFIX key, so the write order is not significant. - self.mainwindow.signalpanel.serialize_to_hdf5(writer) - self.mainwindow.imagepanel.serialize_to_hdf5(writer) - self.serialize_to_hdf5(writer) - return True - - def open_dlhist_file(self, filename: str | None = None) -> bool: - """Open a standalone ``.dlhist`` file into the History Panel. - - Args: - filename: History filename. If None, a file dialog is opened. - - Returns: - True if the history was loaded, False if the operation was canceled. - """ - if filename is None: - basedir = Conf.main.base_dir.get() - with save_restore_stds(): - filename, _filt = getopenfilename( - self, _("Open history file"), basedir, self.FILE_FILTERS - ) - if not filename: - return False - with qt_try_loadsave_file(self.parentWidget(), filename, "load"): - Conf.main.base_dir.set(filename) - from datalab.h5.native import NativeH5Reader # pylint: disable=C0415 - - with NativeH5Reader(filename) as reader: - # A self-contained .dlhist file stores the signal and image - # panel objects in addition to the history sessions. The way - # they are restored depends on whether the workspace is already - # in use (data objects OR history): a pristine workspace is - # loaded directly while preserving UUIDs, otherwise the file - # is imported as new groups/sessions. - workspace_in_use = ( - self.mainwindow.signalpanel.objmodel.get_object_ids() - or self.mainwindow.imagepanel.objmodel.get_object_ids() - or bool(self.__history_sessions) - ) - if workspace_in_use: - # Workspace not empty: import the objects into new groups - # with fresh UUIDs and append the history as new sessions - # whose references are remapped to the imported objects. - self.__import_dlhist_into_new_session(reader) - else: - # Workspace empty: load directly, preserving original UUIDs - # (reset_all=True) so that history references stay valid. - self.mainwindow.signalpanel.deserialize_from_hdf5( - reader, reset_all=True - ) - self.mainwindow.imagepanel.deserialize_from_hdf5( - reader, reset_all=True - ) - self.deserialize_from_hdf5(reader) - return True - - def __import_dlhist_into_new_session(self, reader: NativeH5Reader) -> None: - """Import a ``.dlhist`` file into new groups and new history sessions. - - Used when the workspace already contains objects: the file's signal and - image objects are imported into fresh groups with regenerated UUIDs, and - the history sessions are appended as new independent sessions whose action - references are remapped to the freshly imported objects. - - Args: - reader: HDF5 reader positioned on a ``.dlhist`` file. - """ - panel_map = { - "signal": self.mainwindow.signalpanel, - "image": self.mainwindow.imagepanel, - } - uuid_remap: dict[str, dict[str, str]] = {} - imported_by_pstr: dict[str, list] = {} - # 1. Import objects from each panel (each panel is read by its own - # H5_PREFIX key). Read each object preserving its original UUID to - # capture the old->new mapping, then assign a fresh UUID so that the - # imported objects keep an independent identity. - for pstr, panel in panel_map.items(): - uuid_remap[pstr] = {} - imported: list = [] - imported_by_pstr[pstr] = imported - if panel.H5_PREFIX not in reader.h5: - continue - with reader.group(panel.H5_PREFIX): - for name in reader.h5.get(panel.H5_PREFIX, []): - with reader.group(name): - group = panel.add_group("") - with reader.group("title"): - group.title = reader.read_str() - for obj_name in reader.h5.get( - f"{panel.H5_PREFIX}/{name}", [] - ): - obj = panel.deserialize_object_from_hdf5( - reader, obj_name, reset_all=True - ) - old_uuid = get_uuid(obj) - new_uuid = str(uuid4()) - # SignalObj/ImageObj store UUID via metadata option - try: - obj.set_metadata_option("uuid", new_uuid) - except AttributeError: - obj.uuid = new_uuid - uuid_remap[pstr][old_uuid] = new_uuid - panel.add_object( - obj, get_uuid(group), set_current=False - ) - imported.append(obj) - panel.selection_changed() - # 2. Remap source UUIDs in imported objects' processing_parameters so - # that reprocessing in the Processing tab uses the imported sources, - # not the originals (same logic as duplicate_selected_entries). - from datalab.gui.processor.base import ( # pylint: disable=import-outside-toplevel - PROCESSING_PARAMETERS_OPTION, - ProcessingParameters, - ) - - for pstr, objs in imported_by_pstr.items(): - pmap = uuid_remap.get(pstr, {}) - if not pmap: - continue - for obj in objs: - try: - pp_dict = obj.get_metadata_option(PROCESSING_PARAMETERS_OPTION) - except (AttributeError, ValueError): - continue - if not pp_dict: - continue - try: - pp = ProcessingParameters.from_dict(pp_dict) - except Exception: # pylint: disable=broad-except - continue - changed = False - if pp.source_uuid is not None and pp.source_uuid in pmap: - pp.source_uuid = pmap[pp.source_uuid] - changed = True - if pp.source_uuids is not None: - new_src = [pmap.get(u, u) for u in pp.source_uuids] - if new_src != pp.source_uuids: - pp.source_uuids = new_src - changed = True - if changed: - try: - obj.set_metadata_option( - PROCESSING_PARAMETERS_OPTION, pp.to_dict() - ) - except (AttributeError, ValueError): - pass - # 3. Import history sessions as new independent sessions whose captured - # UUIDs are remapped to the imported objects. - if self.H5_PREFIX not in reader.h5: - return - sessions = reader.read_object_list(self.H5_PREFIX, HistorySession) or [] - imported_suffix = _("Imported") - new_sessions: list[HistorySession] = [] - for session in sessions: - self.__session_increment += 1 - title = f"{session.title} {imported_suffix}" - new_session = session.copy_with_uuid_remap( - title=title, uuid_remap=uuid_remap - ) - new_session.number = self.__session_increment - new_sessions.append(new_session) - # Register output mappings for imported actions so that - # _resolve_target_outputs / get_downstream_actions work. - for action in new_session.actions: - if action.output_uuids: - self._action_output_uuids[action.uuid] = list( - action.output_uuids - ) - for out_uuid in action.output_uuids: - self._output_to_action[out_uuid] = action.uuid - self.__history_sessions.extend(new_sessions) - self.tree.populate_tree(self.__history_sessions) - self.refresh_compatibility_items() - self.__update_actions_state() - - def refresh_compatibility_items(self, *args: Any) -> None: - """Refresh action item compatibility markers in the tree.""" - del args - self.tree.update_compatibility_states(self.__history_sessions, self.mainwindow) - - def serialize_to_hdf5(self, writer: NativeH5Writer) -> None: - """Serialize whole panel to a HDF5 file - - Args: - writer: HDF5 writer - """ - writer.write_object_list(self.__history_sessions, self.H5_PREFIX) - - def deserialize_from_hdf5( - self, reader: NativeH5Reader, reset_all: bool = False - ) -> None: - """Deserialize whole panel from a HDF5 file - - Args: - reader: HDF5 reader - reset_all: Unused (kept for compatibility with panel API) - """ - if self.H5_PREFIX not in reader.h5: - self.__history_sessions = [] - self.__session_increment = 0 - self.tree.populate_tree(self.__history_sessions) - self.__update_actions_state() - return - self.__history_sessions: list[HistorySession] = ( - reader.read_object_list(self.H5_PREFIX, HistorySession) or [] - ) - if self.__history_sessions: - self.__session_increment = self.__history_sessions[-1].number - # Rebuild the bijective mapping from the loaded actions. Legacy - # (v1) actions have empty ``output_uuids`` and contribute nothing - # to the index — the heuristic fallback handles them. - self._action_output_uuids = {} - self._output_to_action = {} - for session in self.__history_sessions: - for action in session.actions: - if action.output_uuids: - self._action_output_uuids[action.uuid] = list( - action.output_uuids - ) - for out_uuid in action.output_uuids: - self._output_to_action[out_uuid] = action.uuid - self.tree.populate_tree(self.__history_sessions) - self.refresh_compatibility_items() - self.__update_actions_state() - - def __len__(self) -> int: - """Return number of objects""" - return sum(len(session.actions) for session in self.__history_sessions) - - def __getitem__(self, nb: int) -> HistoryAction: - """Return object from its number (1 to N)""" - for session in self.__history_sessions: - if nb <= len(session.actions): - return session.actions[nb - 1] - nb -= len(session.actions) - raise IndexError("Index out of range") - - def __iter__(self) -> Generator[HistoryAction, None, None]: - """Iterate over objects""" - for session in self.__history_sessions: - yield from session.actions - - def create_new_session(self) -> None: - """Create a new history list""" - self.__session_increment += 1 - session = HistorySession(number=self.__session_increment) - self.__history_sessions.append(session) - self.tree.populate_tree(self.__history_sessions) - self.refresh_compatibility_items() - - def start_new_session_after_workspace_reset(self) -> None: - """Start a new history session after a workspace reset, when useful.""" - if self.__history_sessions and self.__history_sessions[-1].actions: - self.create_new_session() - - def add_compute_entry( - self, - action_title: str, - panel_str: str, - func_name: str, - pattern: str, - save_state: bool = True, - output_uuids: list[str] | None = None, - plugin_origin: dict[str, Any] | None = None, - **kwargs: Any, - ) -> HistoryAction | None: - """Record a *compute* action in the current history session. - - Args: - action_title: Title shown in the history tree. - panel_str: ``"signal"`` or ``"image"``. - func_name: Sigima feature name (resolvable via - :meth:`BaseProcessor.get_feature`). - pattern: One of ``"1_to_1"``, ``"1_to_0"``, ``"n_to_1"``, ``"2_to_1"``, - ``"1_to_n"``, ``"multiple_1_to_1"`` (the latter is recorded for - traceability but not replayable). - save_state: If True, capture the workspace state for replay. - output_uuids: Optional list of UUIDs of the data objects produced by - this action. When known at call time, prefer passing it here so the - bijective mapping is initialised in one step. Most callers do not - know the outputs yet and instead wrap the compute call with - :meth:`capture_outputs` (or call :meth:`register_action_outputs` - explicitly afterwards) using the returned action. - plugin_origin: Optional plugin origin descriptor (see - :func:`datalab.gui.processor.base._detect_plugin_origin`). ``None`` - for built-in Sigima/DataLab features. - **kwargs: Extra primitive kwargs (``param``, ``obj2_uuids``, - ``obj2_name``, ``pairwise``, ``params`` (list of DataSet), - ``func_names`` (list of str), ...). ``DataSet`` instances are - serialised as JSON. - - Returns: - The created :class:`HistoryAction`, or ``None`` if recording is - disabled (record mode off or replay in progress). - """ - if not self.__record_mode or self.__replaying: - return None - state = WorkspaceState() - if save_state: - state.save(self.mainwindow) - # Deep-copy kwargs so each action owns independent parameter - # instances. Without this, consecutive applications of the same - # function (e.g. two gaussian_filter calls with different sigma) - # would share a single DataSet object and editing one action's - # parameters would silently mutate the other. - action = HistoryAction( - title=action_title, - kind=HistoryAction.KIND_COMPUTE, - panel_str=panel_str, - func_name=func_name, - pattern=pattern, - kwargs=deepcopy(kwargs), - state=state, - plugin_origin=plugin_origin, - ) - self.add_object(action) - if output_uuids is not None: - self.register_action_outputs(action, output_uuids) - return action - - def add_compute_entry_from_pp( - self, - action_title: str, - pp: Any, # ProcessingParameters (avoid circular import) - panel_str: str, - save_state: bool = True, - output_uuids: list[str] | None = None, - plugin_origin: dict[str, Any] | None = None, - **extras: Any, - ) -> HistoryAction | None: - """Record a *compute* action derived from a ``ProcessingParameters``. - - Bridges the dash-form pattern used in object metadata - (``"1-to-1"`` …) with the underscore form expected by - :class:`HistoryAction` (``"1_to_1"`` …) so that both sides share - a single identity (``func_name`` / ``pattern`` / ``param``). - - Args: - action_title: Title shown in the history tree. - pp: :class:`~datalab.gui.processor.base.ProcessingParameters` - instance describing the operation. - panel_str: ``"signal"`` or ``"image"``. - save_state: If True, capture the workspace state for replay. - output_uuids: Optional list of UUIDs of the data objects produced - by this action (see :meth:`add_compute_entry`). - plugin_origin: Optional plugin origin descriptor (see - :meth:`add_compute_entry`). - **extras: Additional history-only kwargs (``obj2_uuids``, - ``obj2_name``, ``pairwise``, ``params``, ``func_names``…). - - Returns: - The created :class:`HistoryAction`, or ``None`` if recording is - disabled. - """ - hist_pattern = pp.pattern.replace("-", "_") - kwargs: dict[str, Any] = {} - if pp.param is not None and "param" not in extras and "params" not in extras: - kwargs["param"] = pp.param - kwargs.update(extras) - return self.add_compute_entry( - action_title, - panel_str=panel_str, - func_name=pp.func_name, - pattern=hist_pattern, - save_state=save_state, - output_uuids=output_uuids, - plugin_origin=plugin_origin, - **kwargs, - ) - - def register_action_outputs( - self, action: HistoryAction, output_uuids: list[str] - ) -> None: - """Register the data objects produced by ``action``. - - Maintains the bijective ``action → outputs`` and ``output → action`` - mappings. May be called multiple times for a given action (later calls - replace earlier ones, e.g. after a cascade recompute). - - Args: - action: The history action that produced the outputs. - output_uuids: UUIDs of the produced data objects (empty for - ``1_to_0`` analysis patterns and for UI actions that did not - create new objects). - """ - # Drop previous outputs for this action from the reverse index. - previous = self._action_output_uuids.get(action.uuid, []) - for prev_uuid in previous: - if self._output_to_action.get(prev_uuid) == action.uuid: - self._output_to_action.pop(prev_uuid, None) - new_outputs = list(output_uuids) - # Ownership transfer: if an output_uuid already belongs to a - # *different* action, remove it from that action's output list so the - # forward mapping stays consistent. The HistoryAction object's - # ``output_uuids`` attribute is NOT updated here because traversing all - # sessions to locate the object would be expensive; the panel-level - # dicts are the source of truth. - for out_uuid in new_outputs: - old_action_uuid = self._output_to_action.get(out_uuid) - if old_action_uuid is not None and old_action_uuid != action.uuid: - old_list = self._action_output_uuids.get(old_action_uuid) - if old_list is not None: - try: - old_list.remove(out_uuid) - except ValueError: - pass - if not old_list: - del self._action_output_uuids[old_action_uuid] - _logger.debug( - "Output %s transferred from action %s to %s", - out_uuid, - old_action_uuid, - action.uuid, - ) - action.output_uuids = list(new_outputs) - self._action_output_uuids[action.uuid] = new_outputs - for out_uuid in new_outputs: - self._output_to_action[out_uuid] = action.uuid - - @contextmanager - def capture_outputs( - self, action: HistoryAction | None - ) -> Generator[None, None, None]: - """Context manager: snapshot panel object IDs and record diffs as outputs. - - Use around any compute call when the produced UUIDs are not known - upfront. On exit, every newly-added object (signal or image) is - registered as an output of ``action`` via - :meth:`register_action_outputs`. No-op when ``action`` is ``None`` - (recording disabled). - - Args: - action: The history action being processed, or ``None``. - """ - if action is None: - yield - return - panels = (self.mainwindow.signalpanel, self.mainwindow.imagepanel) - before = { - p.PANEL_STR_ID: set(p.objmodel.get_object_ids()) for p in panels - } - try: - yield - finally: - new_uuids: list[str] = [] - for p in panels: - before_p = before[p.PANEL_STR_ID] - for uid in p.objmodel.get_object_ids(): - if uid not in before_p: - new_uuids.append(uid) - self.register_action_outputs(action, new_uuids) - - def _prune_output_mapping(self) -> None: - """Drop entries of :attr:`_output_to_action` whose object no longer exists. - - Connected to each data panel's ``SIG_OBJECT_REMOVED`` so that the - reverse index stays consistent with the live workspace. The forward - ``_action_output_uuids`` mapping is intentionally left intact: it - records the *historical* outputs of each action (useful for replay - and cascade introspection even after an output was deleted). - """ - if not self._output_to_action: - return - alive: set[str] = set() - for panel in (self.mainwindow.signalpanel, self.mainwindow.imagepanel): - alive.update(panel.objmodel.get_object_ids()) - stale = [u for u in self._output_to_action if u not in alive] - for u in stale: - self._output_to_action.pop(u, None) - - def _reconnect_chain_after_removal(self, panel: BaseDataPanel) -> None: - """Reconnect the processing chain after object(s) were deleted from a - data panel, like removing a link from a linked list. - - Each deleted object that was an intermediate processing result has its - downstream consumers reconnected to its own source (the first source for - multi-source operations) and recomputed in cascade, so the chain keeps - producing consistent results. Cases that cannot be reconnected (the - deleted object has no valid source) are reported in a single warning but - the deletion is always kept. - - Connected to each data panel's ``SIG_OBJECT_REMOVED`` (bound to the - panel via ``functools.partial``). Runs before :meth:`_prune_output_mapping` - so the bijective output map is still available. - """ - pstr = panel.PANEL_STR_ID - previous = self.__obj_ids_snapshot.get(pstr, set()) - current = set(panel.objmodel.get_object_ids()) - removed = previous - current - if not removed or self.__reconnecting: - return - self.__reconnecting = True - try: - warnings: list[str] = [] - roots_to_recompute: list[HistoryAction] = [] - for x_uuid in removed: - self.__reconnect_single_removed( - panel, x_uuid, warnings, roots_to_recompute - ) - for action in roots_to_recompute: - self._recompute_action_in_place(action) - self.recompute_cascade(action) - if warnings: - QW.QMessageBox.warning( - self.mainwindow, - _("Delete"), - _( - "Some operations could not be reconnected after " - "deletion:" - ) - + "\n\n• " - + "\n• ".join(warnings), - ) - self.tree.populate_tree(self.__history_sessions) - self.refresh_compatibility_items() - self.__update_actions_state() - finally: - self.__reconnecting = False - self.__refresh_obj_ids_snapshot() - - def __reconnect_single_removed( - self, - panel: BaseDataPanel, - x_uuid: str, - warnings: list[str], - roots_to_recompute: list[HistoryAction], - ) -> None: - """Reconnect consumers of a single deleted object ``x_uuid``. - - Appends a localized message to ``warnings`` when reconnection is not - possible, and appends each consumer's producing action to - ``roots_to_recompute`` so the caller can recompute the cascade. - """ - from datalab.gui.processor.base import ( # pylint: disable=import-outside-toplevel - ProcessingParameters, - extract_processing_parameters, - insert_processing_parameters, - ) - - pstr = panel.PANEL_STR_ID - # 1. Producing action of the deleted object (to learn its source). - action_a = None - action_a_uuid = self._output_to_action.get(x_uuid) - if action_a_uuid is not None: - for session in self.__history_sessions: - for a in session.actions: - if a.uuid == action_a_uuid: - action_a = a - break - if action_a is not None: - break - # 2. Consumers: objects whose processing references x_uuid as a source. - consumers: list[tuple[Any, Any]] = [] - for obj in panel.objmodel: - pp = extract_processing_parameters(obj) - if pp is None: - continue - if pp.source_uuid == x_uuid or ( - pp.source_uuids and x_uuid in pp.source_uuids - ): - consumers.append((obj, pp)) - if not consumers: - # Leaf deletion: nothing downstream to reconnect. - return - # 3. Source S of the deleted object (first source for multi-source ops). - s_uuid: str | None = None - if action_a is not None: - sel = action_a.state.selection.get(pstr, []) - if sel: - s_uuid = sel[0] - alive_ids = set(panel.objmodel.get_object_ids()) - if s_uuid is None or s_uuid not in alive_ids: - label = ( - action_a.title - or action_a.func_name - if action_a is not None - else x_uuid - ) - warnings.append( - _( - "“%s” has dependent operations but no valid source to " - "reconnect to — downstream results are left unchanged." - ) - % label - ) - return - # 4. Reconnect each consumer: replace x_uuid -> s_uuid in its pp and in - # its producing action's recorded inputs, then queue it for recompute. - for obj, pp in consumers: - new_source_uuid = ( - s_uuid if pp.source_uuid == x_uuid else pp.source_uuid - ) - new_source_uuids = pp.source_uuids - if pp.source_uuids and x_uuid in pp.source_uuids: - new_source_uuids = [ - s_uuid if u == x_uuid else u for u in pp.source_uuids - ] - insert_processing_parameters( - obj, - ProcessingParameters( - func_name=pp.func_name, - pattern=pp.pattern, - param=pp.param, - source_uuid=new_source_uuid, - source_uuids=new_source_uuids, - ), - ) - if pp.func_name: - action_b = self.find_action_for_output( - get_uuid(obj), pp.func_name - ) - if action_b is not None: - self.__rewrite_action_source( - action_b, pstr, x_uuid, s_uuid - ) - if action_b not in roots_to_recompute: - roots_to_recompute.append(action_b) - # 5. Drop the deleted node's action if all its outputs are gone. - if action_a is not None: - outs = self._action_output_uuids.get(action_a.uuid, []) - if not any(o in alive_ids for o in outs): - self.__remove_single_action(action_a) - - def __rewrite_action_source( - self, - action: HistoryAction, - pstr: str, - old_uuid: str, - new_uuid: str, - ) -> None: - """Replace ``old_uuid`` with ``new_uuid`` in an action's recorded inputs. - - Updates both the captured selection and the ``obj2_uuids`` kwarg (for - 2_to_1 actions) so future replays/recomputes use the new source. - """ - sel = action.state.selection.get(pstr) - if sel: - action.state.selection[pstr] = [ - new_uuid if u == old_uuid else u for u in sel - ] - obj2 = action.kwargs.get("obj2_uuids") - if isinstance(obj2, str): - if obj2 == old_uuid: - action.kwargs["obj2_uuids"] = new_uuid - elif obj2: - action.kwargs["obj2_uuids"] = [ - new_uuid if u == old_uuid else u for u in obj2 - ] - - def __remove_single_action(self, action: HistoryAction) -> None: - """Remove a single action from its session (splice, not truncate). - - Also drops the action's entries from the bijective output maps, and - removes the parent session if it becomes empty. - """ - for session in self.__history_sessions: - if action in session.actions: - session.actions.remove(action) - outs = self._action_output_uuids.pop(action.uuid, []) - for out_uuid in outs: - if self._output_to_action.get(out_uuid) == action.uuid: - self._output_to_action.pop(out_uuid, None) - if not session.actions: - self.__history_sessions.remove(session) - break - - def add_ui_entry( - self, - action_title: str, - target: str, - method_name: str, - save_state: bool = True, - **kwargs: Any, - ) -> None: - """Record a *UI* action in the current history session. - - Args: - action_title: Title shown in the history tree. - target: One of ``"mainwindow"``, ``"signalpanel"``, ``"imagepanel"``, - ``"historypanel"`` -- attribute path on the main window. - method_name: Method name to call on ``target`` at replay time. - save_state: If True, capture the workspace state for replay. - **kwargs: Method keyword arguments. ``DataSet`` instances are - serialised as JSON; other values must be HDF5-friendly primitives. - """ - if not self.__record_mode or self.__replaying: - return - state = WorkspaceState() - if save_state: - state.save(self.mainwindow) - # Deep-copy kwargs to ensure independent parameter ownership - # (same rationale as in add_compute_entry). - action = HistoryAction( - title=action_title, - kind=HistoryAction.KIND_UI, - target=target, - method_name=method_name, - kwargs=deepcopy(kwargs), - state=state, - ) - self.add_object(action) - - def add_entry( - self, - action_title: str, - save_state: bool, - func: Callable, - **kwargs, - ) -> None: - """Legacy entry-point kept as a compatibility shim. - - Most call sites have been migrated to :meth:`add_compute_entry` or - :meth:`add_ui_entry`. The remaining paths -- and the - :func:`add_to_history` decorator -- still call ``add_entry`` with a - bound method; we infer the ``(target, method_name)`` from the bound - ``func.__self__`` and route to :meth:`add_ui_entry`. - """ - if not self.__record_mode or self.__replaying: - return - target = None - if hasattr(func, "__self__"): - target = _resolve_self_target(func.__self__) - if target is None: - # Cannot route safely -- skip rather than pickle a Callable. - return - self.add_ui_entry( - action_title, - target=target, - method_name=func.__name__, - save_state=save_state, - **kwargs, - ) - - # ------ AbstractPanel interface --------------------------------------------------- - def create_object(self) -> HistoryAction: - """Create and return object""" - return HistoryAction() - - def add_object(self, obj: HistoryAction) -> None: - """Add object to panel""" - if not self.__history_sessions: - self.create_new_session() - self.__history_sessions[-1].add_action(obj) - self.tree.add_action_to_tree(obj) - self.tree.rearrange_tree() - self.refresh_compatibility_items() - self.__update_actions_state() - - def remove_all_objects(self): - """Remove all objects""" - super().remove_all_objects() - self._action_output_uuids.clear() - self._output_to_action.clear() - self.__update_actions_state() diff --git a/datalab/gui/panel/history/__init__.py b/datalab/gui/panel/history/__init__.py new file mode 100644 index 000000000..4cce7abf8 --- /dev/null +++ b/datalab/gui/panel/history/__init__.py @@ -0,0 +1,21 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +"""History panel subpackage — re-exports public history symbols.""" + +from datalab.gui.panel.history.panel import HistoryPanel +from datalab.history import HistoryAction, HistorySession, WorkspaceState +from datalab.history.core import ( + HISTORY_ACTION_SCHEMA_VERSION, + HISTORY_SCHEMA_VERSION, +) +from datalab.widgets.historytree import HistoryTree + +__all__ = [ + "HISTORY_ACTION_SCHEMA_VERSION", + "HISTORY_SCHEMA_VERSION", + "HistoryAction", + "HistoryPanel", + "HistorySession", + "HistoryTree", + "WorkspaceState", +] diff --git a/datalab/gui/panel/history/chain.py b/datalab/gui/panel/history/chain.py new file mode 100644 index 000000000..48e3a935c --- /dev/null +++ b/datalab/gui/panel/history/chain.py @@ -0,0 +1,375 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +"""Action↔output chain helpers for the History panel.""" + +from __future__ import annotations + +import logging +from typing import TYPE_CHECKING, Any + +from qtpy import QtWidgets as QW + +from datalab.config import _ +from datalab.env import execenv +from datalab.gui.processor.base import ( + ProcessingParameters, + extract_processing_parameters, + insert_processing_parameters, +) +from datalab.history import HistoryAction, HistorySession +from datalab.objectmodel import get_uuid + +if TYPE_CHECKING: + from datalab.gui.panel.base import BaseDataPanel + from datalab.gui.panel.history.panel import HistoryPanel + +_logger = logging.getLogger(__name__) + + +def find_parent_session( + panel: HistoryPanel, action: HistoryAction +) -> HistorySession | None: + """Return the session that contains ``action``, or None.""" + for session in panel._history_sessions: + if action in session.actions: + return session + return None + + +def resolve_panel_for_action( + panel: HistoryPanel, action: HistoryAction +) -> BaseDataPanel | None: + """Return the data panel targeted by ``action``, or ``None``.""" + if action.kind != HistoryAction.KIND_COMPUTE: + return None + if action.panel_str == "signal": + return panel.mainwindow.signalpanel + if action.panel_str == "image": + return panel.mainwindow.imagepanel + return None + + +def find_output_object_uuid( + panel: HistoryPanel, panel_data: BaseDataPanel, action: HistoryAction +) -> str | None: + """Find the UUID of the output object produced by ``action`` in ``panel_data``. + + Primary path: consult the bijective ``action_output_uuids`` mapping. + Fallback path: legacy heuristic on ``processing_parameters`` metadata. + """ + registered = panel._action_output_uuids.get(action.uuid) + if registered: + existing_ids = set(panel_data.objmodel.get_object_ids()) + for out_uuid in registered: + if out_uuid in existing_ids: + return out_uuid + if action.func_name is None: + return None + recorded_uuids = set(action.state.selection.get(panel_data.PANEL_STR_ID, [])) + if not recorded_uuids: + return None + for obj in panel_data.objmodel: + pp = extract_processing_parameters(obj) + if pp is None or pp.func_name != action.func_name: + continue + if pp.source_uuid is not None and pp.source_uuid in recorded_uuids: + return get_uuid(obj) + if pp.source_uuids is not None and recorded_uuids.intersection(pp.source_uuids): + return get_uuid(obj) + return None + + +def find_action_for_output( + panel: HistoryPanel, output_uuid: str, func_name: str +) -> HistoryAction | None: + """Find the :class:`HistoryAction` that produced ``output_uuid``.""" + if not panel._history_sessions: + return None + action_uuid = panel._output_to_action.get(output_uuid) + if action_uuid is not None: + for session in panel._history_sessions: + for action in session.actions: + if action.uuid == action_uuid: + if action.func_name == func_name: + return action + return None + panel_data: BaseDataPanel | None = None + output_obj = None + for p in (panel.mainwindow.signalpanel, panel.mainwindow.imagepanel): + if p.objmodel.has_uuid(output_uuid): + output_obj = p.objmodel[output_uuid] + panel_data = p + break + if panel_data is None or output_obj is None: + return None + pp = extract_processing_parameters(output_obj) + if pp is None or pp.func_name != func_name: + return None + target_source_uuid = pp.source_uuid + if target_source_uuid is None: + return None + for current_session in reversed(panel._history_sessions): + for action in reversed(current_session.actions): + if action.kind != HistoryAction.KIND_COMPUTE: + continue + if action.func_name != func_name: + continue + if action.panel_str != panel_data.PANEL_STR_ID: + continue + captured = action.state.selection.get(panel_data.PANEL_STR_ID, []) + if captured and captured[0] == target_source_uuid: + return action + return None + + +def get_session_of(panel: HistoryPanel, action: HistoryAction) -> HistorySession | None: + """Return the session that contains ``action``, or None.""" + for session in panel._history_sessions: + if action in session.actions: + return session + return None + + +def action_output_uuid(panel: HistoryPanel, action: HistoryAction) -> str | None: + """Return the UUID of the object produced by ``action``, or ``None``.""" + panel_data = resolve_panel_for_action(panel, action) + if panel_data is None: + return None + return find_output_object_uuid(panel, panel_data, action) + + +def action_consumes_any(action: HistoryAction, uuids: set[str]) -> bool: + """Return True if ``action``'s input UUIDs intersect ``uuids``.""" + if action.kind != HistoryAction.KIND_COMPUTE: + return False + pstr = action.panel_str or "" + captured: set[str] = set(action.state.selection.get(pstr, [])) + obj2 = action.kwargs.get("obj2_uuids") + if obj2: + if isinstance(obj2, str): + captured.add(obj2) + else: + captured.update(obj2) + return bool(captured & uuids) + + +def collect_downstream_uuids(panel: HistoryPanel, action: HistoryAction) -> set[str]: + """Return the transitive closure of output UUIDs descending from ``action``.""" + if not panel._history_sessions: + return set() + current = get_session_of(panel, action) + if current is None: + return set() + root_out = action_output_uuid(panel, action) + if root_out is None: + return set() + closure: set[str] = {root_out} + idx = current.actions.index(action) + for downstream in current.actions[idx + 1 :]: + if downstream.kind != HistoryAction.KIND_COMPUTE: + continue + if not action_consumes_any(downstream, closure): + continue + out_uuid = action_output_uuid(panel, downstream) + if out_uuid is not None: + closure.add(out_uuid) + closure.discard(root_out) + return closure + + +def get_downstream_actions( + panel: HistoryPanel, action: HistoryAction +) -> list[HistoryAction]: + """Return the actions of the current session that depend on ``action``.""" + if not panel._history_sessions: + return [] + current = get_session_of(panel, action) + if current is None: + return [] + root_out = action_output_uuid(panel, action) + if root_out is None: + return [] + closure: set[str] = {root_out} + downstream: list[HistoryAction] = [] + idx = current.actions.index(action) + for candidate in current.actions[idx + 1 :]: + if candidate.kind != HistoryAction.KIND_COMPUTE: + continue + if not action_consumes_any(candidate, closure): + continue + downstream.append(candidate) + out_uuid = action_output_uuid(panel, candidate) + if out_uuid is not None: + closure.add(out_uuid) + return downstream + + +def resolve_target_outputs( + panel: HistoryPanel, panel_data: BaseDataPanel, action: HistoryAction +) -> tuple[list[str], list[str]]: + """Return ``(existing, missing)`` UUIDs registered for ``action``.""" + registered = list(panel._action_output_uuids.get(action.uuid, [])) + existing_ids = set(panel_data.objmodel.get_object_ids()) + existing: list[str] = [u for u in registered if u in existing_ids] + missing: list[str] = [u for u in registered if u not in existing_ids] + return existing, missing + + +def existing_input_uuids(panel_data: BaseDataPanel, action: HistoryAction) -> list[str]: + """Return recorded input UUIDs that still exist in ``panel_data``.""" + recorded = action.state.selection.get(panel_data.PANEL_STR_ID, []) + return [uuid for uuid in recorded if panel_data.objmodel.has_uuid(uuid)] + + +def prune_output_mapping(panel: HistoryPanel) -> None: + """Drop entries of :attr:`_output_to_action` whose object no longer exists.""" + if not panel._output_to_action: + return + alive: set[str] = set() + for pdata in (panel.mainwindow.signalpanel, panel.mainwindow.imagepanel): + alive.update(pdata.objmodel.get_object_ids()) + stale = [u for u in panel._output_to_action if u not in alive] + for u in stale: + panel._output_to_action.pop(u, None) + + +def rewrite_action_source( + action: HistoryAction, + pstr: str, + old_uuid: str, + new_uuid: str, +) -> None: + """Replace ``old_uuid`` with ``new_uuid`` in an action's recorded inputs.""" + sel = action.state.selection.get(pstr) + if sel: + action.state.selection[pstr] = [new_uuid if u == old_uuid else u for u in sel] + obj2 = action.kwargs.get("obj2_uuids") + if isinstance(obj2, str): + if obj2 == old_uuid: + action.kwargs["obj2_uuids"] = new_uuid + elif obj2: + action.kwargs["obj2_uuids"] = [new_uuid if u == old_uuid else u for u in obj2] + + +def remove_single_action(panel: HistoryPanel, action: HistoryAction) -> None: + """Remove a single action from its session (splice, not truncate).""" + for session in panel._history_sessions: + if action in session.actions: + session.actions.remove(action) + outs = panel._action_output_uuids.pop(action.uuid, []) + for out_uuid in outs: + if panel._output_to_action.get(out_uuid) == action.uuid: + panel._output_to_action.pop(out_uuid, None) + if not session.actions: + panel._history_sessions.remove(session) + break + + +def reconnect_single_removed( + panel: HistoryPanel, + panel_data: BaseDataPanel, + x_uuid: str, + warnings: list[str], + roots_to_recompute: list[HistoryAction], +) -> None: + """Reconnect consumers of a single deleted object ``x_uuid``.""" + pstr = panel_data.PANEL_STR_ID + action_a = None + action_a_uuid = panel._output_to_action.get(x_uuid) + if action_a_uuid is not None: + for session in panel._history_sessions: + for a in session.actions: + if a.uuid == action_a_uuid: + action_a = a + break + if action_a is not None: + break + consumers: list[tuple[Any, Any]] = [] + for obj in panel_data.objmodel: + pp = extract_processing_parameters(obj) + if pp is None: + continue + if pp.source_uuid == x_uuid or (pp.source_uuids and x_uuid in pp.source_uuids): + consumers.append((obj, pp)) + if not consumers: + return + s_uuid: str | None = None + if action_a is not None: + sel = action_a.state.selection.get(pstr, []) + if sel: + s_uuid = sel[0] + alive_ids = set(panel_data.objmodel.get_object_ids()) + if s_uuid is None or s_uuid not in alive_ids: + label = action_a.title or action_a.func_name if action_a is not None else x_uuid + warnings.append( + _( + "“%s” has dependent operations but no valid source to " + "reconnect to — downstream results are left unchanged." + ) + % label + ) + return + for obj, pp in consumers: + new_source_uuid = s_uuid if pp.source_uuid == x_uuid else pp.source_uuid + new_source_uuids = pp.source_uuids + if pp.source_uuids and x_uuid in pp.source_uuids: + new_source_uuids = [s_uuid if u == x_uuid else u for u in pp.source_uuids] + insert_processing_parameters( + obj, + ProcessingParameters( + func_name=pp.func_name, + pattern=pp.pattern, + param=pp.param, + source_uuid=new_source_uuid, + source_uuids=new_source_uuids, + ), + ) + if pp.func_name: + action_b = find_action_for_output(panel, get_uuid(obj), pp.func_name) + if action_b is not None: + rewrite_action_source(action_b, pstr, x_uuid, s_uuid) + if action_b not in roots_to_recompute: + roots_to_recompute.append(action_b) + if action_a is not None: + outs = panel._action_output_uuids.get(action_a.uuid, []) + if not any(o in alive_ids for o in outs): + remove_single_action(panel, action_a) + + +def reconnect_chain_after_removal( + panel: HistoryPanel, panel_data: BaseDataPanel +) -> None: + """Reconnect the processing chain after object(s) were deleted from a data panel.""" + from datalab.gui.panel.history import recompute as hrec + + pstr = panel_data.PANEL_STR_ID + previous = panel._obj_ids_snapshot.get(pstr, set()) + current = set(panel_data.objmodel.get_object_ids()) + removed = previous - current + if not removed or panel._reconnecting: + return + panel._reconnecting = True + try: + warnings: list[str] = [] + roots_to_recompute: list[HistoryAction] = [] + for x_uuid in removed: + reconnect_single_removed( + panel, panel_data, x_uuid, warnings, roots_to_recompute + ) + for action in roots_to_recompute: + hrec.recompute_action_in_place(panel, action) + hrec.recompute_cascade(panel, action) + if warnings and not execenv.unattended: + QW.QMessageBox.warning( + panel.mainwindow, + _("Delete"), + _("Some operations could not be reconnected after deletion:") + + "\n\n• " + + "\n• ".join(warnings), + ) + panel.tree.populate_tree(panel._history_sessions) + panel.refresh_compatibility_items() + panel.update_actions_state() + finally: + panel._reconnecting = False + panel.refresh_obj_ids_snapshot() diff --git a/datalab/gui/panel/history/interactive_replay.py b/datalab/gui/panel/history/interactive_replay.py new file mode 100644 index 000000000..2514981d9 --- /dev/null +++ b/datalab/gui/panel/history/interactive_replay.py @@ -0,0 +1,195 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +"""Interactive (dialog-driven) replay helpers for the History panel.""" + +from __future__ import annotations + +import copy +import logging +from typing import TYPE_CHECKING + +import guidata.dataset as gds +from guidata.dataset.qtwidgets import DataSetEditDialog, DataSetGroupEditDialog +from qtpy import QtWidgets as QW + +from datalab.config import _ +from datalab.env import execenv +from datalab.gui.panel.history import recompute as hrec +from datalab.history import HistoryAction, HistorySession + +if TYPE_CHECKING: + from datalab.gui.panel.history.panel import HistoryPanel + +_logger = logging.getLogger(__name__) + + +def replay_restore_actions( + panel: HistoryPanel, replay: bool = True, restore_selection: bool = True +) -> None: + """Replay and/or restore selection for the selected actions.""" + panel.refresh_compatibility_items() + selected = panel.tree.get_selected_actions_or_sessions(panel._history_sessions) + if not selected: + if not panel._history_sessions: + return + selected = [panel._history_sessions[-1]] + for session_or_action in selected: + if isinstance(session_or_action, HistoryAction) and session_or_action.is_stale: + hrec.recompute_cascade(panel, session_or_action) + continue + if not session_or_action.is_current_state_compatible( + panel.mainwindow, restore_selection=restore_selection + ): + if not execenv.unattended: + QW.QMessageBox.critical( + panel.mainwindow, + _("Error"), + _("The current workspace state is not compatible with the action."), + ) + return + if replay: + if panel._edit_mode and isinstance(session_or_action, HistoryAction): + edit_mode_replay(panel, session_or_action) + elif panel._edit_mode and isinstance(session_or_action, HistorySession): + view_only_session_replay(panel, session_or_action, restore_selection) + else: + with panel.replaying(), panel.output_suppressed(): + session_or_action.replay( + panel.mainwindow, + restore_selection=restore_selection, + edit=panel._edit_mode, + ) + elif restore_selection: + if panel._edit_mode or panel.has_any_pending_edits(): + restore_action_params(panel, session_or_action) + else: + session_or_action.restore(panel.mainwindow) + + +def prompt_edit_action_params( + panel: HistoryPanel, action: HistoryAction +) -> bool | None: + """Open the parameter dialog for *action* according to its pattern.""" + pattern = action.pattern + if pattern in {"1_to_1", "1_to_0", "n_to_1", "2_to_1"}: + param = action.kwargs.get("param") + if param is None: + return None + edited = copy.deepcopy(param) + if not edited.edit(parent=panel.mainwindow): + return False + action.snapshot_kwargs() + action.kwargs["param"] = edited + return True + if pattern == "1_to_n": + params = action.kwargs.get("params") or [] + if not params: + return None + edited_params = [copy.deepcopy(p) for p in params] + group = gds.DataSetGroup(edited_params, title=_("Parameters")) + if not group.edit(parent=panel.mainwindow): + return False + action.snapshot_kwargs() + action.kwargs["params"] = edited_params + return True + return None + + +def edit_mode_replay(panel: HistoryPanel, action: HistoryAction) -> None: + """Replay a single action in edit mode: open param dialog, update kwargs.""" + if action.kind != HistoryAction.KIND_COMPUTE or action.pattern is None: + with panel.replaying(), panel.output_suppressed(): + action.replay(panel.mainwindow, restore_selection=True, edit=True) + return + + chain: list[HistoryAction] = [action] + panel.get_downstream_actions(action) + edited_actions: list[HistoryAction] = [] + for a in chain: + result = prompt_edit_action_params(panel, a) + if result is False: + for done in edited_actions: + done.restore_kwargs() + panel.tree.refresh_action_item(done) + return + if result is True: + edited_actions.append(a) + + for a in edited_actions: + panel.tree.refresh_action_item(a) + + downstream = chain[1:] + hrec.recompute_action_in_place(panel, action) + hrec.recompute_cascade(panel, action, descendants=downstream) + + for a in chain: + panel.tree.refresh_action_item(a) + QW.QApplication.processEvents() + + +def show_readonly_param_dialog( + panel: HistoryPanel, dataset: gds.DataSet | gds.DataSetGroup +) -> None: + """Show a parameter dialog identical to the edit dialog but read-only.""" + if isinstance(dataset, gds.DataSetGroup): + dialog = DataSetGroupEditDialog(dataset, parent=panel.mainwindow) + else: + dialog = DataSetEditDialog(dataset, parent=panel.mainwindow) + for edl in dialog.edit_layout: + for widget in edl.widgets: + if widget.group is not None: + widget.group.setEnabled(False) + if widget.label is not None: + widget.label.setEnabled(False) + dialog.exec() + + +def view_only_session_replay( + panel: HistoryPanel, + session: HistorySession, + restore_selection: bool, +) -> None: + """Replay a session in edit mode with read-only parameter dialogs.""" + for action in session.actions: + if action.kind != HistoryAction.KIND_COMPUTE: + continue + pattern = action.pattern + panel.select_action_in_tree(action) + QW.QApplication.processEvents() + if pattern in {"1_to_1", "1_to_0", "n_to_1", "2_to_1"}: + param = action.kwargs.get("param") + if param is not None: + show_readonly_param_dialog(panel, copy.deepcopy(param)) + elif pattern == "1_to_n": + params = action.kwargs.get("params") or [] + if params: + group = gds.DataSetGroup( + [copy.deepcopy(p) for p in params], + title=_("Parameters"), + ) + show_readonly_param_dialog(panel, group) + + with panel.replaying(), panel.output_suppressed(): + session.replay( + panel.mainwindow, + restore_selection=restore_selection, + edit=False, + ) + + +def restore_action_params( + panel: HistoryPanel, item: HistoryAction | HistorySession +) -> None: + """Restore original kwargs from snapshot and recompute in-place.""" + actions: list[HistoryAction] + if isinstance(item, HistorySession): + actions = [a for a in item.actions if a.kind == HistoryAction.KIND_COMPUTE] + else: + actions = [item] + for action in actions: + if not action.has_pending_edits: + continue + action.restore_kwargs() + panel.tree.refresh_action_item(action) + hrec.recompute_action_in_place(panel, action) + hrec.recompute_cascade(panel, action) + panel.update_actions_state() diff --git a/datalab/gui/panel/history/panel.py b/datalab/gui/panel/history/panel.py new file mode 100644 index 000000000..c060e361d --- /dev/null +++ b/datalab/gui/panel/history/panel.py @@ -0,0 +1,902 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +""" +.. History panel (see parent package :mod:`datalab.gui.panel`) +""" + +from __future__ import annotations + +import functools +import logging +from contextlib import contextmanager +from typing import TYPE_CHECKING, Any, Callable, Generator + +from guidata.configtools import get_icon +from guidata.qthelpers import add_actions, create_action +from guidata.widgets.dockable import DockableWidgetMixin +from qtpy import QtCore as QC +from qtpy import QtGui as QG +from qtpy import QtWidgets as QW + +from datalab.config import Conf, _ +from datalab.env import execenv +from datalab.gui import historysession_ops as hsess +from datalab.gui import historytools_ops as htools +from datalab.gui.panel.base import AbstractPanel +from datalab.gui.panel.history import chain as hchain +from datalab.gui.panel.history import interactive_replay as hreplay +from datalab.gui.panel.history import recompute as hrec +from datalab.h5 import history as hio +from datalab.history import HistoryAction, HistorySession +from datalab.widgets.historytree import HistoryTree +from datalab.widgets.workspacestate_widget import WorkspaceStateWidget + +if TYPE_CHECKING: + from datalab.gui.main import DLMainWindow + from datalab.gui.panel.base import BaseDataPanel + from datalab.h5.native import NativeH5Reader, NativeH5Writer + +_logger = logging.getLogger(__name__) + + +class HistoryPanel(AbstractPanel, DockableWidgetMixin): + """History panel""" + + LOCATION = QC.Qt.RightDockWidgetArea + PANEL_STR = _("History panel") + + H5_PREFIX = "DataLab_His" + + SIG_OBJECT_MODIFIED = QC.Signal() + + FILE_FILTERS = f"{_('History files')} (*.dlhist)" + + def __init__(self, parent: DLMainWindow) -> None: + super().__init__(parent) + self.setWindowTitle(self.PANEL_STR) + self.setWindowIcon(get_icon("history.svg")) + self.setOrientation(QC.Qt.Vertical) + + self._record_mode = False + self._edit_mode = False + self._replaying = False + self._output_suppressed = False + self._syncing = False + self._cascade_in_progress = False + self._delete_action: QW.QAction | None = None + self._duplicate_action: QW.QAction | None = None + self._step_prev_action: QW.QAction | None = None + self._step_next_action: QW.QAction | None = None + self._restore_selection_action: QW.QAction | None = None + self._edit_action: QW.QAction | None = None + self._record_action: QW.QAction | None = None + self._menu_actions: list[QW.QAction] = self.create_menu_actions() + + self.mainwindow = parent + self.tree = HistoryTree(self) + self.tree.customContextMenuRequested.connect(self.show_context_menu) + self.tree.itemDoubleClicked.connect(self.replay_restore_actions) + self.tree.itemSelectionChanged.connect(self.sync_panel_selection) + self.tree.itemSelectionChanged.connect(self.update_actions_state) + self.tree.itemSelectionChanged.connect(self.update_state_widget) + + self._state_widget = WorkspaceStateWidget(self) + + toolbar = QW.QToolBar(self) + add_actions(toolbar, self._menu_actions) + widget = QW.QWidget(self) + layout = QW.QVBoxLayout() + layout.addWidget(toolbar) + layout.addWidget(self.tree) + layout.addWidget(self._state_widget) + layout.setContentsMargins(0, 0, 0, 0) + widget.setLayout(layout) + + self.addWidget(widget) + + self._history_sessions: list[HistorySession] = [] + self._session_increment = 0 + self._action_output_uuids: dict[str, list[str]] = {} + self._output_to_action: dict[str, str] = {} + self._cascade_warnings: list[str] = [] + self._broken_actions: set[str] = set() + self._reconnecting = False + self._obj_ids_snapshot: dict[str, set[str]] = {} + for panel in (self.mainwindow.signalpanel, self.mainwindow.imagepanel): + panel.SIG_OBJECT_ADDED.connect(self.refresh_compatibility_items) + panel.SIG_OBJECT_ADDED.connect(self.refresh_obj_ids_snapshot) + panel.SIG_OBJECT_REMOVED.connect(self.refresh_compatibility_items) + panel.SIG_OBJECT_REMOVED.connect( + functools.partial(self.reconnect_chain_after_removal, panel) + ) + panel.SIG_OBJECT_REMOVED.connect(self.prune_output_mapping) + panel.SIG_OBJECT_MODIFIED.connect(self.refresh_compatibility_items) + self.refresh_obj_ids_snapshot() + self.update_actions_state() + self.refresh_compatibility_items() + if not execenv.unattended and Conf.proc.history_auto_record.get(True): + self._record_action.setChecked(True) + self.create_new_session() + + def refresh_obj_ids_snapshot(self) -> None: + """Cache the current object ids of both data panels.""" + self._obj_ids_snapshot = { + self.mainwindow.signalpanel.PANEL_STR_ID: set( + self.mainwindow.signalpanel.objmodel.get_object_ids() + ), + self.mainwindow.imagepanel.PANEL_STR_ID: set( + self.mainwindow.imagepanel.objmodel.get_object_ids() + ), + } + + def update_actions_state(self) -> None: + """Update the enabled state of menu actions depending on history content.""" + has_history = len(self) > 0 + for action in (self._delete_action, self._duplicate_action): + if action is not None: + action.setEnabled(has_history) + if self._step_prev_action is not None: + self._step_prev_action.setEnabled(self.can_step_prev()) + if self._step_next_action is not None: + self._step_next_action.setEnabled(self.can_step_next()) + if self._restore_selection_action is not None: + self._restore_selection_action.setEnabled( + self._edit_mode or self.has_any_pending_edits() + ) + + __update_actions_state = update_actions_state + + @property + def history_sessions(self) -> list[HistorySession]: + """Return mutable history sessions storage.""" + return self._history_sessions + + @history_sessions.setter + def history_sessions(self, sessions: list[HistorySession]) -> None: + """Replace history sessions storage.""" + self._history_sessions = sessions + + @property + def session_increment(self) -> int: + """Return the current session counter.""" + return self._session_increment + + @session_increment.setter + def session_increment(self, value: int) -> None: + """Set the current session counter.""" + self._session_increment = value + + @property + def record_mode_enabled(self) -> bool: + """Return True when record mode is enabled.""" + return self._record_mode + + def has_any_pending_edits(self) -> bool: + """Return True if any action across all sessions has a pending Edit + mode snapshot (i.e. uncommitted edits that Restore can revert).""" + return any( + action.has_pending_edits + for session in self._history_sessions + for action in session.actions + ) + + def update_state_widget(self) -> None: + """Update the workspace state widget from the currently selected action.""" + action = self.current_action() + if action is not None: + self._state_widget.update_from_state(action.state) + else: + self._state_widget.update_from_state(None) + + def create_menu_actions(self) -> list[QW.QAction]: + """Create menu actions for the history panel.""" + edit_action = create_action( + self, + _("Edit mode"), + toggled=self.toggle_edit_mode, + icon=get_icon("edit_mode.svg"), + ) + edit_action.setChecked(self._edit_mode) + self._edit_action = edit_action + record_action = create_action( + self, + _("Record mode"), + toggled=self.toggle_record_mode, + icon=get_icon("record.svg"), + ) + record_action.setChecked(self._record_mode) + self._record_action = record_action + new_session_action = create_action( + self, + _("New session"), + self.create_new_session, + icon=get_icon("libre-gui-add.svg"), + tip=_("Start a new history session"), + ) + open_action = create_action( + self, + _("Open history file..."), + triggered=lambda checked=False: self.open_dlhist_file(), + icon=get_icon("fileopen_h5.svg"), + tip=_("Open history from a standalone .dlhist file"), + ) + save_action = create_action( + self, + _("Save history file..."), + triggered=lambda checked=False: self.save_to_dlhist_file(), + icon=get_icon("filesave_h5.svg"), + tip=_("Save history to a standalone .dlhist file"), + ) + self._delete_action = create_action( + self, + _("Delete"), + self.delete_selected, + icon=get_icon("delete.svg"), + ) + self._duplicate_action = create_action( + self, + _("Duplicate"), + self.duplicate_selected_entries, + icon=get_icon("duplicate.svg"), + tip=_("Duplicate selected history action/session"), + ) + self._step_prev_action = create_action( + self, + _("Previous step"), + triggered=self.step_prev, + icon=get_icon("libre-gui-arrow-left.svg"), + tip=_("Select the previous action in the current session"), + shortcut=QG.QKeySequence("Ctrl+Left"), + ) + self._step_next_action = create_action( + self, + _("Next step"), + triggered=self.step_next, + icon=get_icon("libre-gui-arrow-right.svg"), + tip=_("Select the next action in the current session"), + shortcut=QG.QKeySequence("Ctrl+Right"), + ) + generate_macro_action = create_action( + self, + _("Generate macro"), + self.generate_macro, + icon=get_icon("console.svg"), + tip=_("Generate a Python macro script from history"), + ) + remove_incompatible_action = create_action( + self, + _("Remove incompatible"), + self.remove_incompatible_actions, + icon=get_icon("edit/delete_all.svg"), + tip=_("Remove actions incompatible with the current workspace"), + ) + self._restore_selection_action = create_action( + self, + _("Restore parameters"), + lambda: self.replay_restore_actions(restore_selection=True, replay=False), + icon=get_icon("restore_selection.svg"), + tip=_("Restore original parameters (discard edit-mode changes)"), + ) + return [ + record_action, + new_session_action, + None, + open_action, + save_action, + None, + self._step_prev_action, + self._step_next_action, + None, + create_action( + self, + _("Replay"), + lambda: self.replay_restore_actions(restore_selection=False), + icon=get_icon("replay.svg"), + ), + self._restore_selection_action, + edit_action, + None, + self._duplicate_action, + generate_macro_action, + None, + remove_incompatible_action, + self._delete_action, + ] + + def toggle_edit_mode(self, checked: bool) -> None: + """Toggle edit mode. + + Toggling Edit mode off is a definitive commit: all parameter + changes performed during the session become permanent. + """ + if not checked and self.has_any_pending_edits(): + reply = ( + QW.QMessageBox.Yes + if execenv.unattended + else QW.QMessageBox.question( + self.mainwindow, + _("Commit edit mode changes?"), + _( + "You are about to exit Edit mode.\n\n" + "All parameter changes made during this session will be " + "permanently kept.\n" + "This action cannot be undone — Restore will no longer " + "be available.\n\n" + "Do you want to continue?" + ), + QW.QMessageBox.Yes | QW.QMessageBox.No, + QW.QMessageBox.No, + ) + ) + if reply != QW.QMessageBox.Yes: + if self._edit_action is not None: + self._edit_action.blockSignals(True) + self._edit_action.setChecked(True) + self._edit_action.blockSignals(False) + return + self._edit_mode = checked + if not checked: + for session in self._history_sessions: + for action in session.actions: + action.discard_snapshot() + self.update_actions_state() + + def toggle_record_mode(self, checked: bool) -> None: + """Toggle record mode.""" + self._record_mode = checked + + def is_edit_mode(self) -> bool: + """Return True when the History panel is in edit mode.""" + return self._edit_mode + + @contextmanager + def replaying(self) -> Generator[None, None, None]: + """Context manager suppressing history capture during its scope.""" + previous = self._replaying + self._replaying = True + try: + yield + finally: + self._replaying = previous + + def is_replaying(self) -> bool: + """Return True when an external replay/recompute is in progress.""" + return self._replaying + + @contextmanager + def output_suppressed(self) -> Generator[None, None, None]: + """Context manager suppressing compute outputs during its scope.""" + previous = self._output_suppressed + self._output_suppressed = True + try: + yield + finally: + self._output_suppressed = previous + + def is_output_suppressed(self) -> bool: + """Return True when compute outputs must not be added to panels.""" + return self._output_suppressed + + def show_context_menu(self, pos: QC.QPoint) -> None: + """Show the context menu.""" + self.refresh_compatibility_items() + menu = QW.QMenu() + add_actions(menu, self._menu_actions) + menu.exec_(self.tree.mapToGlobal(pos)) + + def get_action_from_uuid(self, uuid: str) -> HistoryAction: + """Get the action from its UUID.""" + for session in self._history_sessions: + for action in session.actions: + if action.uuid == uuid: + return action + raise ValueError("Action not found") + + # ------------------------------------------------------------------ + # Interactive replay delegations + # ------------------------------------------------------------------ + + def replay_restore_actions( + self, replay: bool = True, restore_selection: bool = True + ) -> None: + """Replay and/or restore selection for the selected actions.""" + return hreplay.replay_restore_actions(self, replay, restore_selection) + + def prompt_edit_action_params(self, action: HistoryAction) -> bool | None: + """Open the parameter dialog for *action* according to its pattern.""" + return hreplay.prompt_edit_action_params(self, action) + + def edit_mode_replay(self, action: HistoryAction) -> None: + """Replay a single action in edit mode.""" + return hreplay.edit_mode_replay(self, action) + + def show_readonly_param_dialog(self, dataset: Any) -> None: + """Show a parameter dialog identical to the edit dialog but read-only.""" + return hreplay.show_readonly_param_dialog(self, dataset) + + def view_only_session_replay( + self, session: HistorySession, restore_selection: bool + ) -> None: + """Replay a session in edit mode with read-only parameter dialogs.""" + return hreplay.view_only_session_replay(self, session, restore_selection) + + def restore_action_params(self, item: HistoryAction | HistorySession) -> None: + """Restore original kwargs from snapshot and recompute in-place.""" + return hreplay.restore_action_params(self, item) + + # ------------------------------------------------------------------ + # Chain delegations + # ------------------------------------------------------------------ + + def find_parent_session(self, action: HistoryAction) -> HistorySession | None: + """Return the session that contains ``action``, or None.""" + return hchain.find_parent_session(self, action) + + def resolve_panel_for_action(self, action: HistoryAction) -> BaseDataPanel | None: + """Return the data panel targeted by ``action``, or ``None``.""" + return hchain.resolve_panel_for_action(self, action) + + def find_output_object_uuid( + self, panel: BaseDataPanel, action: HistoryAction + ) -> str | None: + """Find the UUID of the output object produced by ``action``.""" + return hchain.find_output_object_uuid(self, panel, action) + + def find_action_for_output( + self, output_uuid: str, func_name: str + ) -> HistoryAction | None: + """Find the action that produced ``output_uuid``.""" + return hchain.find_action_for_output(self, output_uuid, func_name) + + def get_session_of(self, action: HistoryAction) -> HistorySession | None: + """Return the session that contains ``action``, or None.""" + return hchain.get_session_of(self, action) + + def action_output_uuid(self, action: HistoryAction) -> str | None: + """Return the UUID of the object produced by ``action``, or ``None``.""" + return hchain.action_output_uuid(self, action) + + _action_output_uuid = action_output_uuid + + def action_consumes_any(self, action: HistoryAction, uuids: set[str]) -> bool: + """Return True if ``action``'s input UUIDs intersect ``uuids``.""" + return hchain.action_consumes_any(action, uuids) + + def collect_downstream_uuids(self, action: HistoryAction) -> set[str]: + """Return the transitive closure of output UUIDs descending from ``action``.""" + return hchain.collect_downstream_uuids(self, action) + + def get_downstream_actions(self, action: HistoryAction) -> list[HistoryAction]: + """Return the actions of the current session that depend on ``action``.""" + return hchain.get_downstream_actions(self, action) + + def resolve_target_outputs( + self, panel: BaseDataPanel, action: HistoryAction + ) -> tuple[list[str], list[str]]: + """Return ``(existing, missing)`` UUIDs registered for ``action``.""" + return hchain.resolve_target_outputs(self, panel, action) + + def existing_input_uuids( + self, panel: BaseDataPanel, action: HistoryAction + ) -> list[str]: + """Return recorded input UUIDs that still exist in ``panel``.""" + return hchain.existing_input_uuids(panel, action) + + def prune_output_mapping(self) -> None: + """Drop entries of :attr:`_output_to_action` whose object no longer exists.""" + return hchain.prune_output_mapping(self) + + def rewrite_action_source( + self, + action: HistoryAction, + pstr: str, + old_uuid: str, + new_uuid: str, + ) -> None: + """Replace ``old_uuid`` with ``new_uuid`` in an action's recorded inputs.""" + return hchain.rewrite_action_source(action, pstr, old_uuid, new_uuid) + + def remove_single_action(self, action: HistoryAction) -> None: + """Remove a single action from its session (splice, not truncate).""" + return hchain.remove_single_action(self, action) + + def reconnect_single_removed( + self, + panel: BaseDataPanel, + x_uuid: str, + warnings: list[str], + roots_to_recompute: list[HistoryAction], + ) -> None: + """Reconnect consumers of a single deleted object ``x_uuid``.""" + return hchain.reconnect_single_removed( + self, panel, x_uuid, warnings, roots_to_recompute + ) + + def reconnect_chain_after_removal(self, panel: BaseDataPanel) -> None: + """Reconnect the processing chain after object(s) were deleted.""" + return hchain.reconnect_chain_after_removal(self, panel) + + # ------------------------------------------------------------------ + # Recompute delegations + # ------------------------------------------------------------------ + + def refresh_action(self, action: HistoryAction) -> None: + """Refresh the tree display for ``action`` after its kwargs were mutated.""" + return hrec.refresh_action(self, action) + + def update_obj_in_place(self, target_obj: Any, new_obj: Any) -> None: + """Copy data + title + metadata from ``new_obj`` onto ``target_obj``.""" + return hrec.update_obj_in_place(target_obj, new_obj) + + def refresh_target(self, panel: BaseDataPanel, output_uuid: str) -> None: + """Refresh tree item + plot for ``output_uuid`` in ``panel``.""" + return hrec.refresh_target(panel, output_uuid) + + def record_missing_outputs(self, action: HistoryAction, missing: list[str]) -> None: + """Log + queue a user-facing warning for deleted output objects.""" + return hrec.record_missing_outputs(self, action, missing) + + def recompute_action_in_place(self, action: HistoryAction) -> None: + """Re-run ``action`` on the existing output object(s) (same UUIDs).""" + return hrec.recompute_action_in_place(self, action) + + def handle_missing_feature(self, action: HistoryAction, exc: Any) -> None: + """Flag ``action`` as broken (missing plugin) and queue a user warning.""" + return hrec.handle_missing_feature(self, action, exc) + + def recompute_1_to_1_in_place(self, action: HistoryAction) -> None: + """Recompute a single 1-to-1 action in place.""" + return hrec.recompute_1_to_1_in_place(self, action) + + def recompute_1_to_n_in_place(self, action: HistoryAction) -> None: + """Recompute a 1-to-n action in place.""" + return hrec.recompute_1_to_n_in_place(self, action) + + def recompute_n_to_1_in_place(self, action: HistoryAction) -> None: + """Recompute an n-to-1 action in place.""" + return hrec.recompute_n_to_1_in_place(self, action) + + def recompute_2_to_1_in_place(self, action: HistoryAction) -> None: + """Recompute a 2-to-1 action in place.""" + return hrec.recompute_2_to_1_in_place(self, action) + + def recompute_1_to_0_in_place(self, action: HistoryAction) -> None: + """Recompute a 1-to-0 analysis on each source object in place.""" + return hrec.recompute_1_to_0_in_place(self, action) + + def recompute_cascade( + self, + root_action: HistoryAction, + descendants: list[HistoryAction] | None = None, + ) -> None: + """Recompute ``root_action``'s descendants in the current session.""" + return hrec.recompute_cascade(self, root_action, descendants) + + def flush_cascade_warnings(self) -> None: + """Show + clear accumulated cascade warnings (no-op when empty).""" + return hrec.flush_cascade_warnings(self) + + # ------------------------------------------------------------------ + # Sync History tree selection → Signal/Image panel + # ------------------------------------------------------------------ + + def sync_panel_selection(self) -> None: + """Sync data panel selection from the currently selected tree item.""" + if self._replaying or self._syncing: + return + item = self.tree.currentItem() + if item is None or not item.isSelected(): + return + if item.parent() is None: + index = self.tree.indexOfTopLevelItem(item) + if index < 0 or index >= len(self._history_sessions): + return + session = self._history_sessions[index] + action = next( + (a for a in session.actions if a.kind == HistoryAction.KIND_COMPUTE), + None, + ) + if action is None: + return + else: + uuid = item.data(0, QC.Qt.UserRole) + try: + action = self.tree.get_action_from_uuid(uuid, self._history_sessions) + except ValueError: + return + + panel = self.resolve_panel_for_action(action) + if panel is None: + return + + target_uuids: list[str] = [] + output_uuid = self.find_output_object_uuid(panel, action) + if output_uuid is not None: + target_uuids = [output_uuid] + else: + target_uuids = self.existing_input_uuids(panel, action) + + if not target_uuids: + return + + self._syncing = True + try: + with QC.QSignalBlocker(panel.objview): + panel.objview.select_objects(target_uuids) + self.mainwindow.set_current_panel(panel) + finally: + self._syncing = False + + # ------------------------------------------------------------------ + # Step-by-step navigation + # ------------------------------------------------------------------ + + def current_action(self) -> HistoryAction | None: + """Return the action currently selected in the tree, or ``None``.""" + item = self.tree.currentItem() + if item is None or item.parent() is None: + return None + uuid = item.data(0, QC.Qt.UserRole) + try: + return self.tree.get_action_from_uuid(uuid, self._history_sessions) + except ValueError: + return None + + def current_session(self) -> HistorySession | None: + """Return the session relevant for step navigation.""" + item = self.tree.currentItem() + if item is not None: + if item.parent() is None: + index = self.tree.indexOfTopLevelItem(item) + if 0 <= index < len(self._history_sessions): + return self._history_sessions[index] + else: + action = self.current_action() + if action is not None: + return self.find_parent_session(action) + if self._history_sessions: + return self._history_sessions[-1] + return None + + def can_step_prev(self) -> bool: + """Return True if a previous action exists in the current session.""" + session = self.current_session() + if session is None or not session.actions: + return False + action = self.current_action() + if action is None or action not in session.actions: + return False + return session.actions.index(action) > 0 + + def can_step_next(self) -> bool: + """Return True if a next action exists in the current session.""" + session = self.current_session() + if session is None or not session.actions: + return False + action = self.current_action() + if action is None or action not in session.actions: + return True + return session.actions.index(action) < len(session.actions) - 1 + + def select_action_in_tree(self, action: HistoryAction) -> None: + """Select ``action`` in the tree (triggers ``sync_panel_selection``).""" + for i in range(self.tree.topLevelItemCount()): + sess_item = self.tree.topLevelItem(i) + for j in range(sess_item.childCount()): + child = sess_item.child(j) + if child.data(0, QC.Qt.UserRole) == action.uuid: + self.tree.clearSelection() + self.tree.setCurrentItem(child) + child.setSelected(True) + return + + def step_prev(self) -> None: + """Select the previous action in the current session.""" + if not self.can_step_prev(): + return + session = self.current_session() + action = self.current_action() + idx = session.actions.index(action) + self.select_action_in_tree(session.actions[idx - 1]) + self.update_actions_state() + + _step_prev = step_prev + + def step_next(self) -> None: + """Select the next action in the current session.""" + if not self.can_step_next(): + return + session = self.current_session() + action = self.current_action() + if action is None or action not in session.actions: + target = session.actions[0] + else: + target = session.actions[session.actions.index(action) + 1] + self.select_action_in_tree(target) + self.update_actions_state() + + _step_next = step_next + + # ------------------------------------------------------------------ + # History tools delegations + # ------------------------------------------------------------------ + + def duplicate_selected_entries(self) -> None: + """Duplicate selected entries.""" + return htools.duplicate_selected_entries(self) + + def generate_macro(self) -> None: + """Generate a Python macro script from history.""" + return htools.generate_macro(self) + + def select_sessions(self, sessions: list[HistorySession]) -> None: + """Select top-level tree items matching ``sessions``.""" + self.tree.clearSelection() + for session in sessions: + index = self._history_sessions.index(session) + item = self.tree.topLevelItem(index) + item.setSelected(True) + self.tree.setCurrentItem(item) + + def delete_selected(self) -> None: + """Delete the currently selected entries.""" + return htools.delete_selected(self) + + def remove_incompatible_actions(self) -> None: + """Remove actions incompatible with the current workspace.""" + return htools.remove_incompatible_actions(self) + + # ------------------------------------------------------------------ + # HDF5 / .dlhist I/O delegations + # ------------------------------------------------------------------ + + def save_to_dlhist_file(self, filename: str | None = None) -> bool: + """Save history to a standalone .dlhist file.""" + return hio.save_to_dlhist_file(self, filename) + + def open_dlhist_file(self, filename: str | None = None) -> bool: + """Open history from a standalone .dlhist file.""" + return hio.open_dlhist_file(self, filename) + + def import_dlhist_into_new_session(self, reader: NativeH5Reader) -> None: + """Import a .dlhist into a new session.""" + return hio.import_dlhist_into_new_session(self, reader) + + def refresh_compatibility_items(self, *args: Any) -> None: + """Refresh compatibility icons in the history tree.""" + return hio.refresh_compatibility_items(self, *args) + + def serialize_to_hdf5(self, writer: NativeH5Writer) -> None: + """Serialize the history to HDF5.""" + return hio.serialize_to_hdf5(self, writer) + + def deserialize_from_hdf5( + self, reader: NativeH5Reader, reset_all: bool = False + ) -> None: + """Deserialize the history from HDF5.""" + return hio.deserialize_from_hdf5(self, reader, reset_all) + + def __len__(self) -> int: + """Return number of objects.""" + return sum(len(session.actions) for session in self._history_sessions) + + def __getitem__(self, nb: int) -> HistoryAction: + """Return object from its number (1 to N).""" + for session in self._history_sessions: + if nb <= len(session.actions): + return session.actions[nb - 1] + nb -= len(session.actions) + raise IndexError("Index out of range") + + def __iter__(self) -> Generator[HistoryAction, None, None]: + """Iterate over objects.""" + for session in self._history_sessions: + yield from session.actions + + # ------------------------------------------------------------------ + # Session operations delegations + # ------------------------------------------------------------------ + + def create_new_session(self) -> None: + """Create a new history session.""" + return hsess.create_new_session(self) + + def start_new_session_after_workspace_reset(self) -> None: + """Start a new history session after a workspace reset.""" + return hsess.start_new_session_after_workspace_reset(self) + + def add_compute_entry( + self, + action_title: str, + panel_str: str, + func_name: str, + pattern: str, + save_state: bool = True, + output_uuids: list[str] | None = None, + plugin_origin: dict[str, Any] | None = None, + **kwargs: Any, + ) -> HistoryAction | None: + """Add a compute entry to the history.""" + return hsess.add_compute_entry( + self, + action_title, + panel_str, + func_name, + pattern, + save_state, + output_uuids, + plugin_origin, + **kwargs, + ) + + def add_compute_entry_from_pp( + self, + action_title: str, + pp: Any, + panel_str: str, + save_state: bool = True, + output_uuids: list[str] | None = None, + plugin_origin: dict[str, Any] | None = None, + **extras: Any, + ) -> HistoryAction | None: + """Add a compute entry built from a :class:`ProcessingParameters`.""" + return hsess.add_compute_entry_from_pp( + self, + action_title, + pp, + panel_str, + save_state, + output_uuids, + plugin_origin, + **extras, + ) + + def register_action_outputs( + self, action: HistoryAction, output_uuids: list[str] + ) -> None: + """Register the output UUIDs produced by ``action``.""" + return hsess.register_action_outputs(self, action, output_uuids) + + def capture_outputs( + self, action: HistoryAction | None + ) -> Generator[None, None, None]: + """Context manager capturing outputs produced by ``action``.""" + return hsess.capture_outputs(self, action) + + def add_ui_entry( + self, + action_title: str, + target: str, + method_name: str, + save_state: bool = True, + **kwargs: Any, + ) -> None: + """Add a UI entry to the history.""" + return hsess.add_ui_entry( + self, action_title, target, method_name, save_state, **kwargs + ) + + def add_entry( + self, + action_title: str, + save_state: bool, + func: Callable, + **kwargs: Any, + ) -> None: + """Add a generic entry to the history.""" + return hsess.add_entry(self, action_title, save_state, func, **kwargs) + + # ------ AbstractPanel interface --------------------------------------------------- + def create_object(self) -> HistoryAction: + """Create and return object.""" + return HistoryAction() + + def add_object(self, obj: HistoryAction) -> None: + """Add an object to the history.""" + return hsess.add_object(self, obj) + + def remove_all_objects(self) -> None: + """Remove all objects.""" + super().remove_all_objects() + self._action_output_uuids.clear() + self._output_to_action.clear() diff --git a/datalab/gui/panel/history/recompute.py b/datalab/gui/panel/history/recompute.py new file mode 100644 index 000000000..308d34e58 --- /dev/null +++ b/datalab/gui/panel/history/recompute.py @@ -0,0 +1,495 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +"""In-place recompute helpers for the History panel cascade.""" + +from __future__ import annotations + +import logging +from typing import TYPE_CHECKING + +from coverage.debug import pp +from qtpy import QtWidgets as QW +from sigima.objects import ImageObj, SignalObj + +from datalab.config import _ +from datalab.env import execenv +from datalab.gui.processor.base import ( + FeatureNotFoundError, + ProcessingParameters, + extract_processing_parameters, + insert_processing_parameters, +) +from datalab.history import HistoryAction +from datalab.objectmodel import get_uuid + +if TYPE_CHECKING: + from datalab.gui.panel.base import BaseDataPanel + from datalab.gui.panel.history.panel import HistoryPanel + +_logger = logging.getLogger(__name__) + + +def refresh_action(panel: HistoryPanel, action: HistoryAction) -> None: + """Refresh the tree display for ``action`` after its kwargs were mutated. + + Used by :meth:`ObjectProp.apply_processing_parameters` to update the + Description column when the user edits a ``param`` from the Processing + tab of the Signal/Image panel. + """ + panel.tree.refresh_action_item(action) + + +def update_obj_in_place( + target_obj: SignalObj | ImageObj, + new_obj: SignalObj | ImageObj, +) -> None: + """Copy data + title + metadata from ``new_obj`` onto ``target_obj``. + + Preserves the target's identity (UUID, panel position, references) + while reflecting all user-visible changes produced by a recompute. + """ + target_obj.title = new_obj.title + if isinstance(target_obj, SignalObj): + target_obj.xydata = new_obj.xydata + else: + target_obj.data = new_obj.data + target_obj.invalidate_maskdata_cache() + try: + saved_uuid = target_obj.metadata.get("__uuid") + saved_number = target_obj.metadata.get("__number") + target_obj.metadata.clear() + target_obj.metadata.update(new_obj.metadata) + if saved_uuid is not None: + target_obj.metadata["__uuid"] = saved_uuid + if saved_number is not None: + target_obj.metadata["__number"] = saved_number + except AttributeError: + pass + + +def refresh_target(panel_data: BaseDataPanel, output_uuid: str) -> None: + """Refresh tree item + plot for ``output_uuid`` in ``panel_data``. + + Also updates the Properties panel when the refreshed object is + currently selected, marks the object as freshly processed so the + Processing tab is shown, and emits ``SIG_OBJECT_MODIFIED``. + """ + panel_data.objview.update_item(output_uuid) + panel_data.refresh_plot(output_uuid, update_items=True, force=True) + obj = ( + panel_data.objmodel[output_uuid] + if panel_data.objmodel.has_uuid(output_uuid) + else None + ) + if obj is not None: + if obj is panel_data.objview.get_current_object(): + panel_data.objprop.update_properties_from(obj, force_tab="processing") + else: + panel_data.objprop.mark_as_freshly_processed(obj) + panel_data.SIG_OBJECT_MODIFIED.emit() + + +def record_missing_outputs( + panel: HistoryPanel, action: HistoryAction, missing: list[str] +) -> None: + """Log + queue a user-facing warning for deleted output objects.""" + if not missing: + return + name = action.func_name or action.title or action.uuid + _logger.warning( + "Cascade recompute: %d output(s) missing for action %s (%s).", + len(missing), + action.uuid, + name, + ) + panel._cascade_warnings.append( + _( + "Action %s has been edited but its target output object(s) " + "no longer exist — skipping." + ) + % name + ) + + +def recompute_action_in_place(panel: HistoryPanel, action: HistoryAction) -> None: + """Re-run ``action`` on the existing output object(s) (same UUIDs).""" + if action.kind != HistoryAction.KIND_COMPUTE: + return + method = { + "1_to_1": recompute_1_to_1_in_place, + "1_to_n": recompute_1_to_n_in_place, + "n_to_1": recompute_n_to_1_in_place, + "2_to_1": recompute_2_to_1_in_place, + "1_to_0": recompute_1_to_0_in_place, + }.get(action.pattern or "") + if method is None: + _logger.warning( + "Cascade recompute: unsupported pattern %r for action %s.", + action.pattern, + action.uuid, + ) + panel._cascade_warnings.append( + _("Action %s uses pattern %r which is not recomputable yet.") + % (action.func_name or action.uuid, action.pattern) + ) + return + try: + method(panel, action) + except FeatureNotFoundError as exc: + handle_missing_feature(panel, action, exc) + except (RuntimeError, ValueError, AttributeError, KeyError, TypeError) as exc: + _logger.exception( + "Cascade recompute failed for action %s (%s): %s", + action.uuid, + action.func_name, + exc, + ) + panel._cascade_warnings.append( + _("Recompute failed for action %s: %s") + % (action.func_name or action.uuid, exc) + ) + + +def handle_missing_feature( + panel: HistoryPanel, action: HistoryAction, exc: FeatureNotFoundError +) -> None: + """Flag ``action`` as broken (missing plugin) and queue a user warning.""" + action.is_stale = True + panel._broken_actions.add(action.uuid) + plugin_origin = action.plugin_origin or exc.plugin_origin or {} + directory = (plugin_origin.get("directory") if plugin_origin else None) or "?" + param = action.kwargs.get("param") + paramclass = exc.paramclass_name or ( + type(param).__name__ if param is not None else "—" + ) + func_name = action.func_name or exc.func_name or action.uuid + location = f"{directory}/plugins:{func_name}" + _logger.warning( + "Cascade recompute: plugin missing for action %s (%s) — %s.", + action.uuid, + func_name, + location, + ) + panel._cascade_warnings.append( + _( + "Action %(name)s skipped: plugin '%(loc)s' is missing.\n" + "Required parameter class: %(param)s\n" + "Reinstall the plugin to re-enable this action." + ) + % {"name": func_name, "loc": location, "param": paramclass} + ) + + +def recompute_1_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> None: + """Recompute a single 1-to-1 action in place.""" + panel_data = panel.resolve_panel_for_action(action) + if panel_data is None: + return + existing, missing = panel.resolve_target_outputs(panel_data, action) + if not existing and not missing: + legacy = panel.find_output_object_uuid(panel_data, action) + if legacy is not None: + existing = [legacy] + record_missing_outputs(panel, action, missing) + if not existing: + return + output_uuid = existing[0] + if not panel_data.objmodel.has_uuid(output_uuid): + return + output_obj = panel_data.objmodel[output_uuid] + pp = extract_processing_parameters(output_obj) + if pp is None or pp.source_uuid is None: + return + if not panel_data.objmodel.has_uuid(pp.source_uuid): + panel._cascade_warnings.append( + _("Action %s: source object was deleted — skipping.") + % (action.func_name or action.uuid) + ) + return + source_obj = panel_data.objmodel[pp.source_uuid] + param = action.kwargs.get("param") + new_obj = panel_data.processor.recompute_1_to_1( + action.func_name, + source_obj, + param, + plugin_origin=action.plugin_origin, + ) + if new_obj is None: + return + update_obj_in_place(output_obj, new_obj) + insert_processing_parameters( + output_obj, + ProcessingParameters( + func_name=pp.func_name, + pattern=pp.pattern, + param=param if param is not None else pp.param, + source_uuid=pp.source_uuid, + ), + ) + panel_data.processor.auto_recompute_analysis(output_obj) + refresh_target(panel_data, output_uuid) + + +def recompute_1_to_n_in_place(panel: HistoryPanel, action: HistoryAction) -> None: + """Recompute a 1-to-n action in place: replace each of the N outputs.""" + panel_data = panel.resolve_panel_for_action(action) + if panel_data is None: + return + existing, missing = panel.resolve_target_outputs(panel_data, action) + record_missing_outputs(panel, action, missing) + if not existing: + return + if not panel_data.objmodel.has_uuid(existing[0]): + return + first_obj = panel_data.objmodel[existing[0]] + pp = extract_processing_parameters(first_obj) + if pp is None or pp.source_uuid is None: + return + if not panel_data.objmodel.has_uuid(pp.source_uuid): + panel._cascade_warnings.append( + _("Action %s: source object was deleted — skipping.") + % (action.func_name or action.uuid) + ) + return + source_obj = panel_data.objmodel[pp.source_uuid] + params = action.kwargs.get("params") or [] + if not params: + return + new_objs = panel_data.processor.recompute_1_to_n( + action.func_name, + source_obj, + params, + plugin_origin=action.plugin_origin, + ) + if not new_objs: + return + n = min(len(existing), len(new_objs)) + for idx in range(n): + out_uuid = existing[idx] + if not panel_data.objmodel.has_uuid(out_uuid): + continue + out_obj = panel_data.objmodel[out_uuid] + new_obj = new_objs[idx] + update_obj_in_place(out_obj, new_obj) + new_param = params[idx] if idx < len(params) else None + insert_processing_parameters( + out_obj, + ProcessingParameters( + func_name=action.func_name, + pattern="1-to-n", + param=new_param, + source_uuid=pp.source_uuid, + ), + ) + panel_data.processor.auto_recompute_analysis(out_obj) + refresh_target(panel_data, out_uuid) + if len(new_objs) != len(existing): + _logger.warning( + "1-to-n cardinality changed for action %s: %d outputs, %d existing.", + action.uuid, + len(new_objs), + len(existing), + ) + + +def recompute_n_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> None: + """Recompute an n-to-1 action in place.""" + panel_data = panel.resolve_panel_for_action(action) + if panel_data is None: + return + existing, missing = panel.resolve_target_outputs(panel_data, action) + record_missing_outputs(panel, action, missing) + if not existing: + return + output_uuid = existing[0] + if not panel_data.objmodel.has_uuid(output_uuid): + return + output_obj = panel_data.objmodel[output_uuid] + pp = extract_processing_parameters(output_obj) + source_uuids: list[str] = [] + if pp is not None and pp.source_uuids: + source_uuids = list(pp.source_uuids) + else: + source_uuids = list(action.state.selection.get(panel_data.PANEL_STR_ID, [])) + src_objs: list[SignalObj | ImageObj] = [] + for uuid in source_uuids: + if panel_data.objmodel.has_uuid(uuid): + src_objs.append(panel_data.objmodel[uuid]) + if not src_objs: + panel._cascade_warnings.append( + _("Action %s: all source objects were deleted — skipping.") + % (action.func_name or action.uuid) + ) + return + param = action.kwargs.get("param") + new_obj = panel_data.processor.recompute_n_to_1( + action.func_name, + src_objs, + param, + plugin_origin=action.plugin_origin, + ) + if new_obj is None: + return + update_obj_in_place(output_obj, new_obj) + insert_processing_parameters( + output_obj, + ProcessingParameters( + func_name=action.func_name, + pattern="n-to-1", + param=param, + source_uuids=[get_uuid(o) for o in src_objs], + ), + ) + panel_data.processor.auto_recompute_analysis(output_obj) + refresh_target(panel_data, output_uuid) + + +def recompute_2_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> None: + """Recompute a 2-to-1 action in place (single or pairwise).""" + panel_data = panel.resolve_panel_for_action(action) + if panel_data is None: + return + existing, missing = panel.resolve_target_outputs(panel_data, action) + record_missing_outputs(panel, action, missing) + if not existing: + return + param = action.kwargs.get("param") + obj2_uuids = action.kwargs.get("obj2_uuids") or [] + if isinstance(obj2_uuids, str): + obj2_uuids = [obj2_uuids] + pairwise = bool(action.kwargs.get("pairwise")) + recorded_inputs = list(action.state.selection.get(panel_data.PANEL_STR_ID, [])) + for idx, out_uuid in enumerate(existing): + if not panel_data.objmodel.has_uuid(out_uuid): + continue + output_obj = panel_data.objmodel[out_uuid] + pp = extract_processing_parameters(output_obj) + src_uuids = ( + list(pp.source_uuids) + if pp is not None and pp.source_uuids + else ( + recorded_inputs[idx : idx + 1] + obj2_uuids[idx : idx + 1] + if pairwise + else recorded_inputs[idx : idx + 1] + obj2_uuids[:1] + ) + ) + if len(src_uuids) < 2: + panel._cascade_warnings.append( + _("Action %s: missing source(s) for output #%d — skipping.") + % (action.func_name or action.uuid, idx + 1) + ) + continue + if not ( + panel_data.objmodel.has_uuid(src_uuids[0]) + and panel_data.objmodel.has_uuid(src_uuids[1]) + ): + panel._cascade_warnings.append( + _("Action %s: source object(s) were deleted — skipping.") + % (action.func_name or action.uuid) + ) + continue + obj1 = panel_data.objmodel[src_uuids[0]] + obj2 = panel_data.objmodel[src_uuids[1]] + new_obj = panel_data.processor.recompute_2_to_1( + action.func_name, + obj1, + obj2, + param, + plugin_origin=action.plugin_origin, + ) + if new_obj is None: + continue + update_obj_in_place(output_obj, new_obj) + insert_processing_parameters( + output_obj, + ProcessingParameters( + func_name=action.func_name, + pattern="2-to-1", + param=param, + source_uuids=[get_uuid(obj1), get_uuid(obj2)], + ), + ) + panel_data.processor.auto_recompute_analysis(output_obj) + refresh_target(panel_data, out_uuid) + + +def recompute_1_to_0_in_place(panel: HistoryPanel, action: HistoryAction) -> None: + """Recompute a 1-to-0 analysis on each source object in place.""" + panel_data = panel.resolve_panel_for_action(action) + if panel_data is None: + return + sources = list(action.state.selection.get(panel_data.PANEL_STR_ID, [])) + if not sources: + return + param = action.kwargs.get("param") + missing: list[str] = [] + for uuid in sources: + if not panel_data.objmodel.has_uuid(uuid): + missing.append(uuid) + continue + src_obj = panel_data.objmodel[uuid] + panel_data.processor.recompute_1_to_0( + action.func_name, + src_obj, + param, + plugin_origin=action.plugin_origin, + ) + refresh_target(panel_data, uuid) + if missing: + panel._cascade_warnings.append( + _("Action %s: %d analysed object(s) were deleted — skipping.") + % (action.func_name or action.uuid, len(missing)) + ) + + +def recompute_cascade( + panel: HistoryPanel, + root_action: HistoryAction, + descendants: list[HistoryAction] | None = None, +) -> None: + """Recompute ``root_action``'s descendants in the current session in place.""" + if descendants is None: + descendants = panel.get_downstream_actions(root_action) + if root_action.is_stale: + descendants = [root_action] + descendants + if getattr(panel, "_cascade_in_progress", False): + flush_cascade_warnings(panel) + return + if not descendants: + flush_cascade_warnings(panel) + return + panel._broken_actions.clear() + panel._cascade_in_progress = True + try: + for action in descendants: + action.is_stale = True + panel.tree.refresh_action_item(action) + QW.QApplication.processEvents() + for action in descendants: + try: + recompute_action_in_place(panel, action) + finally: + if action.uuid not in panel._broken_actions: + action.is_stale = False + panel.tree.refresh_action_item(action) + QW.QApplication.processEvents() + finally: + for action in descendants: + if action.is_stale and action.uuid not in panel._broken_actions: + action.is_stale = False + panel.tree.refresh_action_item(action) + panel._cascade_in_progress = False + flush_cascade_warnings(panel) + + +def flush_cascade_warnings(panel: HistoryPanel) -> None: + """Show + clear accumulated cascade warnings (no-op when empty).""" + if panel._cascade_warnings and not execenv.unattended: + QW.QMessageBox.warning( + panel.mainwindow, + _("Cascade recompute"), + _("Some downstream actions could not be recomputed:") + + "\n\n• " + + "\n• ".join(panel._cascade_warnings), + ) + panel._cascade_warnings = [] diff --git a/datalab/h5/history.py b/datalab/h5/history.py new file mode 100644 index 000000000..55060006c --- /dev/null +++ b/datalab/h5/history.py @@ -0,0 +1,263 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +"""History panel HDF5 import/export and persistence helpers.""" + +from __future__ import annotations + +import os.path as osp +from typing import TYPE_CHECKING, Any +from uuid import uuid4 + +from qtpy.compat import getopenfilename, getsavefilename + +from datalab.config import Conf, _ +from datalab.gui.processor.base import ( + PROCESSING_PARAMETERS_OPTION, + ProcessingParameters, +) +from datalab.h5.native import NativeH5Reader, NativeH5Writer +from datalab.history import HistorySession +from datalab.objectmodel import get_uuid +from datalab.utils.qthelpers import qt_try_loadsave_file, save_restore_stds + +if TYPE_CHECKING: + from datalab.gui.panel.history import HistoryPanel + + +def save_to_dlhist_file(panel: HistoryPanel, filename: str | None = None) -> bool: + """Save the History Panel content to a standalone ``.dlhist`` file. + + Args: + filename: History filename. If None, a file dialog is opened. + + Returns: + True if the history was saved, False if the operation was canceled. + """ + if filename is None: + basedir = Conf.main.base_dir.get() + with save_restore_stds(): + filename, _filt = getsavefilename( + panel, _("Save history file"), basedir, panel.FILE_FILTERS + ) + if not filename: + return False + if osp.splitext(filename)[1] == "": + filename += ".dlhist" + with qt_try_loadsave_file(panel.parentWidget(), filename, "save"): + Conf.main.base_dir.set(filename) + with NativeH5Writer(filename) as writer: + # Make the .dlhist file panel-contained: store the signal and + # image panel objects (all of them) alongside the history, so + # that reopening restores both the data objects and the history + # that references them. Each section is read back by its own + # H5_PREFIX key, so the write order is not significant. + panel.mainwindow.signalpanel.serialize_to_hdf5(writer) + panel.mainwindow.imagepanel.serialize_to_hdf5(writer) + panel.serialize_to_hdf5(writer) + return True + + +def open_dlhist_file(panel: HistoryPanel, filename: str | None = None) -> bool: + """Open a standalone ``.dlhist`` file into the History Panel. + + Args: + filename: History filename. If None, a file dialog is opened. + + Returns: + True if the history was loaded, False if the operation was canceled. + """ + if filename is None: + basedir = Conf.main.base_dir.get() + with save_restore_stds(): + filename, _filt = getopenfilename( + panel, _("Open history file"), basedir, panel.FILE_FILTERS + ) + if not filename: + return False + with qt_try_loadsave_file(panel.parentWidget(), filename, "load"): + Conf.main.base_dir.set(filename) + with NativeH5Reader(filename) as reader: + # A panel-contained .dlhist file stores the signal and image + # panel objects in addition to the history sessions. The way + # they are restored depends on whether the workspace is already + # in use (data objects OR history): a pristine workspace is + # loaded directly while preserving UUIDs, otherwise the file + # is imported as new groups/sessions. + workspace_in_use = ( + panel.mainwindow.signalpanel.objmodel.get_object_ids() + or panel.mainwindow.imagepanel.objmodel.get_object_ids() + or bool(panel.history_sessions) + ) + if workspace_in_use: + # Workspace not empty: import the objects into new groups + # with fresh UUIDs and append the history as new sessions + # whose references are remapped to the imported objects. + panel.import_dlhist_into_new_session(reader) + else: + # Workspace empty: load directly, preserving original UUIDs + # (reset_all=True) so that history references stay valid. + panel.mainwindow.signalpanel.deserialize_from_hdf5( + reader, reset_all=True + ) + panel.mainwindow.imagepanel.deserialize_from_hdf5( + reader, reset_all=True + ) + panel.deserialize_from_hdf5(reader) + return True + + +def import_dlhist_into_new_session(panel: HistoryPanel, reader: NativeH5Reader) -> None: + """Import a ``.dlhist`` file into new groups and new history sessions. + + Used when the workspace already contains objects: the file's signal and + image objects are imported into fresh groups with regenerated UUIDs, and + the history sessions are appended as new independent sessions whose action + references are remapped to the freshly imported objects. + + Args: + reader: HDF5 reader positioned on a ``.dlhist`` file. + """ + panel_map = { + "signal": panel.mainwindow.signalpanel, + "image": panel.mainwindow.imagepanel, + } + uuid_remap: dict[str, dict[str, str]] = {} + imported_by_pstr: dict[str, list] = {} + # 1. Import objects from each panel (each panel is read by its own + # H5_PREFIX key). Read each object preserving its original UUID to + # capture the old->new mapping, then assign a fresh UUID so that the + # imported objects keep an independent identity. + for pstr, data_panel in panel_map.items(): + uuid_remap[pstr] = {} + imported: list = [] + imported_by_pstr[pstr] = imported + if data_panel.H5_PREFIX not in reader.h5: + continue + with reader.group(data_panel.H5_PREFIX): + for name in reader.h5.get(data_panel.H5_PREFIX, []): + with reader.group(name): + group = data_panel.add_group("") + with reader.group("title"): + group.title = reader.read_str() + for obj_name in reader.h5.get(f"{data_panel.H5_PREFIX}/{name}", []): + obj = data_panel.deserialize_object_from_hdf5( + reader, obj_name, reset_all=True + ) + old_uuid = get_uuid(obj) + new_uuid = str(uuid4()) + # SignalObj/ImageObj store UUID via metadata option + try: + obj.set_metadata_option("uuid", new_uuid) + except AttributeError: + obj.uuid = new_uuid + uuid_remap[pstr][old_uuid] = new_uuid + data_panel.add_object(obj, get_uuid(group), set_current=False) + imported.append(obj) + data_panel.selection_changed() + # 2. Remap source UUIDs in imported objects' processing_parameters so + # that reprocessing in the Processing tab uses the imported sources, + # not the originals (same logic as duplicate_selected_entries). + for pstr, objs in imported_by_pstr.items(): + pmap = uuid_remap.get(pstr, {}) + if not pmap: + continue + for obj in objs: + try: + pp_dict = obj.get_metadata_option(PROCESSING_PARAMETERS_OPTION) + except (AttributeError, ValueError): + continue + if not pp_dict: + continue + try: + pp = ProcessingParameters.from_dict(pp_dict) + except (TypeError, ValueError, AttributeError): + continue + changed = False + if pp.source_uuid is not None and pp.source_uuid in pmap: + pp.source_uuid = pmap[pp.source_uuid] + changed = True + if pp.source_uuids is not None: + new_src = [pmap.get(u, u) for u in pp.source_uuids] + if new_src != pp.source_uuids: + pp.source_uuids = new_src + changed = True + if changed: + try: + obj.set_metadata_option(PROCESSING_PARAMETERS_OPTION, pp.to_dict()) + except (AttributeError, ValueError): + pass + # 3. Import history sessions as new independent sessions whose captured + # UUIDs are remapped to the imported objects. + if panel.H5_PREFIX not in reader.h5: + return + sessions = reader.read_object_list(panel.H5_PREFIX, HistorySession) or [] + imported_suffix = _("Imported") + new_sessions: list[HistorySession] = [] + for session in sessions: + panel.session_increment += 1 + title = f"{session.title} {imported_suffix}" + new_session = session.copy_with_uuid_remap(title=title, uuid_remap=uuid_remap) + new_session.number = panel.session_increment + new_sessions.append(new_session) + # Register output mappings for imported actions so that + # _resolve_target_outputs / get_downstream_actions work. + for action in new_session.actions: + if action.output_uuids: + panel._action_output_uuids[action.uuid] = list(action.output_uuids) + for out_uuid in action.output_uuids: + panel._output_to_action[out_uuid] = action.uuid + panel.history_sessions.extend(new_sessions) + panel.tree.populate_tree(panel.history_sessions) + panel.refresh_compatibility_items() + panel.update_actions_state() + + +def refresh_compatibility_items(panel: HistoryPanel, *args: Any) -> None: + """Refresh action item compatibility markers in the tree.""" + del args + panel.tree.update_compatibility_states(panel.history_sessions, panel.mainwindow) + + +def serialize_to_hdf5(panel: HistoryPanel, writer: NativeH5Writer) -> None: + """Serialize whole panel to a HDF5 file + + Args: + writer: HDF5 writer + """ + writer.write_object_list(panel.history_sessions, panel.H5_PREFIX) + + +def deserialize_from_hdf5( + panel: HistoryPanel, reader: NativeH5Reader, reset_all: bool = False +) -> None: + """Deserialize whole panel from a HDF5 file + + Args: + reader: HDF5 reader + reset_all: Unused (kept for compatibility with panel API) + """ + if panel.H5_PREFIX not in reader.h5: + panel.history_sessions = [] + panel.session_increment = 0 + panel.tree.populate_tree(panel.history_sessions) + panel.update_actions_state() + return + panel.history_sessions = ( + reader.read_object_list(panel.H5_PREFIX, HistorySession) or [] + ) + if panel.history_sessions: + panel.session_increment = panel.history_sessions[-1].number + # Rebuild the bijective mapping from the loaded actions. Legacy + # (v1) actions have empty ``output_uuids`` and contribute nothing + # to the index — the heuristic fallback handles them. + panel._action_output_uuids = {} + panel._output_to_action = {} + for session in panel.history_sessions: + for action in session.actions: + if action.output_uuids: + panel._action_output_uuids[action.uuid] = list(action.output_uuids) + for out_uuid in action.output_uuids: + panel._output_to_action[out_uuid] = action.uuid + panel.tree.populate_tree(panel.history_sessions) + panel.refresh_compatibility_items() + panel.update_actions_state() diff --git a/datalab/history/__init__.py b/datalab/history/__init__.py new file mode 100644 index 000000000..2ecb73c20 --- /dev/null +++ b/datalab/history/__init__.py @@ -0,0 +1,23 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +"""DataLab history model package (pure data model, no Qt widgets).""" + +from datalab.history.action import HistoryAction +from datalab.history.core import ( + HISTORY_ACTION_SCHEMA_VERSION, + HISTORY_SCHEMA_VERSION, + add_to_history, + get_datetime_str, +) +from datalab.history.session import HistorySession +from datalab.history.workspace_state import WorkspaceState + +__all__ = [ + "HISTORY_ACTION_SCHEMA_VERSION", + "HISTORY_SCHEMA_VERSION", + "HistoryAction", + "HistorySession", + "WorkspaceState", + "add_to_history", + "get_datetime_str", +] diff --git a/datalab/history/action.py b/datalab/history/action.py new file mode 100644 index 000000000..4d1907976 --- /dev/null +++ b/datalab/history/action.py @@ -0,0 +1,781 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +"""HistoryAction model: serialisable description of one recorded operation.""" + +from __future__ import annotations + +import html +import inspect +import json +import logging +import os +from typing import TYPE_CHECKING, Any, Callable, Generator +from uuid import uuid4 + +import sigima.proc.image +import sigima.proc.signal +from guidata.dataset.datatypes import DataSet +from sigima.objects import ( # noqa: F401 (kept for downstream consumers) + ImageObj, + SignalObj, +) + +from datalab.config import _ +from datalab.gui import ObjItf +from datalab.history.core import ( + HISTORY_ACTION_SCHEMA_VERSION, + HISTORY_SCHEMA_VERSION, + _copy_history_value, + _decode_kwargs, + _encode_kwargs, + get_datetime_str, +) +from datalab.history.workspace_state import WorkspaceState +from datalab.objectmodel import get_uuid + +if TYPE_CHECKING: + from datalab.gui.main import DLMainWindow + from datalab.h5.native import NativeH5Reader, NativeH5Writer + +_logger = logging.getLogger(__name__) + + +class HistoryAction(ObjItf): + """Object representing an action in the history panel. + + An action is a serialisable description of either a *compute* call (resolved + via the panel processor's feature registry) or a *UI* call (resolved as a + method on a known target -- ``mainwindow``/``signalpanel``/``imagepanel``). + + No Python ``Callable`` is ever pickled: a compute action is identified by + ``(panel_str, func_name, pattern)`` and a UI action by ``(target, + method_name)``. ``DataSet`` payloads inside ``kwargs`` are serialised with + :func:`guidata.dataset.conv.dataset_to_json`. + """ + + KIND_COMPUTE = "compute" + KIND_UI = "ui" + + FUNC_EDIT_MODE = "edit" # Name of the function parameter to enable edit mode + # Methods that create new data objects. During non-persistent (output-suppressed) + # replay, these UI actions are skipped so the panel object count stays stable. + UI_CREATION_METHODS: frozenset[str] = frozenset({"new_object"}) + + def __init__( + self, + title: str = "", + kind: str = KIND_UI, + # --- compute-only -------------------------------------------------- + panel_str: str | None = None, + func_name: str | None = None, + pattern: str | None = None, + # --- ui-only ------------------------------------------------------- + target: str | None = None, + method_name: str | None = None, + # --- common -------------------------------------------------------- + kwargs: dict[str, Any] | None = None, + state: WorkspaceState | None = None, + plugin_origin: dict[str, Any] | None = None, + ) -> None: + super().__init__() + self.__title = title or "" + self.kind = kind + # Compute kind: + self.panel_str = panel_str + self.func_name = func_name + self.pattern = pattern + # UI kind: + self.target = target + self.method_name = method_name + # Common: + self.kwargs: dict[str, Any] = ( + {} if kwargs is None else {k: v for k, v in kwargs.items() if v is not None} + ) + self.state = WorkspaceState() if state is None else state + self.dtstr: str = get_datetime_str() + self.uuid: str = str(uuid4()) + self.schema_version: int = HISTORY_ACTION_SCHEMA_VERSION + # UUIDs of the data objects produced by this action (bijective mapping + # maintained by :class:`HistoryPanel`). Populated post-compute via + # :meth:`HistoryPanel.register_action_outputs`. Empty for ``1_to_0`` + # patterns, for UI actions, and for sessions loaded without output info + # loaded from disk (the heuristic fallback then takes over). + self.output_uuids: list[str] = [] + # Plugin origin descriptor for compute actions (None for built-in + # Sigima/DataLab features). Populated at registration time by + # :meth:`BaseProcessor.add_feature` and propagated through + # ``add_compute_entry_from_pp``. See + # :func:`datalab.gui.processor.base._detect_plugin_origin` for shape. + # Persisted as a JSON string in HDF5. + self.plugin_origin: dict[str, Any] | None = plugin_origin + # Transient flag (NOT serialized): set during a cascade recompute to + # display a "stale" visual marker in the tree. Cleared once the + # action has been recomputed. + self.is_stale: bool = False + # Snapshot of original kwargs before edit-mode modification. + # Set lazily when the first edit-mode change touches this action. + # Persisted to HDF5 so that the Restore + # action still works after a save/reload cycle while Edit mode is + # active. Cleared by ``discard_snapshot`` (definitive commit when + # toggling Edit mode off) or ``restore_kwargs`` (Restore button). + self._saved_kwargs: dict[str, Any] | None = None + + def snapshot_kwargs(self) -> None: + """Save a copy of the current kwargs as the pre-edit baseline. + + No-op if a snapshot already exists (preserves the original baseline + across multiple edit-mode replays). + """ + if self._saved_kwargs is None: + self._saved_kwargs = { + key: _copy_history_value(value) for key, value in self.kwargs.items() + } + + def restore_kwargs(self) -> None: + """Restore kwargs from the saved snapshot and clear the snapshot.""" + if self._saved_kwargs is not None: + self.kwargs = self._saved_kwargs + self._saved_kwargs = None + + def discard_snapshot(self) -> None: + """Discard the saved snapshot (accept current kwargs as definitive).""" + self._saved_kwargs = None + + @property + def has_pending_edits(self) -> bool: + """Return True if this action has unsaved edit-mode changes.""" + return self._saved_kwargs is not None + + def regenerate_uuid(self): + """Regenerate UUID after loading from a file (no-op: per-action UUID).""" + + def copy(self, title_suffix: str | None = None) -> HistoryAction: + """Return an independent copy of this history action.""" + state = self.state.copy() + title = self.title + if title_suffix: + title = f"{title} {title_suffix}" + new_action = HistoryAction( + title=title, + kind=self.kind, + panel_str=self.panel_str, + func_name=self.func_name, + pattern=self.pattern, + target=self.target, + method_name=self.method_name, + kwargs={ + key: _copy_history_value(value) for key, value in self.kwargs.items() + }, + state=state, + ) + new_action.output_uuids = list(self.output_uuids) + # Note: _saved_kwargs is intentionally NOT propagated to the copy. + # Copying an action acts as an implicit commit (no pending edits). + return new_action + + def copy_with_uuid_remap( + self, uuid_remap: dict[str, dict[str, str]] + ) -> HistoryAction: + """Return a copy of this action with all captured UUIDs rewritten. + + Args: + uuid_remap: Per-panel mapping ``{panel_str: {old_uuid: new_uuid}}`` + used to translate captured UUIDs to the cloned objects created by + the Duplicate operation. + + Returns: + A new independent :class:`HistoryAction` with remapped UUIDs. + """ + new_action = self.copy() + # Rewrite state.selection + for pstr, uuids in new_action.state.selection.items(): + pmap = uuid_remap.get(pstr, {}) + new_action.state.selection[pstr] = [pmap.get(u, u) for u in uuids] + # Rewrite state.object_metadata keys + for pstr, metadata in new_action.state.object_metadata.items(): + pmap = uuid_remap.get(pstr, {}) + new_action.state.object_metadata[pstr] = { + pmap.get(uuid, uuid): val for uuid, val in metadata.items() + } + # Rewrite obj2_uuids in kwargs + obj2 = new_action.kwargs.get("obj2_uuids") + if obj2: + if isinstance(obj2, str): + obj2 = [obj2] + pstr = new_action.panel_str or "" + pmap = uuid_remap.get(pstr, {}) + rewritten = [pmap.get(u, u) for u in obj2] + new_action.kwargs["obj2_uuids"] = ( + rewritten[0] if len(rewritten) == 1 else rewritten + ) + # Rewrite output_uuids — they reference the target panel. + if new_action.output_uuids: + pstr = new_action.panel_str or "" + pmap = uuid_remap.get(pstr, {}) + new_action.output_uuids = [pmap.get(u, u) for u in new_action.output_uuids] + return new_action + + @property + def title(self) -> str: + """Return object title""" + return self.__title + + # ------------------------------------------------------------------ + # Description rendering (used by the tree view) + # ------------------------------------------------------------------ + + def __iter_param_kwargs(self) -> Generator[Any, None, None]: + """Yield kwargs values whose name ends with ``param`` (typically DataSets).""" + for kwname, value in self.kwargs.items(): + if kwname.endswith("param") and value is not None: + yield value + + @property + def description(self) -> str: + """Return object description (string representing function parameters)""" + desc = "" + no_parameters = True + for param in self.__iter_param_kwargs(): + if desc: + desc += os.linesep + desc += str(param) + no_parameters = False + if desc or no_parameters: + if desc: + return desc + # Fall back to a textual hint of the resolved callable + return self.__fallback_doc() + + def __fallback_doc(self) -> str: + """Return a single-line docstring for the underlying call, if available.""" + try: + func = self._resolve_callable() + except ( + ImportError, + ModuleNotFoundError, + AttributeError, + TypeError, + ValueError, + ): + return "" + doc = getattr(func, "__doc__", None) or "" + return doc.splitlines()[0] if doc else "" + + @property + def description_summary(self) -> str: + """Return a short, single-line summary of the description (collapsed view). + + For DataSet parameters, uses the dataset title followed by a compact + representation of its public fields ("name=value, ..."). Falls back to + the first non-empty line of the full description when no DataSet is + present. + """ + summaries: list[str] = [] + for param in self.__iter_param_kwargs(): + if isinstance(param, DataSet): + title = param.get_title() or "" + # Collect "name=value" for each non-private item of the DataSet. + pairs: list[str] = [] + for item in param.get_items(): + name = item.get_name() + if name.startswith("_"): + continue + try: + value = item.get_value(param) + except (AttributeError, KeyError, TypeError, ValueError): + continue + # Format floats compactly, leave other reprs as-is + if isinstance(value, float): + value_str = f"{value:g}" + else: + value_str = str(value) + pairs.append(f"{name}={value_str}") + if pairs: + summaries.append( + f"{title}: {', '.join(pairs)}" if title else ", ".join(pairs) + ) + elif title: + summaries.append(title) + if summaries: + return " | ".join(summaries) + for line in self.description.splitlines(): + stripped = line.strip() + if stripped: + return stripped + return "" + + @property + def description_html(self) -> str: + """Return rich-text (HTML) description used for the expanded view.""" + # Normal path + parts: list[str] = [] + no_parameters = True + for param in self.__iter_param_kwargs(): + no_parameters = False + if isinstance(param, DataSet): + parts.append(param.to_html()) + else: + parts.append(html.escape(str(param)).replace("\n", "<br>")) + if parts: + return "<br><br>".join(parts) + if no_parameters: + text = self.description + if not text: + return "" + return html.escape(text).replace("\n", "<br>") + return "" + + def to_macro_code( + self, + step_index: int, + input_var: str, + imports: set[str], + obj2_var: str | None = None, + ) -> tuple[list[str], str | None]: + """Return Python source lines for this action as a standalone sigima call. + + Args: + step_index: Step number for variable naming. + input_var: Name of the input variable from the previous step. + imports: Mutable set of import statements accumulated by the caller. + obj2_var: Resolved variable name for the second operand (2-to-1 + pattern). When ``None``, the second operand is left as a + placeholder. + + Returns: + Tuple of (code_lines, output_var_name). ``output_var_name`` is + ``None`` for UI-kind actions (no data output). + """ + if self.kind != self.KIND_COMPUTE: + return [f"# (UI) {self.title} [skipped]"], None + + lines: list[str] = [] + output_var = f"result_{step_index}" + + # Determine the sigima module alias + if self.panel_str == "signal": + mod_alias = "sips" + imports.add("import sigima.proc.signal as sips") + elif self.panel_str == "image": + mod_alias = "sipi" + imports.add("import sigima.proc.image as sipi") + else: + lines.append(f"# {self.title} [unknown panel: {self.panel_str}]") + return lines, None + + lines.append(f"# Step {step_index}: {self.title}") + + param = self.kwargs.get("param") + param_var: str | None = None + + if param is not None and isinstance(param, DataSet): + param_var = f"param_{step_index}" + param_class = type(param).__qualname__ + param_module = type(param).__module__ + imports.add(f"from {param_module} import {param_class}") + lines.append(f"{param_var} = {param_class}()") + # Reconstruct each attribute + for item in param._items: # noqa: SLF001 + attr_name = item._name # noqa: SLF001 + value = getattr(param, attr_name, None) + if value is not None: + lines.append(f"{param_var}.{attr_name} = {value!r}") + + # Build the function call + func_call = f"{mod_alias}.{self.func_name}" + if self.pattern in ("1_to_1", "1_to_0"): + if param_var: + lines.append(f"{output_var} = {func_call}({input_var}, {param_var})") + else: + lines.append(f"{output_var} = {func_call}({input_var})") + elif self.pattern == "n_to_1": + if param_var: + lines.append(f"{output_var} = {func_call}([{input_var}], {param_var})") + else: + lines.append(f"{output_var} = {func_call}([{input_var}])") + elif self.pattern == "2_to_1": + second = obj2_var or "... # TODO: provide second operand" + if param_var: + lines.append( + f"{output_var} = {func_call}({input_var}, {second}, {param_var})" + ) + else: + lines.append(f"{output_var} = {func_call}({input_var}, {second})") + elif self.pattern == "1_to_n": + lines.append(f"{output_var} = {func_call}({input_var})") + else: + lines.append(f"# Unknown pattern {self.pattern!r}") + return lines, None + + return lines, output_var + + # ------------------------------------------------------------------ + # Workspace-state delegation + # ------------------------------------------------------------------ + + def is_current_state_compatible( + self, mainwindow: DLMainWindow, restore_selection: bool + ) -> bool: + """Check if the current workspace state is compatible with the saved state.""" + return self.state.is_current_state_compatible(mainwindow, restore_selection) + + def restore(self, mainwindow: DLMainWindow) -> None: + """Restore the associated workspace state.""" + self.state.restore(mainwindow) + + # ------------------------------------------------------------------ + # Replay + # ------------------------------------------------------------------ + + def _resolve_target(self, mainwindow: DLMainWindow) -> Any: + """Resolve the target object (UI kind) from the mainwindow.""" + attr = self.target or "mainwindow" + if attr == "mainwindow": + return mainwindow + return getattr(mainwindow, attr) + + def _resolve_panel(self, mainwindow: DLMainWindow): + """Resolve the data panel for a compute action.""" + if self.panel_str == "signal": + return mainwindow.signalpanel + if self.panel_str == "image": + return mainwindow.imagepanel + raise ValueError( + f"Unknown panel_str {self.panel_str!r} for compute history action" + ) + + def _resolve_callable(self) -> Callable | None: + """Best-effort lookup of the underlying callable, for description only.""" + if self.kind == self.KIND_COMPUTE and self.func_name: + for module in (sigima.proc.signal, sigima.proc.image): + func = getattr(module, self.func_name, None) + if callable(func): + return func + return None + + def _resolve_obj_by_uuid(self, mainwindow: DLMainWindow, uuid: str) -> Any | None: + """Look up an object by UUID across both data panels.""" + for panel in (mainwindow.signalpanel, mainwindow.imagepanel): + try: + return panel.objmodel[uuid] + except KeyError: + continue + return None + + def replay( + self, + mainwindow: DLMainWindow, + restore_selection: bool, + edit: bool, + uuid_remap: dict[str, dict[str, str]] | None = None, + ) -> None: + """Replay the action. + + Args: + mainwindow: DataLab's main window + restore_selection: True to restore the workspace selection before replaying + a UI-kind action. Ignored for compute-kind actions: their semantics + depends on which objects are selected (e.g. ``n_to_1`` aggregators + such as ``average`` require their captured multi-object selection), + so the captured selection is always restored before running the + computation. + edit: if True, always open the dialog boxes to edit parameters; if False, + use the parameters captured when the action was recorded + uuid_remap: optional per-panel mapping ``{panel_str: {old_uuid: new_uuid}}`` + used during full-session replay to translate captured UUIDs to the + freshly-created ones. Defaults to an empty (identity) mapping. + """ + if uuid_remap is None: + uuid_remap = {} + # Suppress history capture during replay to avoid recording + # synthetic entries when the processor re-executes features. + # The context manager is reentrant, so nesting with + # HistoryPanel.replay_restore_actions() is safe. + hpanel = getattr(mainwindow, "historypanel", None) + if hpanel is not None: + ctx = hpanel.replaying() + else: + from contextlib import nullcontext + + ctx = nullcontext() + with ctx: + self._replay_inner(mainwindow, restore_selection, edit, uuid_remap) + + def _replay_inner( + self, + mainwindow: DLMainWindow, + restore_selection: bool, + edit: bool, + uuid_remap: dict[str, dict[str, str]], + ) -> None: + """Inner replay logic, always called under the replaying guard.""" + if self.kind == self.KIND_COMPUTE: + # Compute actions are selection-driven: restore the captured + # selection (translated through ``uuid_remap`` for session + # replays) whenever it is still resolvable so chained replays + # (especially ``n_to_1`` / ``2_to_1`` / ``1_to_n`` patterns) + # operate on the original input objects rather than on whatever + # the previous action left selected. When the captured UUIDs no + # longer exist (e.g. heuristic remap missed an object), fall + # back to the current selection -- replay may still fail + # downstream, but with the native processor error rather than + # an opaque ``WorkspaceState`` incompatibility. + translated = self._translate_state(uuid_remap) + if translated.is_current_state_compatible(mainwindow, False): + translated.restore(mainwindow) + self._replay_compute(mainwindow, edit, uuid_remap) + else: + if restore_selection: + self.state.restore(mainwindow) + self._replay_ui(mainwindow, edit) + + def _translate_state(self, uuid_remap: dict[str, dict[str, str]]) -> WorkspaceState: + """Return a copy of ``self.state`` whose captured UUIDs have been + translated through ``uuid_remap`` (identity when no mapping).""" + if not uuid_remap: + return self.state + translated = WorkspaceState() + for panel_str, uuids in self.state.selection.items(): + panel_map = uuid_remap.get(panel_str, {}) + translated.selection[panel_str] = [panel_map.get(u, u) for u in uuids] + translated.states = dict(self.state.states) + translated.titles = dict(self.state.titles) + for panel_str, metadata in self.state.object_metadata.items(): + panel_map = uuid_remap.get(panel_str, {}) + translated.object_metadata[panel_str] = { + panel_map.get(uuid, uuid): dict(signature) + for uuid, signature in metadata.items() + } + return translated + + def _replay_compute( + self, + mainwindow: DLMainWindow, + edit: bool, + uuid_remap: dict[str, dict[str, str]] | None = None, + ) -> None: + """Replay a compute-kind action via ``processor.run_feature``.""" + if self.pattern == "multiple_1_to_1": + raise NotImplementedError( + _("Replaying compound 'multiple_1_to_1' actions is not supported yet.") + ) + panel = self._resolve_panel(mainwindow) + processor = panel.processor + feature = processor.get_feature(self.func_name) + run_kwargs: dict[str, Any] = {self.FUNC_EDIT_MODE: edit} + + param = self.kwargs.get("param") + if self.pattern in {"1_to_1", "1_to_0", "n_to_1"}: + if param is not None: + run_kwargs["param"] = param + if self.pattern == "n_to_1" and "pairwise" in self.kwargs: + run_kwargs["pairwise"] = self.kwargs["pairwise"] + elif self.pattern == "2_to_1": + uuids = self.kwargs.get("obj2_uuids") or [] + if isinstance(uuids, str): + uuids = [uuids] + # Translate captured UUIDs through ``uuid_remap`` (session replay). + # ``uuid_remap`` keys are ``panel.PANEL_STR_ID`` (matches + # ``WorkspaceState.selection`` keys and + # ``HistoryAction.panel_str``). + panel_map = (uuid_remap or {}).get(panel.PANEL_STR_ID, {}) + uuids = [panel_map.get(u, u) for u in uuids] + objs2 = [ + obj + for obj in (self._resolve_obj_by_uuid(mainwindow, u) for u in uuids) + if obj is not None + ] + if not objs2: + raise ValueError( + _("Cannot replay 2-to-1 action: source object(s) missing.") + ) + run_kwargs["obj2"] = objs2[0] if len(objs2) == 1 else objs2 + if param is not None: + run_kwargs["param"] = param + if "pairwise" in self.kwargs: + run_kwargs["pairwise"] = self.kwargs["pairwise"] + elif self.pattern == "1_to_n": + params = self.kwargs.get("params") or [] + run_kwargs["params"] = params + else: + raise ValueError(f"Unknown compute pattern: {self.pattern!r}") + processor.run_feature(feature, **run_kwargs) + + def _replay_ui(self, mainwindow: DLMainWindow, edit: bool) -> None: + """Replay a UI-kind action by calling ``target.method_name(**kwargs)``.""" + hpanel = mainwindow.historypanel + if ( + hpanel is not None + and hpanel.is_output_suppressed() + and self.method_name in self.UI_CREATION_METHODS + ): + return # Skip creation UI during non-persistent replay + target = self._resolve_target(mainwindow) + # Safety guard for destructive UI actions: if the action would delete + # objects but the captured selection no longer resolves to existing + # UUIDs in the target panel, skip the call rather than delete whatever + # is currently selected (which would silently destroy unrelated data). + DESTRUCTIVE_METHODS = {"remove_object", "remove_group", "delete_all_objects"} + if self.method_name in DESTRUCTIVE_METHODS: + if target is None: + _logger.warning( + "Skipping destructive replay '%s': target '%s' not found", + self.method_name, + self.target, + ) + return + panel_str = getattr(target, "PANEL_STR_ID", None) + if panel_str and self.state and self.state.selection.get(panel_str): + existing_uuids = { + get_uuid(o) + for o in getattr(target, "objmodel", []) + if o is not None + } + captured = set(self.state.selection.get(panel_str, [])) + if not (captured & existing_uuids): + _logger.warning( + "Skipping destructive replay '%s': none of the captured " + "UUIDs %s exist in panel '%s' anymore", + self.method_name, + list(captured), + panel_str, + ) + return + method = getattr(target, self.method_name) + call_kwargs = dict(self.kwargs) + # Inject edit mode if the method supports it + try: + sig = inspect.signature(method) + if self.FUNC_EDIT_MODE in sig.parameters: + call_kwargs[self.FUNC_EDIT_MODE] = edit + except (TypeError, ValueError): + pass + method(**call_kwargs) + + # ------------------------------------------------------------------ + # Serialisation -- no Callable is ever pickled + # ------------------------------------------------------------------ + + def serialize(self, writer: NativeH5Writer) -> None: + """Serialize this action.""" + with writer.group("schema_version"): + writer.write(self.schema_version) + with writer.group("kind"): + writer.write(self.kind) + with writer.group("title"): + writer.write(self.__title) + if self.panel_str is not None: + with writer.group("panel_str"): + writer.write(self.panel_str) + if self.func_name is not None: + with writer.group("func_name"): + writer.write(self.func_name) + if self.pattern is not None: + with writer.group("pattern"): + writer.write(self.pattern) + if self.target is not None: + with writer.group("target"): + writer.write(self.target) + if self.method_name is not None: + with writer.group("method_name"): + writer.write(self.method_name) + encoded = _encode_kwargs(self.kwargs) + if encoded: + with writer.group("kwargs"): + writer.write_dict(encoded) + # ``saved_kwargs``: persisted Edit mode snapshot so the Restore button + # keeps working after save/reload. Group omitted when there are no + # pending edits. + if self._saved_kwargs is not None: + encoded_saved = _encode_kwargs(self._saved_kwargs) + # Write the group unconditionally (even when empty) so that the + # round-trip preserves the distinction between None (no pending + # edits) and {} (degenerate empty snapshot, keeps has_pending_edits). + with writer.group("saved_kwargs"): + writer.write_dict(encoded_saved) + # Only emit ``output_uuids`` when non-empty (empty lists skipped to + # avoid h5py edge cases with empty arrays). + if self.output_uuids: + with writer.group("output_uuids"): + writer.write(list(self.output_uuids)) + # ``plugin_origin``: stored as a JSON string so the HDF5 schema stays + # trivially round-trippable. Skipped when None. + if self.plugin_origin is not None: + with writer.group("plugin_origin"): + writer.write(json.dumps(self.plugin_origin)) + with writer.group("state"): + self.state.serialize(writer) + with writer.group("dtstr"): + writer.write(self.dtstr) + + def deserialize(self, reader: NativeH5Reader) -> None: + """Deserialize this action.""" + self.schema_version = reader.read( + "schema_version", default=HISTORY_SCHEMA_VERSION + ) + with reader.group("kind"): + self.kind = reader.read_any() + with reader.group("title"): + self.__title = reader.read_any() + # Optional descriptors are written conditionally; check existence in + # the underlying HDF5 group before reading to avoid leaking ``__seq`` + # frames on the option stack via guidata's read_any fallback path. + current = reader.h5 + for option in reader.option: + current = current.require_group(option) + for attr in ("panel_str", "func_name", "pattern", "target", "method_name"): + if attr in current.attrs or attr in current: + with reader.group(attr): + setattr(self, attr, reader.read_any()) + else: + setattr(self, attr, None) + if "kwargs" in current.attrs or "kwargs" in current: + with reader.group("kwargs"): + raw = reader.read_dict() + self.kwargs = _decode_kwargs(raw) + else: + self.kwargs = {} + # ``saved_kwargs`` group is present only when an Edit mode snapshot + # exists; otherwise leave it as ``None``. + if "saved_kwargs" in current.attrs or "saved_kwargs" in current: + with reader.group("saved_kwargs"): + raw_saved = reader.read_dict() + self._saved_kwargs = _decode_kwargs(raw_saved) + else: + self._saved_kwargs = None + # ``output_uuids`` is present only when the action produced outputs; + # otherwise leave it empty and consumers fall back to the heuristic + # matcher. + if "output_uuids" in current.attrs or "output_uuids" in current: + with reader.group("output_uuids"): + raw_outputs = reader.read_any() + if raw_outputs is None: + self.output_uuids = [] + else: + self.output_uuids = [str(u) for u in raw_outputs] + else: + self.output_uuids = [] + # ``plugin_origin`` is present only for plugin-originated compute + # actions; otherwise leave it as ``None`` (a replay of a missing plugin + # function then surfaces a generic ``FeatureNotFoundError``). + if "plugin_origin" in current.attrs or "plugin_origin" in current: + with reader.group("plugin_origin"): + raw_origin = reader.read_any() + if raw_origin in (None, ""): + self.plugin_origin = None + else: + try: + self.plugin_origin = json.loads(raw_origin) + except (TypeError, ValueError): + _logger.warning( + "Failed to decode plugin_origin for action %s; " + "falling back to None.", + self.uuid, + ) + self.plugin_origin = None + else: + self.plugin_origin = None + with reader.group("state"): + self.state.deserialize(reader) + with reader.group("dtstr"): + self.dtstr = reader.read_any() diff --git a/datalab/history/core.py b/datalab/history/core.py new file mode 100644 index 000000000..9ac7b3fcb --- /dev/null +++ b/datalab/history/core.py @@ -0,0 +1,235 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +"""History core utilities: schema constants, JSON codec, ``@add_to_history`` decorator.""" + +from __future__ import annotations + +import functools +import importlib +import json +import logging +import warnings +from copy import deepcopy +from typing import TYPE_CHECKING, Any + +import numpy as np +from guidata.dataset.conv import dataset_to_json, json_to_dataset +from guidata.dataset.datatypes import DataSet +from qtpy import QtCore as QC +from sigima.objects.base import BaseROI + +from datalab.config import _ + +if TYPE_CHECKING: + from datalab.gui.panel.base import BaseDataPanel + from datalab.gui.panel.history import HistoryPanel + from datalab.gui.processor.base import BaseProcessor + +_logger = logging.getLogger(__name__) +_TRUSTED_ROI_MODULE_PREFIX = "sigima." + +# Schema versions for persisted history sessions/actions. Both start at 1. +# Bump the relevant constant (and add the corresponding optional field +# handling in serialize/deserialize) when the on-disk layout evolves. +HISTORY_SCHEMA_VERSION = 1 +HISTORY_ACTION_SCHEMA_VERSION = 1 +# Keys used in the kwargs dict to mark DataSet payloads, so that the +# serialization layer can round-trip them as JSON strings instead of pickling +# arbitrary Python objects. +_DATASET_MARKER = "__dataset_json__" +_DATASET_LIST_MARKER = "__dataset_list_json__" +_ROI_MARKER = "__roi_json__" + + +def get_datetime_str() -> str: + """Return current date and time as a string""" + return QC.QDateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss") + + +def _numpy_to_json_safe(obj: Any) -> Any: + """Recursively convert numpy arrays to lists for JSON serialization.""" + if isinstance(obj, np.ndarray): + return obj.tolist() + if isinstance(obj, dict): + return {k: _numpy_to_json_safe(v) for k, v in obj.items()} + if isinstance(obj, list): + return [_numpy_to_json_safe(i) for i in obj] + return obj + + +def _encode_roi(roi: Any) -> str: + """Encode a sigima ROI object to a JSON string via ``to_dict()``.""" + if not isinstance(roi, BaseROI): + raise TypeError(f"Expected BaseROI instance, got {type(roi)!r}") + roi_dict = _numpy_to_json_safe(roi.to_dict()) + # Store the concrete class so we can reconstruct on decode. + payload = { + "module": type(roi).__module__, + "class": type(roi).__qualname__, + "data": roi_dict, + } + return json.dumps(payload) + + +def _decode_roi(encoded: str) -> Any: + """Decode a JSON string back to a sigima ROI object. + + Only classes from trusted ``sigima.`` modules that are actual + :class:`sigima.objects.base.BaseROI` subclasses are allowed. + + Raises: + ValueError: If the module is not a trusted sigima module or the + resolved class is not a BaseROI subclass. + """ + payload = json.loads(encoded) + module_name = payload["module"] + class_name = payload["class"] + + if not module_name.startswith(_TRUSTED_ROI_MODULE_PREFIX): + raise ValueError( + f"Untrusted ROI module {module_name!r}: " + f"only modules under {_TRUSTED_ROI_MODULE_PREFIX!r} are allowed" + ) + + mod = importlib.import_module(module_name) + cls = getattr(mod, class_name) + + if not (isinstance(cls, type) and issubclass(cls, BaseROI)): + raise ValueError(f"{module_name}.{class_name} is not a BaseROI subclass") + + return cls.from_dict(payload["data"]) + + +def _encode_kwargs(kwargs: dict[str, Any]) -> dict[str, Any]: + """Encode kwargs for HDF5 storage: replace ``DataSet``, ``list[DataSet]``, + and sigima ROI values with marker dicts holding their JSON representation. + + All other values must already be HDF5-friendly primitives (str, int, float, + bool, list/tuple of the same). + + Args: + kwargs: Raw kwargs dict (may contain ``DataSet`` or ROI instances). + + Returns: + A new dict with special values wrapped in marker dicts. + """ + encoded: dict[str, Any] = {} + for key, value in kwargs.items(): + if value is None: + continue + if isinstance(value, DataSet): + encoded[key] = {_DATASET_MARKER: dataset_to_json(value)} + elif isinstance(value, BaseROI): + encoded[key] = {_ROI_MARKER: _encode_roi(value)} + elif ( + isinstance(value, list) + and value + and all(isinstance(item, DataSet) for item in value) + ): + encoded[key] = { + _DATASET_LIST_MARKER: [dataset_to_json(item) for item in value] + } + else: + encoded[key] = value + return encoded + + +def _decode_kwargs(kwargs: dict[str, Any]) -> dict[str, Any]: + """Inverse of :func:`_encode_kwargs`.""" + decoded: dict[str, Any] = {} + for key, value in kwargs.items(): + if isinstance(value, dict) and _DATASET_MARKER in value: + try: + decoded[key] = json_to_dataset(value[_DATASET_MARKER]) + except (TypeError, ValueError, KeyError): + warnings.warn( + _("Failed to deserialize history DataSet kwarg %r.") % key + ) + decoded[key] = None + elif isinstance(value, dict) and _ROI_MARKER in value: + try: + decoded[key] = _decode_roi(value[_ROI_MARKER]) + except Exception as exc: + raise ValueError( + f"Failed to deserialize history ROI kwarg {key!r}: {exc}" + ) from exc + elif isinstance(value, dict) and _DATASET_LIST_MARKER in value: + try: + decoded[key] = [ + json_to_dataset(item) for item in value[_DATASET_LIST_MARKER] + ] + except (TypeError, ValueError, KeyError): + warnings.warn( + _("Failed to deserialize history DataSet-list kwarg %r.") % key + ) + decoded[key] = [] + else: + decoded[key] = value + return decoded + + +def _copy_history_value(value: Any) -> Any: + """Return an independent copy of a history-serializable value.""" + if callable(value): + raise TypeError("History duplication does not support callable kwargs") + if isinstance(value, DataSet): + return json_to_dataset(dataset_to_json(value)) + if isinstance(value, BaseROI): + return _decode_roi(_encode_roi(value)) + if isinstance(value, dict): + return {key: _copy_history_value(item) for key, item in value.items()} + if isinstance(value, list): + return [_copy_history_value(item) for item in value] + if isinstance(value, tuple): + return tuple(_copy_history_value(item) for item in value) + return deepcopy(value) + + +def add_to_history(kwargs_names: list[str] | None = None, title: str | None = None): + """Method decorator to add the method call to the history panel as a UI entry. + + Args: + kwargs_names: List of keyword arguments to add to the history action. + Defaults to None. + title: Title of the history action. Defaults to None. + """ + if kwargs_names is None: + kwargs_names = [] + + def add_to_history_decorator(func): + """Decorator function""" + + @functools.wraps(func) + def method_wrapper(*args, **kwargs): + """Decorator wrapper function""" + self: BaseDataPanel | BaseProcessor = args[0] + history: HistoryPanel = self.mainwindow.historypanel + histkwargs = {k: kwargs[k] for k in kwargs_names if k in kwargs} + target = _resolve_self_target(self) + if target is not None: + history.add_ui_entry( + kwargs.get("title", title) or func.__name__, + target=target, + method_name=func.__name__, + save_state=kwargs.get("save_state", True), + **histkwargs, + ) + return func(*args, **kwargs) + + return method_wrapper + + return add_to_history_decorator + + +def _resolve_self_target(self_obj: Any) -> str | None: + """Resolve a 'self' instance to a string target understood by replay. + + Used by the legacy ``@add_to_history`` decorator. Returns None when no + safe routing is possible (in which case the entry is skipped). + """ + panel_str = getattr(self_obj, "PANEL_STR_ID", None) + if panel_str == "signal": + return "signalpanel" + if panel_str == "image": + return "imagepanel" + return None diff --git a/datalab/history/session.py b/datalab/history/session.py new file mode 100644 index 000000000..24a78a2f7 --- /dev/null +++ b/datalab/history/session.py @@ -0,0 +1,392 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +"""HistorySession: ordered list of HistoryAction with replay logic.""" + +from __future__ import annotations + +from typing import TYPE_CHECKING + +from datalab.config import _ +from datalab.history.action import HistoryAction +from datalab.history.core import HISTORY_SCHEMA_VERSION, get_datetime_str + +if TYPE_CHECKING: + from datalab.gui.main import DLMainWindow + from datalab.h5.native import NativeH5Reader, NativeH5Writer + + +class HistorySession: + """Object representing a history session, i.e. a list of actions. + + A history session is a list of actions that can be replayed in the same order + as they were added to the history session. The history session can be saved to + a file and loaded from a file. + + Args: + title: Title of the history session + number: Number of the history session + """ + + def __init__(self, title: str = "", number: int = 0) -> None: + """Create a new history session""" + prefix = _("Session") + self.title = title if title else f"{prefix} {number:03d}" + self.number = number + self.dtstr: str = get_datetime_str() + self.actions: list[HistoryAction] = [] + self.schema_version: int = HISTORY_SCHEMA_VERSION + + def add_action(self, action: HistoryAction) -> None: + """Add an action to the history session + + Args: + action: Action to add + """ + self.actions.append(action) + + def copy( + self, title: str | None = None, action_title_suffix: str | None = None + ) -> HistorySession: + """Return an independent copy of this history session.""" + session = HistorySession(title=title or self.title, number=self.number) + session.actions = [ + action.copy(title_suffix=action_title_suffix) for action in self.actions + ] + return session + + def copy_with_uuid_remap( + self, title: str, uuid_remap: dict[str, dict[str, str]] + ) -> HistorySession: + """Return a copy of this session with all UUIDs rewritten via ``uuid_remap``. + + Used by the Duplicate operation to build an independent session whose + captured object references point to the cloned data objects. + + Args: + title: Title for the new session. + uuid_remap: Per-panel mapping ``{panel_str: {old_uuid: new_uuid}}``. + + Returns: + A new :class:`HistorySession` with all captured UUIDs remapped. + """ + session = HistorySession(title=title, number=self.number) + session.actions = [ + action.copy_with_uuid_remap(uuid_remap) for action in self.actions + ] + return session + + def is_current_state_compatible( + self, mainwindow: DLMainWindow, restore_selection: bool + ) -> bool: + """Check if the current workspace state is compatible with the saved state + + Args: + mainwindow: DataLab's main window + restore_selection: True to restore the selection before checking the state + + Returns: + bool: True if the current workspace state is compatible with the saved state + """ + if self.actions: + return self.actions[0].is_current_state_compatible( + mainwindow, restore_selection + ) + return True + + def restore(self, mainwindow: DLMainWindow) -> None: + """Restore the state of the workspace associated to the first action of session + + Args: + mainwindow: DataLab's main window + """ + if self.actions: + self.actions[0].restore(mainwindow) + + def replay( + self, mainwindow: DLMainWindow, restore_selection: bool, edit: bool + ) -> None: + """Replay the history session + + Args: + mainwindow: DataLab's main window + restore_selection: True to restore the workspace selection before replaying + edit: if True, always open the dialog boxes to edit parameters, if False, + use the parameters passed when creating the action + """ + # Per-panel ``{old_uuid: new_uuid}`` mapping, populated as UI actions + # create new objects. Used by compute actions to translate their + # captured selection (and ``obj2_uuids``) into the freshly-created + # UUIDs of the current replay, so chained ``n_to_1`` / ``2_to_1`` / + # ``1_to_n`` actions operate on the correct inputs. Keys are + # ``panel.PANEL_STR_ID`` (matches ``WorkspaceState.selection`` keys). + panels = (mainwindow.signalpanel, mainwindow.imagepanel) + uuid_remap: dict[str, dict[str, str]] = {p.PANEL_STR_ID: {} for p in panels} + # FIFO of newly-created UUIDs not yet claimed by a remap entry -- + # required because most creation UI actions (e.g. ``new_signal``) + # are recorded with ``save_state=False`` (empty captured selection), + # so we cannot pair captured-vs-new UUIDs by position at UI time. + # Subsequent compute actions claim from this queue on demand. + unclaimed: dict[str, list[str]] = {p.PANEL_STR_ID: [] for p in panels} + + def _claim_unmapped( + pstr: str, + old_uuids: list[str], + action: HistoryAction, + ) -> None: + """Claim unclaimed new UUIDs for *old_uuids* not yet in uuid_remap. + + Uses title matching (scanning the full unclaimed queue) followed by + panel-order index alignment to deterministically pair old UUIDs + to the correct new UUIDs, regardless of creation order. + """ + # Collect unmapped UUIDs (deduplicated, preserving first-seen order). + all_unmapped: list[str] = [] + seen: set[str] = set() + for u in old_uuids: + if u not in seen and u not in uuid_remap.get(pstr, {}): + all_unmapped.append(u) + seen.add(u) + if not all_unmapped: + return + # Re-sort by recorded panel position when available. + panel_order = list(action.state.object_metadata.get(pstr, {}).keys()) + if panel_order and all(u in panel_order for u in all_unmapped): + all_unmapped.sort(key=panel_order.index) + queue = unclaimed.get(pstr) or [] + if not queue: + return + # Build old UUID → title from captured state and object_metadata. + sel_uuids = action.state.selection.get(pstr, []) + sel_titles = action.state.titles.get(pstr, []) + old_titles: dict[str, str] = {} + for _u, _t in zip(sel_uuids, sel_titles): + if _u in seen: + old_titles[_u] = _t + obj_meta = action.state.object_metadata.get(pstr, {}) + for _u in all_unmapped: + if _u not in old_titles and _u in obj_meta: + meta = obj_meta[_u] + if isinstance(meta, dict) and "title" in meta: + old_titles[_u] = meta["title"] + # Build new UUID → title from the live panel (full queue). + new_titles: dict[str, str] = {} + panel_obj = None + for p in panels: + if p.PANEL_STR_ID == pstr: + panel_obj = p + break + if panel_obj is not None: + for nu in queue: + try: + new_titles[nu] = panel_obj.objmodel[nu].title + except KeyError: + pass + # Phase 1: title matching against the FULL queue. + assigned_old: set[str] = set() + assigned_new: set[str] = set() + for ou in all_unmapped: + if ou not in old_titles: + continue + title = old_titles[ou] + candidates = [ + nu + for nu in queue + if nu not in assigned_new and new_titles.get(nu) == title + ] + if len(candidates) == 1: + uuid_remap.setdefault(pstr, {})[ou] = candidates[0] + assigned_old.add(ou) + assigned_new.add(candidates[0]) + # Phase 2: positional fallback using panel-order alignment. + # Two modes depending on whether the remaining queue covers all + # free recorded panel slots: + # + # A) Absolute index alignment (len(rem_queue) == len(free_indices)): + # Each free panel_order index maps 1-to-1 to a queue slot. + # This ensures e.g. the second-created object maps to the + # second queue entry even when only a subset of old UUIDs + # needs claiming. + # + # B) Relative order fallback (queue is a strict subset): + # The queue only contains later compute-created objects while + # earlier full-panel entries are absent. Absolute alignment + # would leave non-first old UUIDs unmapped. Instead, zip + # rem_old (already sorted by panel order) with rem_queue + # sequentially. + rem_old = [u for u in all_unmapped if u not in assigned_old] + if rem_old and panel_order: + rem_queue = [u for u in queue if u not in assigned_new] + # Find which panel_order indices are "free" (unclaimed). + free_indices: list[int] = [] + for idx, po_uuid in enumerate(panel_order): + if po_uuid not in uuid_remap.get(pstr, {}): + if po_uuid not in assigned_old: + free_indices.append(idx) + if len(rem_queue) == len(free_indices): + # Mode A: absolute index alignment. + idx_to_new: dict[int, str] = {} + for qi, fi in enumerate(free_indices): + if qi < len(rem_queue): + idx_to_new[fi] = rem_queue[qi] + for ou in rem_old: + if ou in panel_order: + idx = panel_order.index(ou) + if idx in idx_to_new: + nu = idx_to_new[idx] + uuid_remap.setdefault(pstr, {})[ou] = nu + assigned_new.add(nu) + else: + # Mode B: relative order fallback. + for ou, nu in zip(rem_old, rem_queue): + uuid_remap.setdefault(pstr, {})[ou] = nu + assigned_new.add(nu) + elif rem_old: + # No panel_order available: sequential fallback. + rem_queue = [u for u in queue if u not in assigned_new] + for ou, nu in zip(rem_old, rem_queue): + uuid_remap.setdefault(pstr, {})[ou] = nu + assigned_new.add(nu) + # Remove all assigned new UUIDs from the unclaimed queue. + if assigned_new: + unclaimed[pstr] = [u for u in queue if u not in assigned_new] + + for action in self.actions[:]: + before = {p.PANEL_STR_ID: set(p.objmodel.get_object_ids()) for p in panels} + if action.kind == HistoryAction.KIND_COMPUTE: + # Lazy-resolve any captured UUIDs missing from the remap by + # claiming from ``unclaimed`` (deterministic: title + panel-order). + pstr = action.panel_str or "" + captured = action.state.selection.get(pstr, []) + if action.pattern == "2_to_1": + # For 2_to_1: collect ALL unmapped old UUIDs from both + # captured selection and obj2_uuids in one batch so + # operand order is preserved by the helper. + obj2 = action.kwargs.get("obj2_uuids") or [] + if isinstance(obj2, str): + obj2 = [obj2] + _claim_unmapped(pstr, list(obj2) + list(captured), action) + else: + # For all other compute patterns (1_to_1, n_to_1, etc.): + # use the same deterministic helper. + _claim_unmapped(pstr, list(captured), action) + action.replay( + mainwindow, + restore_selection=restore_selection, + edit=edit, + uuid_remap=uuid_remap, + ) + # Post-action bookkeeping: track new/removed UUIDs for *every* + # action kind so that later actions consuming compute-created + # outputs can resolve them through ``uuid_remap`` / ``unclaimed``. + for panel in panels: + pstr = panel.PANEL_STR_ID + current_ids = set(panel.objmodel.get_object_ids()) + new_uuids = [ + u for u in panel.objmodel.get_object_ids() if u not in before[pstr] + ] + # Drop vanished UUIDs from the unclaimed queue and the + # reverse remap entries (e.g. ``Remove selected objects``): + # this keeps the FIFO claim in sync with the live panel + # contents during chained creation/removal replays. + removed_uuids = before[pstr] - current_ids + if removed_uuids: + unclaimed[pstr] = [ + u for u in unclaimed.get(pstr, []) if u not in removed_uuids + ] + panel_map = uuid_remap.get(pstr, {}) + for old_key in [ + k for k, v in panel_map.items() if v in removed_uuids + ]: + panel_map.pop(old_key, None) + if not new_uuids: + continue + if action.kind == HistoryAction.KIND_UI: + captured = action.state.selection.get(pstr, []) + if captured: + # Captured post-action selection available: pair + # captured UUIDs with new UUIDs by position. + for old_uuid, new_uuid in zip(captured, new_uuids): + uuid_remap.setdefault(pstr, {})[old_uuid] = new_uuid + # Any extra newly-created UUIDs go to the queue. + unclaimed.setdefault(pstr, []).extend( + new_uuids[len(captured) :] + ) + else: + # No captured selection (typical of ``new_signal``): + # queue all new UUIDs for lazy claiming. + unclaimed.setdefault(pstr, []).extend(new_uuids) + else: + # Compute actions: queue all newly-created UUIDs so + # later actions can lazily claim them. Do NOT map + # captured input UUIDs to output UUIDs — compute + # inputs and outputs are semantically different. + unclaimed.setdefault(pstr, []).extend(new_uuids) + + # Visually close the replay: select the output of the last compute + # action so the user sees the final result highlighted in the panel. + # Without this, the very last action's output is never selected + # (intermediate actions are implicitly "closed" by the next + # iteration's input restore). + if self.actions: + last = self.actions[-1] + if last.kind == HistoryAction.KIND_COMPUTE: + hpanel = getattr(mainwindow, "historypanel", None) + if hpanel is not None: + output_uuid = hpanel._action_output_uuid(last) + if output_uuid: + panel_str = last.panel_str or "" + panel_map = uuid_remap.get(panel_str, {}) + mapped_uuid = panel_map.get(output_uuid, output_uuid) + for panel in panels: + if panel.PANEL_STR_ID == panel_str: + try: + panel.objview.select_objects([mapped_uuid]) + except KeyError: + pass + break + + def serialize(self, writer: NativeH5Writer) -> None: + """Serialize this history session + + Args: + writer: Writer + """ + with writer.group("schema_version"): + writer.write(self.schema_version) + with writer.group("title"): + writer.write(self.title) + with writer.group("number"): + writer.write(self.number) + with writer.group("dtstr"): + writer.write(self.dtstr) + writer.write_object_list(self.actions, "actions") + + def deserialize(self, reader: NativeH5Reader) -> None: + """Deserialize this history session + + Args: + reader: Reader + """ + self.schema_version = reader.read( + "schema_version", default=HISTORY_SCHEMA_VERSION + ) + with reader.group("title"): + self.title = reader.read_any() + with reader.group("number"): + self.number = reader.read_any() + with reader.group("dtstr"): + self.dtstr = reader.read_any() + self.actions = reader.read_object_list("actions", HistoryAction) + + def remove_action(self, action: HistoryAction) -> None: + """Remove an action from the history session + + This implies removing all subsequent actions. If action is not found, this + fails silently. + + Args: + action: Action to remove + """ + if action in self.actions: + index = self.actions.index(action) + self.actions = self.actions[:index] diff --git a/datalab/history/workspace_state.py b/datalab/history/workspace_state.py new file mode 100644 index 000000000..a665d6a8c --- /dev/null +++ b/datalab/history/workspace_state.py @@ -0,0 +1,249 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +"""Workspace state snapshot captured at history action time.""" + +from __future__ import annotations + +from copy import deepcopy +from typing import TYPE_CHECKING, Any + +from datalab.objectmodel import get_uuid + +if TYPE_CHECKING: + from datalab.gui.main import DLMainWindow + from datalab.h5.native import NativeH5Reader, NativeH5Writer + + +class WorkspaceState: + """Object representing the workspace state at a given time. + + The workspace state stores the per-panel selection of objects by **UUID** + (robust against reordering, renaming or interleaved insertions). For + informative display, it also retains the data shape and title of each + selected object at the time of capture. + """ + + def __init__(self) -> None: + """Create a new workspace state""" + # The selection is stored as a dictionary where the key is the panel name + # and the value is the list of UUIDs of selected objects. + self.selection: dict[str, list[str]] = {} + # The states are stored as a dictionary where the key is the panel name + # and the value is the list of states (str) of the objects in the panel. The + # state is a string containing the object data shape (kept for informative + # display only -- not used for selection matching anymore). + self.states: dict[str, list[str]] = {} + # The titles are stored as a dictionary where the key is the panel name and the + # value is the list of titles of the objects in the panel. The title is only + # informative and is not used to determine if two objects have the same state. + self.titles: dict[str, list[str]] = {} + # Structured data signatures of selected objects, keyed by panel name and UUID. + # This is the current schema used for compatibility checks. Missing metadata + # means a pre-Gate-2 history and falls back to UUID-existence validation. + self.object_metadata: dict[str, dict[str, dict[str, Any]]] = {} + + def copy(self) -> WorkspaceState: + """Return an independent copy of this workspace state.""" + state = WorkspaceState() + state.selection = deepcopy(self.selection) + state.states = deepcopy(self.states) + state.titles = deepcopy(self.titles) + state.object_metadata = deepcopy(self.object_metadata) + return state + + def serialize(self, writer: NativeH5Writer) -> None: + """Serialize this workspace state + + Args: + writer: Writer + """ + with writer.group("selection"): + writer.write_dict(self.selection) + with writer.group("states"): + writer.write_dict(self.states) + with writer.group("titles"): + writer.write_dict(self.titles) + with writer.group("object_metadata"): + writer.write_dict(self.object_metadata) + + def deserialize(self, reader: NativeH5Reader) -> None: + """Deserialize this workspace state + + Args: + reader: Reader + """ + with reader.group("selection"): + self.selection = reader.read_dict() + with reader.group("states"): + self.states = reader.read_dict() + with reader.group("titles"): + self.titles = reader.read_dict() + current = reader.h5 + for option in reader.option: + current = current[option] + if "object_metadata" in current.attrs or "object_metadata" in current: + with reader.group("object_metadata"): + self.object_metadata = reader.read_dict() + else: + self.object_metadata = {} + # Normalize legacy translated keys to stable panel identifiers. + self.selection = self._normalize_panel_keys(self.selection) + self.states = self._normalize_panel_keys(self.states) + self.titles = self._normalize_panel_keys(self.titles) + self.object_metadata = self._normalize_panel_keys(self.object_metadata) + + def get_current_selection(self, mainwindow: DLMainWindow) -> dict[str, list[str]]: + """Get the current selection in the workspace, keyed by panel name and + valued by the list of selected object UUIDs. + + Args: + mainwindow: DataLab's main window + + Returns: + Current selection in the workspace, by panel name → list of UUIDs. + """ + selection: dict[str, list[str]] = {} + for panel in (mainwindow.signalpanel, mainwindow.imagepanel): + selection[panel.PANEL_STR_ID] = [ + get_uuid(obj) + for obj in panel.objview.get_sel_objects(include_groups=True) + ] + return selection + + @staticmethod + def get_object_metadata(obj: Any) -> dict[str, Any]: + """Return a stable data signature for an object.""" + data = getattr(obj, "data", None) + shape = getattr(data, "shape", None) + if shape is None: + return {} + shape = [int(size) for size in shape] + ndim = getattr(data, "ndim", len(shape)) + return {"shape": shape, "ndim": int(ndim)} + + @staticmethod + def _normalize_object_metadata(metadata: dict[str, Any]) -> dict[str, Any]: + """Normalize object metadata loaded from HDF5 for comparison.""" + shape = metadata.get("shape") + if shape is None: + return {} + shape = [int(size) for size in shape] + ndim = metadata.get("ndim", len(shape)) + return {"shape": shape, "ndim": int(ndim)} + + # Mapping from legacy translated panel keys to stable identifiers. + # Covers the English translations; other locales are handled by the + # catch-all ``"signal"``/``"image"`` substring heuristic below. + _LEGACY_PANEL_KEY_MAP: dict[str, str] = { + "Signal Panel": "signal", + "Image Panel": "image", + } + + @classmethod + def _normalize_panel_key(cls, key: str) -> str: + """Map a potentially translated panel key to its stable identifier.""" + if key in ("signal", "image"): + return key + mapped = cls._LEGACY_PANEL_KEY_MAP.get(key) + if mapped is not None: + return mapped + # Heuristic for non-English translations: look for the stable ID + # substring in the key (e.g. "Panneau signal" → "signal"). + lowered = key.lower() + for stable_id in ("signal", "image"): + if stable_id in lowered: + return stable_id + return key + + @classmethod + def _normalize_panel_keys(cls, d: dict) -> dict: + """Return *d* with all top-level keys normalized to stable panel IDs.""" + return {cls._normalize_panel_key(k): v for k, v in d.items()} + + def save(self, mainwindow: DLMainWindow) -> None: + """Save the current workspace state + + Args: + mainwindow: DataLab's main window + """ + self.selection = self.get_current_selection(mainwindow) + self.object_metadata = {} + for panel in (mainwindow.signalpanel, mainwindow.imagepanel): + sel_uuids = self.selection[panel.PANEL_STR_ID] + self.states[panel.PANEL_STR_ID] = [ + str(obj.data.shape) + for obj in panel.objmodel + if get_uuid(obj) in sel_uuids + ] + self.titles[panel.PANEL_STR_ID] = [ + obj.title for obj in panel.objmodel if get_uuid(obj) in sel_uuids + ] + # Store metadata for ALL panel objects (not just selected) so that + # the dict key order captures the full panel ordering. During + # session replay the key order lets us sort old UUIDs by their + # original panel position, which prevents non-commutative 2_to_1 + # operand swaps in the positional-fallback code path. + # ``is_current_state_compatible`` only checks *selected* UUIDs, so + # the extra entries are harmless for compatibility validation. + self.object_metadata[panel.PANEL_STR_ID] = { + get_uuid(obj): self.get_object_metadata(obj) for obj in panel.objmodel + } + + def is_current_state_compatible( # pylint: disable=unused-argument + self, mainwindow: DLMainWindow, restore_selection: bool + ) -> bool: + """Check if the current workspace state is compatible with the saved state. + + Compatibility means that **every** UUID recorded in the saved selection + still exists in the corresponding panel. When structured object metadata + is available (current schema), each selected object's data shape and + dimensions must also match the saved signature. Histories without this + metadata fall back to legacy UUID-existence validation. + + Args: + mainwindow: DataLab's main window + restore_selection: Unused (kept for API symmetry). With UUID-based + identity, the compatibility check no longer depends on the current + selection -- it only depends on object existence. + + Returns: + True if every saved UUID still exists in its panel and saved + metadata, when available, still matches. + """ + if not self.selection: + return True + for panel in (mainwindow.signalpanel, mainwindow.imagepanel): + saved_uuids = self.selection.get(panel.PANEL_STR_ID, []) + existing_uuids = set(panel.objmodel.get_object_ids()) + saved_metadata = self.object_metadata.get(panel.PANEL_STR_ID, {}) + for uuid in saved_uuids: + if uuid not in existing_uuids: + return False + if uuid in saved_metadata: + current = self.get_object_metadata(panel.objmodel[uuid]) + current = self._normalize_object_metadata(current) + saved = self._normalize_object_metadata(saved_metadata[uuid]) + if saved and current != saved: + return False + return True + + def restore(self, mainwindow: DLMainWindow) -> None: + """Restore the workspace state by selecting the recorded UUIDs. + + Args: + mainwindow: DataLab's main window + + Raises: + ValueError: If at least one of the saved UUIDs no longer exists in + its panel. + """ + if not self.selection: + return + if not self.is_current_state_compatible(mainwindow, False): + raise ValueError( + "Current workspace state is not compatible with saved state" + ) + for panel in (mainwindow.signalpanel, mainwindow.imagepanel): + uuids = self.selection.get(panel.PANEL_STR_ID, []) + if uuids: + panel.objview.select_objects(uuids) diff --git a/datalab/locale/fr/LC_MESSAGES/datalab.po b/datalab/locale/fr/LC_MESSAGES/datalab.po index 4b4b85108..fafd660ca 100644 --- a/datalab/locale/fr/LC_MESSAGES/datalab.po +++ b/datalab/locale/fr/LC_MESSAGES/datalab.po @@ -1,6 +1,6 @@ -# French translations for datalab. +# French translations for DataLab. # Copyright (C) 2026 DataLab Platform Developers -# This file is distributed under the same license as the datalab project. +# This file is distributed under the same license as the DataLab project. # msgid "" msgstr "" @@ -949,6 +949,38 @@ msgstr "Troncature de données uint32 en int32." msgid "No supported data available in HDF5 file(s)." msgstr "Aucune donnée prise en charge dans le(s) fichier(s) HDF5." +msgid "Generate macro" +msgstr "Générer une macro" + +msgid "No compute actions to export." +msgstr "Aucune action de calcul à exporter." + +#, python-format +msgid "Macro script copied to clipboard (%d actions)." +msgstr "Script macro copié dans le presse-papiers (%d actions)." + +msgid "" +"Do you really want to delete the selected items?\n" +"\n" +"Note: deleting an action also removes all subsequent actions in the same session." +msgstr "" +"Voulez-vous vraiment supprimer les éléments sélectionnés ?\n" +"\n" +"Note : la suppression d'une action supprime également toutes les actions suivantes de la même session." + +msgid "Do you really want to delete the selected items?" +msgstr "Voulez-vous vraiment supprimer les éléments sélectionnés ?" + +msgid "Remove incompatible" +msgstr "Supprimer les incompatibles" + +msgid "All actions are compatible with the current workspace." +msgstr "Toutes les actions sont compatibles avec l'espace de travail courant." + +#, python-format +msgid "%d incompatible action(s) will be removed. Continue?" +msgstr "%d action(s) incompatible(s) vont être supprimée(s). Continuer ?" + msgid "Macro simple example" msgstr "Exemple simple de macro" @@ -1656,54 +1688,17 @@ msgid "The label has been added as an annotation. You can edit or remove it usin msgstr "L'étiquette a été ajoutée comme annotation. Vous pouvez la modifier ou la supprimer en utilisant la fenêtre d'édition des annotations.<br><br>Ignorer ce message empêchera son affichage ultérieur." #, python-format -msgid "Failed to deserialize history DataSet kwarg %r." -msgstr "Échec de la désérialisation de l'argument DataSet de l'historique %r." - -#, python-format -msgid "Failed to deserialize history DataSet-list kwarg %r." -msgstr "Échec de la désérialisation de l'argument DataSet-list de l'historique %r." - -msgid "Replaying compound 'multiple_1_to_1' actions is not supported yet." -msgstr "La relecture des actions composées 'multiple_1_to_1' n'est pas encore prise en charge." - -msgid "Cannot replay 2-to-1 action: source object(s) missing." -msgstr "Impossible de rejouer une action 2-à-1 : objet(s) source manquant(s)." - -msgid "Session" -msgstr "Session" - -msgid "Show details" -msgstr "Afficher les détails" - -msgid "Hide details" -msgstr "Masquer les détails" - -msgid "Date and time" -msgstr "Date et heure" - -msgid "Description" -msgstr "Description" - -msgid "Title" -msgstr "Titre" - -msgid "Action is compatible with the current workspace state." -msgstr "L'action est compatible avec l'état actuel de l'espace de travail." - -msgid "Action is not compatible with the current workspace state." -msgstr "L'action n'est pas compatible avec l'état actuel de l'espace de travail." - -msgid "Signal" -msgstr "Signal" +msgid "“%s” has dependent operations but no valid source to reconnect to — downstream results are left unchanged." +msgstr "« %s » possède des opérations dépendantes mais aucune source valide à laquelle se reconnecter — les résultats en aval restent inchangés." -msgid "Shape" -msgstr "Forme" +msgid "Some operations could not be reconnected after deletion:" +msgstr "Certaines opérations n'ont pas pu être reconnectées après la suppression :" -msgid "Image" -msgstr "Image" +msgid "The current workspace state is not compatible with the action." +msgstr "L'état actuel de l'espace de travail n'est pas compatible avec l'action." -msgid "Dimensions" -msgstr "Dimensions" +msgid "Parameters" +msgstr "Paramètres" msgid "History panel" msgstr "Panneau d'historique" @@ -1750,15 +1745,9 @@ msgstr "Étape suivante" msgid "Select the next action in the current session" msgstr "Sélectionner l'action suivante dans la session courante" -msgid "Generate macro" -msgstr "Générer une macro" - msgid "Generate a Python macro script from history" msgstr "Générer un script macro Python à partir de l'historique" -msgid "Remove incompatible" -msgstr "Supprimer les incompatibles" - msgid "Remove actions incompatible with the current workspace" msgstr "Supprimer les actions incompatibles avec l'espace de travail courant" @@ -1789,12 +1778,6 @@ msgstr "" "\n" "Souhaitez-vous continuer ?" -msgid "The current workspace state is not compatible with the action." -msgstr "L'état actuel de l'espace de travail n'est pas compatible avec l'action." - -msgid "Parameters" -msgstr "Paramètres" - #, python-format msgid "Action %s has been edited but its target output object(s) no longer exist — skipping." msgstr "L'action %s a été modifiée mais son ou ses objets de sortie cibles n'existent plus — ignorée." @@ -1843,48 +1826,6 @@ msgstr "Recalcul en cascade" msgid "Some downstream actions could not be recomputed:" msgstr "Certaines actions en aval n'ont pas pu être recalculées :" -msgid "No compute actions to export." -msgstr "Aucune action de calcul à exporter." - -#, python-format -msgid "Macro script copied to clipboard (%d actions)." -msgstr "Script macro copié dans le presse-papiers (%d actions)." - -msgid "" -"Do you really want to delete the selected items?\n" -"\n" -"Note: deleting an action also removes all subsequent actions in the same session." -msgstr "" -"Voulez-vous vraiment supprimer les éléments sélectionnés ?\n" -"\n" -"Note : la suppression d'une action supprime également toutes les actions suivantes de la même session." - -msgid "Do you really want to delete the selected items?" -msgstr "Voulez-vous vraiment supprimer les éléments sélectionnés ?" - -msgid "All actions are compatible with the current workspace." -msgstr "Toutes les actions sont compatibles avec l'espace de travail courant." - -#, python-format -msgid "%d incompatible action(s) will be removed. Continue?" -msgstr "%d action(s) incompatible(s) vont être supprimée(s). Continuer ?" - -msgid "Save history file" -msgstr "Enregistrer un fichier d'historique" - -msgid "Open history file" -msgstr "Ouvrir un fichier d'historique" - -msgid "Imported" -msgstr "Importé" - -msgid "Some operations could not be reconnected after deletion:" -msgstr "Certaines opérations n'ont pas pu être reconnectées après la suppression :" - -#, python-format -msgid "“%s” has dependent operations but no valid source to reconnect to — downstream results are left unchanged." -msgstr "« %s » possède des opérations dépendantes mais aucune source valide à laquelle se reconnecter — les résultats en aval restent inchangés." - msgid "New image" msgstr "Nouvelle image" @@ -3377,6 +3318,32 @@ msgstr "C'est la fin de la visite guidée !" msgid "You can show the tour again, or close this dialog box." msgstr "Vous pouvez afficher la visite guidée à nouveau, ou fermer cette boîte de dialogue." +msgid "Save history file" +msgstr "Enregistrer un fichier d'historique" + +msgid "Open history file" +msgstr "Ouvrir un fichier d'historique" + +msgid "Imported" +msgstr "Importé" + +msgid "Replaying compound 'multiple_1_to_1' actions is not supported yet." +msgstr "La relecture des actions composées 'multiple_1_to_1' n'est pas encore prise en charge." + +msgid "Cannot replay 2-to-1 action: source object(s) missing." +msgstr "Impossible de rejouer une action 2-à-1 : objet(s) source manquant(s)." + +#, python-format +msgid "Failed to deserialize history DataSet kwarg %r." +msgstr "Échec de la désérialisation de l'argument DataSet de l'historique %r." + +#, python-format +msgid "Failed to deserialize history DataSet-list kwarg %r." +msgstr "Échec de la désérialisation de l'argument DataSet-list de l'historique %r." + +msgid "Session" +msgstr "Session" + msgid "Registered plugins:" msgstr "Plugins enregistrés :" @@ -3767,6 +3734,9 @@ msgstr "Afficher le tableau" msgid "Path" msgstr "Chemin" +msgid "Description" +msgstr "Description" + msgid "Textual preview" msgstr "Aperçu textuel" @@ -3785,6 +3755,24 @@ msgstr "Afficher uniquement les données prises en charge" msgid "Show values" msgstr "Afficher les valeurs" +msgid "Show details" +msgstr "Afficher les détails" + +msgid "Hide details" +msgstr "Masquer les détails" + +msgid "Date and time" +msgstr "Date et heure" + +msgid "Title" +msgstr "Titre" + +msgid "Action is compatible with the current workspace state." +msgstr "L'action est compatible avec l'état actuel de l'espace de travail." + +msgid "Action is not compatible with the current workspace state." +msgstr "L'action n'est pas compatible avec l'état actuel de l'espace de travail." + msgid "Image background selection" msgstr "Sélection de l'arrière-plan de l'image" @@ -4141,6 +4129,18 @@ msgstr "Merci de sélectionner le fichier à importer." msgid "Example Wizard" msgstr "Assistant exemple" +msgid "Signal" +msgstr "Signal" + +msgid "Shape" +msgstr "Forme" + +msgid "Image" +msgstr "Image" + +msgid "Dimensions" +msgstr "Dimensions" + msgid "Minimum value" msgstr "Valeur minimum" diff --git a/datalab/tests/features/common/auto_analysis_recompute_unit_test.py b/datalab/tests/features/common/auto_analysis_recompute_unit_test.py index 326cf66a8..7bf374acd 100644 --- a/datalab/tests/features/common/auto_analysis_recompute_unit_test.py +++ b/datalab/tests/features/common/auto_analysis_recompute_unit_test.py @@ -199,6 +199,10 @@ def test_analysis_recompute_after_recompute_1_to_1(): editor = panel.objprop.processing_param_editor editor.dataset.angle = 90.0 # Change from 45° to 90° + # In-place recompute + automatic analysis recompute only happens when + # the History panel is in edit mode (otherwise a new object is created). + win.historypanel.toggle_edit_mode(True) + # Apply the modified parameters (this triggers recompute_1_to_1) report = panel.objprop.apply_processing_parameters(interactive=False) diff --git a/datalab/tests/features/common/history_app_test.py b/datalab/tests/features/common/history_app_test.py index bf50d08e3..211b1282c 100644 --- a/datalab/tests/features/common/history_app_test.py +++ b/datalab/tests/features/common/history_app_test.py @@ -18,11 +18,13 @@ # pylint: disable=invalid-name # Allows short reference names like x, y, ... # guitest: show +import sigima.objects import sigima.params import sigima.proc.signal as sips from qtpy import QtCore as QC from sigima.tests.data import create_paracetamol_signal +from datalab.config import _ from datalab.env import execenv from datalab.gui.panel.history import HistoryAction, HistorySession, WorkspaceState from datalab.objectmodel import get_uuid @@ -34,6 +36,11 @@ def _entry_titles(history) -> list[str]: return [action.title for action in history] +def _session_action_counts(history) -> list[int]: + """Return the number of recorded actions in each history session.""" + return [len(session.actions) for session in history.history_sessions] + + def test_history_app(): """Run history application test scenario""" with datalab_test_app_context() as win: @@ -54,10 +61,11 @@ def test_history_app(): "Record mode is disabled: no entry should have been recorded" ) - # Reset workspace before starting the recorded scenario - # (this also clears the history panel) + # Reset workspace before starting the recorded scenario. + # No history exists yet, so this must not create an empty session. win.reset_all() assert len(history) == 0 + assert _session_action_counts(history) == [] # --- Enable record mode and start recording ---------------------------- history.toggle_record_mode(True) @@ -73,7 +81,7 @@ def test_history_app(): assert len(history) == 1 creation_entry = history[1] assert isinstance(creation_entry, HistoryAction) - assert creation_entry.title == "New signal" + assert creation_entry.title == _("New signal") assert creation_entry.state.selection == {} assert creation_entry.state.states == {} @@ -85,8 +93,8 @@ def test_history_app(): deriv_entry = history[2] assert deriv_entry.title # title must be non-empty # Workspace state must remember the single-object selection (by UUID) - assert deriv_entry.state.selection.get(panel.PANEL_STR) == [obj1_uuid] - assert len(deriv_entry.state.states.get(panel.PANEL_STR, [])) == 1 + assert deriv_entry.state.selection.get(panel.PANEL_STR_ID) == [obj1_uuid] + assert len(deriv_entry.state.states.get(panel.PANEL_STR_ID, [])) == 1 # 3) 1-to-1 with parameters (compute_1_to_1 + DataSet param) norm_param = sigima.params.NormalizeParam.create(method="maximum") @@ -103,7 +111,7 @@ def test_history_app(): panel.processor.run_feature(sips.fwhm, sigima.params.FWHMParam()) assert len(history) == 4 fwhm_entry = history[4] - assert fwhm_entry.state.selection.get(panel.PANEL_STR) == [obj1_uuid] + assert fwhm_entry.state.selection.get(panel.PANEL_STR_ID) == [obj1_uuid] # 5) n-to-1 aggregation (compute_n_to_1) on signals #1 and #2 obj2 = panel.objmodel.get_object_from_number(2) @@ -112,7 +120,7 @@ def test_history_app(): panel.processor.run_feature(sips.average) assert len(history) == 5 avg_entry = history[5] - assert sorted(avg_entry.state.selection.get(panel.PANEL_STR, [])) == sorted( + assert sorted(avg_entry.state.selection.get(panel.PANEL_STR_ID, [])) == sorted( [obj1_uuid, obj2_uuid] ) @@ -121,12 +129,12 @@ def test_history_app(): panel.processor.run_feature(sips.difference, obj2) assert len(history) == 6 diff_entry = history[6] - assert diff_entry.state.selection.get(panel.PANEL_STR) == [obj1_uuid] + assert diff_entry.state.selection.get(panel.PANEL_STR_ID) == [obj1_uuid] # --- Iteration / indexing API ------------------------------------------ all_titles = _entry_titles(history) assert len(all_titles) == 6 - assert all_titles[0] == "New signal" + assert all_titles[0] == _("New signal") # Indexing is 1-based; iteration order matches index order assert history[1] is creation_entry assert history[6] is diff_entry @@ -166,13 +174,12 @@ def test_history_app(): assert isinstance(action.dtstr, str) and action.dtstr # --- Delete cascade within a session ----------------------------------- - # ``delete_actions`` itself opens a confirmation dialog; we exercise the + # ``delete_selected`` itself opens a confirmation dialog; we exercise the # underlying ``HistorySession.remove_action`` path used by it. target = new_session_entry target_session: HistorySession | None = None - # pylint: disable=protected-access - for session in history._HistoryPanel__history_sessions: # noqa: SLF001 + for session in history.history_sessions: if target in session.actions: target_session = session break diff --git a/datalab/tests/features/common/history_contract_unit_test.py b/datalab/tests/features/common/history_contract_unit_test.py deleted file mode 100644 index d0731ccb6..000000000 --- a/datalab/tests/features/common/history_contract_unit_test.py +++ /dev/null @@ -1,214 +0,0 @@ -# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. - -""" -History panel contract tests - -Validates the core history-panel contract: - -1. ``compute_1_to_1`` produces a coherent ``ProcessingParameters`` *and* - history entry (same ``func_name``, same source UUID). -2. ``HistoryAction.replay`` finds its target by UUID even after the panel - has been reordered by inserting/deleting siblings. -3. ``recompute_processing`` does not add a history entry (anti-loop guard). -4. ``HistoryAction`` round-trips through HDF5 without pickling any - ``Callable`` and remains replayable after deserialisation. -5. A UI action (rename via ``set_current_object_title``) is captured and - replayable. -""" - -# pylint: disable=invalid-name - -# guitest: skip - -import os -import tempfile - -import sigima.params -import sigima.proc.signal as sips -from sigima.tests.data import create_paracetamol_signal - -from datalab.gui.panel.history import ( - HistoryAction, - HistorySession, - WorkspaceState, -) -from datalab.gui.processor.base import extract_processing_parameters -from datalab.h5.native import NativeH5Reader, NativeH5Writer -from datalab.objectmodel import get_uuid -from datalab.tests import datalab_test_app_context - - -def test_compute_1_to_1_history_matches_processing_parameters(): - """History entry and ProcessingParameters share func_name + source UUID.""" - with datalab_test_app_context() as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - panel.add_object(create_paracetamol_signal()) - src_uuid = get_uuid(panel.objmodel.get_object_from_number(1)) - - panel.objview.select_objects([1]) - panel.processor.run_feature(sips.derivative) - - # Latest object holds ProcessingParameters. - result_obj = panel.objmodel.get_object_from_number(2) - pp = extract_processing_parameters(result_obj) - assert pp is not None - assert pp.func_name == "derivative" - assert pp.source_uuid == src_uuid - - # Latest history entry mirrors the same identity. - entry = history[len(history)] - assert entry.kind == HistoryAction.KIND_COMPUTE - assert entry.func_name == "derivative" - assert entry.pattern == "1_to_1" - assert entry.state.selection.get(panel.PANEL_STR) == [src_uuid] - - -def test_replay_finds_target_by_uuid_after_reorder(): - """Replay locates source object by UUID even after reordering.""" - with datalab_test_app_context() as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - - panel.add_object(create_paracetamol_signal()) - target_uuid = get_uuid(panel.objmodel.get_object_from_number(1)) - - panel.objview.select_objects([1]) - panel.processor.run_feature(sips.derivative) - deriv_entry = history[len(history)] - - # Reorder the panel: insert a new sibling before the original source. - panel.add_object(create_paracetamol_signal()) - # Sanity: the original object now lives at a different index but its - # UUID is unchanged. - assert get_uuid(panel.objmodel[target_uuid]) == target_uuid - - n_before = len(panel.objmodel) - deriv_entry.replay(win, restore_selection=True, edit=False) - assert len(panel.objmodel) == n_before + 1 - - # The replayed result must be derived from the same source UUID. - new_obj = panel.objmodel.get_object_from_number(len(panel.objmodel)) - new_pp = extract_processing_parameters(new_obj) - assert new_pp is not None - assert new_pp.source_uuid == target_uuid - - -def test_recompute_processing_does_not_add_history_entry(): - """``recompute_processing`` is silent on the history panel (anti-loop).""" - with datalab_test_app_context() as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - panel.add_object(create_paracetamol_signal()) - - panel.objview.select_objects([1]) - panel.processor.run_feature(sips.derivative) - n_before = len(history) - - # Select the derived object and recompute it: no new entry expected. - derived = panel.objmodel.get_object_from_number(2) - panel.objview.set_current_object(derived) - panel.recompute_processing() - - assert len(history) == n_before, ( - "recompute_processing must not register a history entry" - ) - - -def test_history_action_hdf5_roundtrip_without_pickle(): - """Serialise+deserialise a HistoryAction; replay still works.""" - with datalab_test_app_context() as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - panel.add_object(create_paracetamol_signal()) - src_uuid = get_uuid(panel.objmodel.get_object_from_number(1)) - - norm_param = sigima.params.NormalizeParam.create(method="maximum") - panel.objview.select_objects([1]) - panel.processor.run_feature(sips.normalize, norm_param) - original = history[len(history)] - - # Wrap into a session so we exercise the full HDF5 path used by - # the panel (write_object_list / read_object_list). - session = HistorySession(number=1) - session.actions.append(original) - - with tempfile.TemporaryDirectory() as tmpdir: - path = os.path.join(tmpdir, "history.dlhist") - with NativeH5Writer(path) as writer: - writer.write_object_list([session], "history_session") - with NativeH5Reader(path) as reader: - restored_sessions = reader.read_object_list( - "history_session", HistorySession - ) - - assert len(restored_sessions) == 1 - restored = restored_sessions[0].actions[0] - - # No pickled Callable: the rebuilt HistoryAction has no ``func`` attr. - assert not hasattr(restored, "func") - assert restored.kind == HistoryAction.KIND_COMPUTE - assert restored.func_name == "normalize" - assert restored.pattern == "1_to_1" - assert restored.panel_str == panel.PANEL_STR_ID - # DataSet kwarg survived the JSON round-trip. - restored_param = restored.kwargs.get("param") - assert restored_param is not None - assert type(restored_param).__name__ == type(norm_param).__name__ - - # Replay the restored entry against the live workspace. - n_before = len(panel.objmodel) - restored.replay(win, restore_selection=True, edit=False) - assert len(panel.objmodel) == n_before + 1 - new_obj = panel.objmodel.get_object_from_number(len(panel.objmodel)) - new_pp = extract_processing_parameters(new_obj) - assert new_pp is not None - assert new_pp.source_uuid == src_uuid - assert new_pp.func_name == "normalize" - - -def test_ui_action_rename_capture_and_replay(): - """A UI rename is captured and can be replayed.""" - with datalab_test_app_context() as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - panel.add_object(create_paracetamol_signal()) - - obj = panel.objmodel.get_object_from_number(1) - original_title = obj.title - - new_title = "renamed-by-test" - panel.objview.set_current_object(obj) - panel.set_current_object_title(new_title) - assert obj.title == new_title - - rename_entry = history[len(history)] - assert rename_entry.kind == HistoryAction.KIND_UI - assert rename_entry.target == "signalpanel" - assert rename_entry.method_name == "set_current_object_title" - assert rename_entry.kwargs.get("title") == new_title - - # Mutate the title to something else, then replay: the entry must - # restore the recorded value. - panel.set_current_object_title("transient-title") - assert obj.title == "transient-title" - - rename_entry.replay(win, restore_selection=False, edit=False) - assert obj.title == new_title - assert obj.title != original_title - - # WorkspaceState type check. - assert isinstance(rename_entry.state, WorkspaceState) - - -if __name__ == "__main__": - test_compute_1_to_1_history_matches_processing_parameters() - test_replay_finds_target_by_uuid_after_reorder() - test_recompute_processing_does_not_add_history_entry() - test_history_action_hdf5_roundtrip_without_pickle() - test_ui_action_rename_capture_and_replay() diff --git a/datalab/tests/features/common/history_replay_app_test.py b/datalab/tests/features/common/history_replay_app_test.py deleted file mode 100644 index 6b349d43b..000000000 --- a/datalab/tests/features/common/history_replay_app_test.py +++ /dev/null @@ -1,448 +0,0 @@ -# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. - -""" -History panel replay & persistence tests - -Covers replay/restore edge cases and HDF5 persistence paths: - -1. Workspace ``.h5`` round-trip embeds the history panel and survives - save → reset → reload (``MainWindow.save_h5_workspace`` / - ``load_h5_workspace``). -2. Standalone ``HistoryPanel.serialize_to_hdf5`` / - ``deserialize_from_hdf5`` round-trip on a populated panel (mirrors - the ``.dlhist`` save/open menu paths). -3. ``1_to_n`` replay (extract ROI) reproduces the same number of - children and same source UUID. -4. ``multiple_1_to_1`` replay surfaces a clear ``NotImplementedError``. -5. Replay of a ``2_to_1`` action whose secondary source UUID has been - deleted raises ``ValueError`` instead of silently failing. -6. Public panel API ``replay_restore_actions(replay=True)`` produces - a new object when a tree item is selected. -7. Public panel API ``replay_restore_actions(replay=False)`` only - restores the workspace selection (no new object). -8. ``n_to_1`` replay forces the captured selection so a chained - ``[New, ..., New, average]`` session does not aggregate over a - stale single-object selection. -9. ``n_to_1`` replay falls back to the current selection when the - captured UUIDs no longer exist (typical of a full-session replay - in a fresh workspace), so the failure surfaces as the native - processor error rather than an opaque ``WorkspaceState`` - incompatibility. -10. Full ``HistorySession`` replay on an empty workspace correctly - re-runs ``[New, New, New, average]`` end-to-end: the per-session - UUID remap translates the captured ``n_to_1`` selection to the - freshly-created signals. -11. Full ``HistorySession`` replay with an intermediate - ``[New, New, New, Remove, average]`` correctly drops the - vanished UUID from the remap queue so ``average`` aggregates - over the right two surviving signals. -""" - -# pylint: disable=invalid-name - -# guitest: skip - -import os - -import pytest -import sigima.objects -import sigima.params -import sigima.proc.signal as sips -from qtpy import QtCore as QC -from sigima.objects.signal.creation import NewSignalParam -from sigima.tests import helpers -from sigima.tests.data import create_paracetamol_signal - -from datalab.gui.panel.history import HistoryAction, WorkspaceState -from datalab.h5.native import NativeH5Reader, NativeH5Writer -from datalab.objectmodel import get_uuid -from datalab.tests import datalab_test_app_context - - -def _select_tree_item_for(history, entry: HistoryAction) -> None: - """Select the tree item matching ``entry`` in the history tree.""" - tree = history.tree - for i in range(tree.topLevelItemCount()): - sess_item = tree.topLevelItem(i) - for j in range(sess_item.childCount()): - child = sess_item.child(j) - if child.data(0, QC.Qt.UserRole) == entry.uuid: - tree.clearSelection() - tree.setCurrentItem(child) - child.setSelected(True) - return - raise AssertionError(f"No tree item found for entry {entry.uuid}") - - -# --- 1) Workspace .h5 round-trip ------------------------------------------ - - -def test_workspace_h5_roundtrip_with_history(): - """Saving + reloading the workspace ``.h5`` preserves the history panel.""" - with datalab_test_app_context() as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - panel.add_object(create_paracetamol_signal()) - - norm_param = sigima.params.NormalizeParam.create(method="maximum") - panel.objview.select_objects([1]) - panel.processor.run_feature(sips.normalize, norm_param) - - recorded_titles = [a.title for a in history] - recorded_func_names = [a.func_name for a in history] - recorded_kinds = [a.kind for a in history] - n_recorded = len(history) - assert n_recorded >= 1 - - with helpers.WorkdirRestoringTempDir() as tmpdir: - path = os.path.join(tmpdir, "workspace.h5") - win.save_h5_workspace(path) - - # Wipe everything (objects + history) then reload. - win.reset_all() - assert len(panel.objmodel) == 0 - - win.load_h5_workspace([path], reset_all=True) - - # Note: ``save_h5_workspace`` itself records a UI history entry - # ("Save to HDF5 file") *before* writing — that entry is part of - # what gets saved. The reloaded history must therefore contain - # at least the originally-recorded actions. - reloaded = win.historypanel - reloaded_titles = [a.title for a in reloaded] - for title in recorded_titles: - assert title in reloaded_titles, ( - f"Title {title!r} missing from reloaded history" - ) - for func_name in recorded_func_names: - if func_name is not None: - assert func_name in [a.func_name for a in reloaded] - for kind in recorded_kinds: - assert kind in [a.kind for a in reloaded] - - -# --- 2) Standalone .dlhist round-trip on full panel ----------------------- - - -def test_history_panel_dlhist_roundtrip(): - """``HistoryPanel.serialize_to_hdf5`` / ``deserialize_from_hdf5`` round-trip.""" - with datalab_test_app_context() as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - panel.add_object(create_paracetamol_signal()) - panel.objview.select_objects([1]) - panel.processor.run_feature(sips.derivative) - panel.objview.select_objects([1]) - panel.processor.run_feature( - sips.normalize, sigima.params.NormalizeParam.create(method="maximum") - ) - - original_titles = [a.title for a in history] - original_func_names = [a.func_name for a in history] - assert len(original_titles) >= 2 - - with helpers.WorkdirRestoringTempDir() as tmpdir: - path = os.path.join(tmpdir, "history_panel.dlhist") - with NativeH5Writer(path) as writer: - history.serialize_to_hdf5(writer) - with NativeH5Reader(path) as reader: - history.deserialize_from_hdf5(reader) - - assert [a.title for a in history] == original_titles - assert [a.func_name for a in history] == original_func_names - - -# --- 3) 1-to-n replay (extract ROI) --------------------------------------- - - -def test_replay_1_to_n_extract_roi(): - """``extract_roi`` (1-to-n) is recorded and replayable.""" - with datalab_test_app_context() as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - - sig = create_paracetamol_signal() - sig.roi = sigima.objects.create_signal_roi([[26, 41], [125, 146]], indices=True) - panel.add_object(sig) - src_uuid = get_uuid(panel.objmodel.get_object_from_number(1)) - - n_objects_before = len(panel.objmodel) - panel.objview.select_objects([1]) - panel.processor.run_feature("extract_roi", params=sig.roi.to_params(sig)) - n_added_first = len(panel.objmodel) - n_objects_before - assert n_added_first >= 1 - - entry = history[len(history)] - assert entry.kind == HistoryAction.KIND_COMPUTE - assert entry.pattern == "1_to_n" - assert entry.func_name == "extract_roi" - assert entry.state.selection.get(panel.PANEL_STR) == [src_uuid] - - # Replay against the original source. - n_before_replay = len(panel.objmodel) - entry.replay(win, restore_selection=True, edit=False) - n_added_replay = len(panel.objmodel) - n_before_replay - assert n_added_replay == n_added_first, ( - "Replay must produce the same number of children as the original" - ) - - -# --- 4) multiple_1_to_1 NotImplementedError -------------------------------- - - -def test_multiple_1_to_1_replay_raises_not_implemented(): - """``multiple_1_to_1`` replay raises a clear ``NotImplementedError``.""" - with datalab_test_app_context() as win: - action = HistoryAction( - title="dummy multiple_1_to_1", - kind=HistoryAction.KIND_COMPUTE, - panel_str="signal", - func_name="some_compound_op", - pattern="multiple_1_to_1", - state=WorkspaceState(), - ) - with pytest.raises(NotImplementedError): - action.replay(win, restore_selection=False, edit=False) - - -# --- 5) 2-to-1 replay with vanished secondary source ----------------------- - - -def test_replay_2_to_1_with_vanished_obj2_raises(): - """Replaying a 2-to-1 action whose obj2 was deleted raises ``ValueError``.""" - with datalab_test_app_context() as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - - panel.add_object(create_paracetamol_signal()) - panel.add_object(create_paracetamol_signal()) - obj2 = panel.objmodel.get_object_from_number(2) - - panel.objview.select_objects([1]) - panel.processor.run_feature(sips.difference, obj2) - diff_entry = history[len(history)] - assert diff_entry.pattern == "2_to_1" - - # Delete obj2 so its UUID is no longer resolvable. - panel.objview.set_current_object(obj2) - panel.remove_object(force=True) - - with pytest.raises(ValueError): - # restore_selection=False so we hit the obj2 lookup path, - # not the WorkspaceState compatibility check. - diff_entry.replay(win, restore_selection=False, edit=False) - - -# --- 6) Public API replay_restore_actions(replay=True) --------------------- - - -def test_replay_via_panel_api_creates_new_object(): - """``HistoryPanel.replay_restore_actions`` replays the selected entry.""" - with datalab_test_app_context() as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - panel.add_object(create_paracetamol_signal()) - panel.objview.select_objects([1]) - panel.processor.run_feature(sips.derivative) - deriv_entry = history[len(history)] - - _select_tree_item_for(history, deriv_entry) - - n_before = len(panel.objmodel) - history.replay_restore_actions(replay=True, restore_selection=True) - assert len(panel.objmodel) == n_before + 1 - - -# --- 7) Public API replay_restore_actions(replay=False) ------------------- - - -def test_restore_selection_only_via_panel_api(): - """``replay_restore_actions(replay=False)`` only restores selection.""" - with datalab_test_app_context() as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - panel.add_object(create_paracetamol_signal()) - src_uuid = get_uuid(panel.objmodel.get_object_from_number(1)) - - panel.objview.select_objects([1]) - panel.processor.run_feature(sips.derivative) - deriv_entry = history[len(history)] - - # Move selection elsewhere (the freshly-added derivative). - derived = panel.objmodel.get_object_from_number(2) - panel.objview.set_current_object(derived) - derived_uuid = get_uuid(derived) - assert panel.objview.get_sel_object_uuids() == [derived_uuid] - - _select_tree_item_for(history, deriv_entry) - - n_before = len(panel.objmodel) - history.replay_restore_actions(replay=False, restore_selection=True) - # No new object created. - assert len(panel.objmodel) == n_before - # Selection restored to the originally-recorded source. - assert panel.objview.get_sel_object_uuids() == [src_uuid] - - -# --- 8) n_to_1 replay ignores restore_selection=False -------------------- - - -def test_replay_n_to_1_forces_captured_selection(): - """``n_to_1`` replay must restore the captured multi-object selection - even when ``restore_selection=False`` (otherwise an aggregator such as - ``average`` would be applied to the single object the previous action - left selected and fail with ``src_list must be a list of at least 2 - objects``).""" - with datalab_test_app_context() as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - - panel.add_object(create_paracetamol_signal()) - panel.add_object(create_paracetamol_signal()) - panel.add_object(create_paracetamol_signal()) - - # Average over the three signals (n_to_1 aggregator). - panel.objview.select_objects([1, 2, 3]) - panel.processor.run_feature(sips.average) - avg_entry = history[len(history)] - assert avg_entry.pattern == "n_to_1" - - # Drift selection to a single object (mimics the state left by a - # preceding "New signal" UI action in a chained session replay). - panel.objview.select_objects([1]) - assert len(panel.objview.get_sel_object_uuids()) == 1 - - n_before = len(panel.objmodel) - # restore_selection=False on purpose: compute actions must still - # restore their captured selection internally. - avg_entry.replay(win, restore_selection=False, edit=False) - assert len(panel.objmodel) == n_before + 1 - - -# --- 9) n_to_1 replay tolerates vanished captured UUIDs ------------------- - - -def test_replay_n_to_1_falls_back_when_captured_uuids_gone(): - """When the captured selection refers to UUIDs that no longer exist - (full-session replay creates fresh objects with new UUIDs), the - compute replay must fall back to the current selection rather than - raising the opaque ``WorkspaceState`` incompatibility error.""" - with datalab_test_app_context() as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - - panel.add_object(create_paracetamol_signal()) - panel.add_object(create_paracetamol_signal()) - panel.add_object(create_paracetamol_signal()) - panel.objview.select_objects([1, 2, 3]) - panel.processor.run_feature(sips.average) - avg_entry = history[len(history)] - assert avg_entry.pattern == "n_to_1" - - # Wipe the workspace and recreate three signals: same shape, - # different UUIDs (mimics the state mid-way through a full - # session replay). The captured selection is now stale. - win.reset_all() - panel.add_object(create_paracetamol_signal()) - panel.add_object(create_paracetamol_signal()) - panel.add_object(create_paracetamol_signal()) - panel.objview.select_objects([1, 2, 3]) - assert not avg_entry.state.is_current_state_compatible(win, False) - - n_before = len(panel.objmodel) - # Must not raise ValueError("... not compatible with saved state"); - # falls back to the current selection (the 3 freshly-added signals). - avg_entry.replay(win, restore_selection=False, edit=False) - assert len(panel.objmodel) == n_before + 1 - - -# --- 10) Full session replay with UUID remap ------------------------------ - - -def test_full_session_replay_remaps_uuids_for_n_to_1(): - """A full ``HistorySession.replay`` on an empty workspace correctly - re-runs ``[New signal, New signal, New signal, average]``: the - per-session UUID remap translates ``average``'s captured selection - to the freshly-created signals, instead of aggregating over the - single object the last ``New signal`` left selected.""" - with datalab_test_app_context() as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - - # Record [New, New, New, average]. - for _i in range(3): - panel.new_object(param=NewSignalParam(), edit=False) - n_after_creations = len(panel.objmodel) - assert n_after_creations == 3 - panel.objview.select_objects([1, 2, 3]) - panel.processor.run_feature(sips.average) - assert len(panel.objmodel) == 4 - - # pylint: disable=protected-access - session = history._HistoryPanel__history_sessions[-1] # noqa: SLF001 - - # Reset to an empty workspace, then replay the whole session. - win.reset_all() - assert len(panel.objmodel) == 0 - session.replay(win, restore_selection=False, edit=False) - # 3 fresh signals + 1 average = 4 objects. - assert len(panel.objmodel) == 4 - - -# --- 11) Full session replay with intermediate removal -------------------- - - -def test_full_session_replay_with_intermediate_removal(): - """A full ``HistorySession.replay`` with ``[New, New, New, Remove, - average]`` correctly drops the removed UUID from the unclaimed - queue and the reverse remap, so ``average`` aggregates over the - two surviving signals (and not, e.g., over a stale single-object - selection or a removed one).""" - with datalab_test_app_context() as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - - # Record [New, New, New, Remove #3, average of remaining 2]. - for _i in range(3): - panel.new_object(param=NewSignalParam(), edit=False) - assert len(panel.objmodel) == 3 - panel.objview.select_objects([3]) - panel.remove_object(force=True) - assert len(panel.objmodel) == 2 - panel.objview.select_objects([1, 2]) - panel.processor.run_feature(sips.average) - assert len(panel.objmodel) == 3 - - # pylint: disable=protected-access - session = history._HistoryPanel__history_sessions[-1] # noqa: SLF001 - - # Reset to an empty workspace, then replay the whole session. - win.reset_all() - assert len(panel.objmodel) == 0 - session.replay(win, restore_selection=False, edit=False) - # 3 created − 1 removed + 1 average = 3 objects. - assert len(panel.objmodel) == 3 - - -if __name__ == "__main__": - test_workspace_h5_roundtrip_with_history() - test_history_panel_dlhist_roundtrip() - test_replay_1_to_n_extract_roi() - test_multiple_1_to_1_replay_raises_not_implemented() - test_replay_2_to_1_with_vanished_obj2_raises() - test_replay_via_panel_api_creates_new_object() - test_restore_selection_only_via_panel_api() - test_replay_n_to_1_forces_captured_selection() - test_replay_n_to_1_falls_back_when_captured_uuids_gone() - test_full_session_replay_remaps_uuids_for_n_to_1() - test_full_session_replay_with_intermediate_removal() diff --git a/datalab/tests/features/common/history_test.py b/datalab/tests/features/common/history_test.py new file mode 100644 index 000000000..6d03bf29a --- /dev/null +++ b/datalab/tests/features/common/history_test.py @@ -0,0 +1,1508 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +""" +History panel — grouped exhaustive tests. + +Each ``test_history_*`` function bundles several closely-related scenarios +that previously lived in dedicated tests across: + +* ``history_contract_unit_test.py`` (schema, compatibility, capture/replay + of UI actions, ROI clipboard, HDF5 round-trips, etc.) +* ``history_replay_app_test.py`` (replay patterns, session replay, + duplication, stepping, tree selection, cascade, dlhist persistence, + chain reconnection) +* ``history_app_test.py::test_history_reset_starts_new_session`` + +Each scenario is delimited by a ``# --- scenario: <name> ---`` comment. +Scenarios sharing GUI state run inside a single ``datalab_test_app_context`` +block; truly independent pure-Python scenarios (HDF5 round-trip, +``NotImplementedError`` smoke) run outside or in a nested block. + +Two GUI smoke tests are intentionally kept in their own modules: +``history_app_test.py::test_history_app`` and +``history_panel_app_test.py::test_history_panel``. +""" + +# guitest: skip + +import os +import shutil +import tempfile + +import numpy as np +import pytest +import sigima.objects +import sigima.params +import sigima.proc.signal as sips +from qtpy import QtCore as QC +from sigima.objects import create_signal_roi +from sigima.objects.base import BaseROI +from sigima.objects.signal.creation import NewSignalParam +from sigima.tests import helpers +from sigima.tests.data import create_paracetamol_signal + +from datalab.config import _ +from datalab.gui.panel.base import AddMetadataParam, BaseDataPanel +from datalab.gui.panel.history import ( + HISTORY_ACTION_SCHEMA_VERSION, + HISTORY_SCHEMA_VERSION, + HistoryAction, + HistorySession, + HistoryTree, + WorkspaceState, +) +from datalab.gui.processor.base import extract_processing_parameters +from datalab.h5.native import NativeH5Reader, NativeH5Writer +from datalab.objectmodel import get_uuid +from datalab.tests import datalab_test_app_context + +# --------------------------------------------------------------------------- +# Helpers +# --------------------------------------------------------------------------- + + +def _delete_hdf5_items_by_name(group, item_name: str) -> None: + """Delete HDF5 attributes/groups named ``item_name`` recursively.""" + if item_name in group.attrs: + del group.attrs[item_name] + if not hasattr(group, "keys"): + return + for key in list(group.keys()): + if key == item_name: + del group[key] + else: + _delete_hdf5_items_by_name(group[key], item_name) + + +def _create_serializable_history_session() -> HistorySession: + """Create a history session requiring no application startup.""" + state = WorkspaceState() + state.selection = {"signal": ["source-uuid"]} + state.states = {"signal": ["(10,)"]} + state.titles = {"signal": ["source"]} + state.object_metadata = {"signal": {"source-uuid": {"shape": [10], "ndim": 1}}} + action = HistoryAction( + title="Rename", + kind=HistoryAction.KIND_UI, + target="signalpanel", + method_name="set_current_object_title", + kwargs={"title": "renamed"}, + state=state, + ) + session = HistorySession(number=1) + session.add_action(action) + return session + + +def _session_action_counts(history) -> list[int]: + """Return the number of recorded actions in each history session.""" + return [len(session.actions) for session in history.history_sessions] + + +def _get_tree_item_for(history, entry: HistoryAction): + """Return the tree item matching ``entry`` in the history tree.""" + tree = history.tree + for i in range(tree.topLevelItemCount()): + sess_item = tree.topLevelItem(i) + for j in range(sess_item.childCount()): + child = sess_item.child(j) + if child.data(0, QC.Qt.UserRole) == entry.uuid: + return child + raise AssertionError(f"No tree item found for entry {entry.uuid}") + + +def _select_tree_item_for(history, entry: HistoryAction) -> None: + """Select the tree item matching ``entry`` in the history tree.""" + child = _get_tree_item_for(history, entry) + history.tree.clearSelection() + history.tree.setCurrentItem(child) + child.setSelected(True) + + +def _select_tree_session(history, session) -> None: + """Select the tree item matching ``session`` in the history tree.""" + sessions = history.history_sessions + index = sessions.index(session) + item = history.tree.topLevelItem(index) + history.tree.clearSelection() + history.tree.setCurrentItem(item) + item.setSelected(True) + + +def _record_three_action_session(win): + """Helper: record [add_signal + normalize + derivative] in one session.""" + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) + panel.objview.select_objects([1]) + panel.processor.run_feature( + sips.normalize, sigima.params.NormalizeParam.create(method="maximum") + ) + panel.objview.select_objects([2]) + panel.processor.run_feature(sips.derivative) + return panel, history + + +def _build_cascade_chain(panel, history): + """Build chain s001 -> gaussian -> s002 -> derivative -> s003 -> mavg -> s004. + + Returns ``(action_A, action_B, action_C, output_B, output_C)``. + """ + panel.add_object(create_paracetamol_signal()) + panel.objview.select_objects([1]) + panel.processor.run_feature( + sips.gaussian_filter, sigima.params.GaussianParam.create(sigma=1.5) + ) + action_A = history[len(history)] + + panel.objview.select_objects([2]) + panel.processor.run_feature(sips.derivative) + action_B = history[len(history)] + output_B = panel.objmodel.get_object_from_number(3) + + panel.objview.select_objects([3]) + mavg = sigima.params.MovingAverageParam() + mavg.n = 3 + panel.processor.run_feature(sips.moving_average, mavg) + action_C = history[len(history)] + output_C = panel.objmodel.get_object_from_number(4) + return action_A, action_B, action_C, output_B, output_C + + +# --------------------------------------------------------------------------- +# 1) Schema + HDF5 round-trips +# --------------------------------------------------------------------------- + + +def test_history_schema_and_hdf5_roundtrip(): + """Schema persistence + HDF5 round-trip variants (.dlhist and .h5).""" + # --- scenario: schema_version is persisted --- + session = _create_serializable_history_session() + with tempfile.TemporaryDirectory() as tmpdir: + path = os.path.join(tmpdir, "history_schema.dlhist") + with NativeH5Writer(path) as writer: + writer.write_object_list([session], "history_session") + with NativeH5Reader(path) as reader: + restored_sessions = reader.read_object_list( + "history_session", HistorySession + ) + assert len(restored_sessions) == 1 + restored = restored_sessions[0] + assert restored.schema_version == HISTORY_SCHEMA_VERSION + assert restored.actions[0].schema_version == HISTORY_ACTION_SCHEMA_VERSION + assert restored.actions[0].kwargs == {"title": "renamed"} + assert restored.actions[0].state.object_metadata == { + "signal": {"source-uuid": {"shape": [10], "ndim": 1}} + } + + # --- scenario: missing schema_version defaults to current --- + session = _create_serializable_history_session() + with tempfile.TemporaryDirectory() as tmpdir: + path = os.path.join(tmpdir, "history_schema_missing.dlhist") + with NativeH5Writer(path) as writer: + writer.write_object_list([session], "history_session") + _delete_hdf5_items_by_name(writer.h5, "schema_version") + with NativeH5Reader(path) as reader: + restored_sessions = reader.read_object_list( + "history_session", HistorySession + ) + restored_action = restored_sessions[0].actions[0] + assert restored_sessions[0].schema_version == HISTORY_SCHEMA_VERSION + assert restored_action.schema_version == HISTORY_SCHEMA_VERSION + assert restored_action.title == "Rename" + + # --- scenario: ROI kwargs survive HDF5 round-trip --- + roi = create_signal_roi([[26, 41]], indices=True) + state = WorkspaceState() + state.selection = {"signal": ["dst-uuid"]} + state.states = {"signal": ["(100,)"]} + state.titles = {"signal": ["dst"]} + state.object_metadata = {"signal": {"dst-uuid": {"shape": [100], "ndim": 1}}} + action = HistoryAction( + title="Paste ROI", + kind=HistoryAction.KIND_UI, + target="signalpanel", + method_name="paste_roi", + kwargs={"roi_data": roi}, + state=state, + ) + session = HistorySession(number=1) + session.add_action(action) + with tempfile.TemporaryDirectory() as tmpdir: + path = os.path.join(tmpdir, "roi_roundtrip.dlhist") + with NativeH5Writer(path) as writer: + writer.write_object_list([session], "history_session") + with NativeH5Reader(path) as reader: + restored_sessions = reader.read_object_list( + "history_session", HistorySession + ) + restored_roi = restored_sessions[0].actions[0].kwargs.get("roi_data") + assert restored_roi is not None + assert isinstance(restored_roi, BaseROI) + assert restored_roi.get_single_roi(0).coords.tolist() == [26, 41] + + # --- scenario: legacy translated panel keys are normalized --- + state = WorkspaceState() + state.selection = {"Signal Panel": ["uuid-1"]} + state.states = {"Signal Panel": ["(10,)"]} + state.titles = {"Signal Panel": ["obj1"]} + state.object_metadata = {"Signal Panel": {"uuid-1": {"shape": [10], "ndim": 1}}} + legacy_action = HistoryAction( + title="Legacy", + kind=HistoryAction.KIND_UI, + target="signalpanel", + method_name="set_current_object_title", + kwargs={"title": "renamed"}, + state=state, + ) + legacy_session = HistorySession(number=1) + legacy_session.add_action(legacy_action) + with tempfile.TemporaryDirectory() as tmpdir: + path = os.path.join(tmpdir, "legacy_keys.dlhist") + with NativeH5Writer(path) as writer: + writer.write_object_list([legacy_session], "history_session") + with NativeH5Reader(path) as reader: + restored_sessions = reader.read_object_list( + "history_session", HistorySession + ) + rstate = restored_sessions[0].actions[0].state + assert "signal" in rstate.selection and "Signal Panel" not in rstate.selection + assert rstate.selection["signal"] == ["uuid-1"] + assert rstate.states["signal"] == ["(10,)"] + assert rstate.titles["signal"] == ["obj1"] + assert rstate.object_metadata["signal"] == {"uuid-1": {"shape": [10], "ndim": 1}} + + # GUI-bound HDF5 scenarios run inside one app context. + with datalab_test_app_context() as win: + history = win.historypanel + panel = win.signalpanel + + # --- scenario: deserialize from .h5 without history group does not raise --- + with tempfile.TemporaryDirectory() as tmpdir: + path = os.path.join(tmpdir, "no_history.h5") + with NativeH5Writer(path) as writer: + panel.serialize_to_hdf5(writer) + with NativeH5Reader(path) as reader: + history.deserialize_from_hdf5(reader) + assert len(history) == 0 + + # --- scenario: HistoryAction HDF5 round-trip without pickle, then replay --- + history.toggle_record_mode(True) + panel.add_object(create_paracetamol_signal()) + src_uuid = get_uuid(panel.objmodel.get_object_from_number(1)) + norm_param = sigima.params.NormalizeParam.create(method="maximum") + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.normalize, norm_param) + original = history[len(history)] + ser_session = HistorySession(number=1) + ser_session.actions.append(original) + with tempfile.TemporaryDirectory() as tmpdir: + path = os.path.join(tmpdir, "history.dlhist") + with NativeH5Writer(path) as writer: + writer.write_object_list([ser_session], "history_session") + with NativeH5Reader(path) as reader: + restored_sessions = reader.read_object_list( + "history_session", HistorySession + ) + restored = restored_sessions[0].actions[0] + assert not hasattr(restored, "func") + assert restored.kind == HistoryAction.KIND_COMPUTE + assert restored.func_name == "normalize" + assert restored.pattern == "1_to_1" + assert restored.panel_str == panel.PANEL_STR_ID + restored_param = restored.kwargs.get("param") + assert restored_param is not None + assert type(restored_param).__name__ == type(norm_param).__name__ + n_before = len(panel.objmodel) + restored.replay(win, restore_selection=True, edit=False) + assert len(panel.objmodel) == n_before + 1 + new_obj = panel.objmodel.get_object_from_number(len(panel.objmodel)) + new_pp = extract_processing_parameters(new_obj) + assert new_pp is not None + assert new_pp.source_uuid == src_uuid + assert new_pp.func_name == "normalize" + + # --- scenario: workspace .h5 round-trip embeds history --- + recorded_titles = [a.title for a in history] + recorded_func_names = [a.func_name for a in history] + recorded_kinds = [a.kind for a in history] + assert len(history) >= 1 + with helpers.WorkdirRestoringTempDir() as tmpdir: + path = os.path.join(tmpdir, "workspace.h5") + win.save_h5_workspace(path) + win.reset_all() + assert len(panel.objmodel) == 0 + win.load_h5_workspace([path], reset_all=True) + reloaded = win.historypanel + reloaded_titles = [a.title for a in reloaded] + for title in recorded_titles: + assert title in reloaded_titles + for func_name in recorded_func_names: + if func_name is not None: + assert func_name in [a.func_name for a in reloaded] + for kind in recorded_kinds: + assert kind in [a.kind for a in reloaded] + + # --- scenario: standalone .dlhist round-trip (import path on non-empty WS) --- + win.reset_all() + history = win.historypanel + panel = win.signalpanel + history.toggle_record_mode(True) + panel.add_object(create_paracetamol_signal()) + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.derivative) + panel.objview.select_objects([1]) + panel.processor.run_feature( + sips.normalize, sigima.params.NormalizeParam.create(method="maximum") + ) + original_titles = [a.title for a in history] + original_func_names = [a.func_name for a in history] + assert len(original_titles) >= 2 + n_actions_before = len(history) + n_signals_before = len(panel.objmodel) + n_sessions_before = len(history.history_sessions) + with helpers.WorkdirRestoringTempDir() as tmpdir: + path = os.path.join(tmpdir, "history_panel.dlhist") + assert history.save_to_dlhist_file(path) + assert history.open_dlhist_file(path) + reloaded_titles = [a.title for a in history] + reloaded_func_names = [a.func_name for a in history] + for title in original_titles: + assert title in reloaded_titles + for func_name in original_func_names: + if func_name is not None: + assert func_name in reloaded_func_names + assert len(history.history_sessions) > n_sessions_before + assert len(panel.objmodel) > n_signals_before + assert len(history) > n_actions_before + + # --- scenario: .dlhist self-contained — direct-load into fresh empty workspace --- + tmpdir = tempfile.mkdtemp() + try: + path = os.path.join(tmpdir, "test.dlhist") + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.derivative) + original_titles = [a.title for a in history] + original_func_names = [a.func_name for a in history] + assert len(original_titles) >= 1 + assert history.save_to_dlhist_file(path) + with datalab_test_app_context() as win2: + history2 = win2.historypanel + panel2 = win2.signalpanel + assert len(panel2.objmodel) == 0 + assert len(history2.history_sessions) == 0 + assert history2.open_dlhist_file(path) + reloaded_titles = [a.title for a in history2] + reloaded_func_names = [a.func_name for a in history2] + assert reloaded_titles == original_titles + for func_name in original_func_names: + if func_name is not None: + assert func_name in reloaded_func_names + assert len(panel2.objmodel) >= 1 + finally: + shutil.rmtree(tmpdir, ignore_errors=True) + + +# --------------------------------------------------------------------------- +# 2) HistoryAction / WorkspaceState compatibility +# --------------------------------------------------------------------------- + + +def test_history_action_compatibility(): + """``HistoryAction`` compatibility (UUID/shape/legacy fallback + tree marker).""" + # --- scenario: incompatible when selected UUID disappears --- + with datalab_test_app_context() as win: + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) + obj = panel.objmodel.get_object_from_number(1) + panel.objview.set_current_object(obj) + state = WorkspaceState() + state.save(win) + action = HistoryAction(title="Dummy", state=state) + assert action.is_current_state_compatible(win, restore_selection=False) + panel.remove_object(force=True) + assert not action.is_current_state_compatible(win, restore_selection=False) + + # --- scenario: incompatible when selected object shape changes --- + win.reset_all() + panel.add_object(create_paracetamol_signal()) + obj = panel.objmodel.get_object_from_number(1) + panel.objview.set_current_object(obj) + state = WorkspaceState() + state.save(win) + action = HistoryAction(title="Dummy", state=state) + assert action.is_current_state_compatible(win, restore_selection=False) + obj.set_xydata(obj.x[:-1], obj.y[:-1]) + assert not action.is_current_state_compatible(win, restore_selection=False) + + # --- scenario: histories without object_metadata fall back to UUID check --- + win.reset_all() + panel.add_object(create_paracetamol_signal()) + obj = panel.objmodel.get_object_from_number(1) + panel.objview.set_current_object(obj) + state = WorkspaceState() + state.save(win) + action = HistoryAction(title="Dummy", state=state) + session = HistorySession(number=1) + session.add_action(action) + with tempfile.TemporaryDirectory() as tmpdir: + path = os.path.join(tmpdir, "history_without_gate2_metadata.dlhist") + with NativeH5Writer(path) as writer: + writer.write_object_list([session], "history_session") + _delete_hdf5_items_by_name(writer.h5, "object_metadata") + with NativeH5Reader(path) as reader: + restored_sessions = reader.read_object_list( + "history_session", HistorySession + ) + restored_action = restored_sessions[0].actions[0] + assert restored_action.state.object_metadata == {} + assert restored_action.is_current_state_compatible(win, restore_selection=False) + + # --- scenario: tree marks incompatible action after source deletion --- + win.reset_all() + history = win.historypanel + history.toggle_record_mode(True) + panel.add_object(create_paracetamol_signal()) + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.derivative) + deriv_entry = history[len(history)] + item = _get_tree_item_for(history, deriv_entry) + assert item.data(0, HistoryTree.COMPATIBILITY_ROLE) is True + history.toggle_record_mode(False) + panel.objview.select_objects([1]) + panel.remove_object(force=True) + history.refresh_compatibility_items() + item = _get_tree_item_for(history, deriv_entry) + assert item.data(0, HistoryTree.COMPATIBILITY_ROLE) is False + assert item.foreground(0).color().isValid() + + +# --------------------------------------------------------------------------- +# 3) Recording: compute + UI actions +# --------------------------------------------------------------------------- + + +def test_history_recording_compute_and_ui(monkeypatch): + """Recording and replay of compute + UI actions (capture fidelity).""" + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) + src_uuid = get_uuid(panel.objmodel.get_object_from_number(1)) + + # --- scenario: compute_1_to_1 history matches ProcessingParameters --- + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.derivative) + result_obj = panel.objmodel.get_object_from_number(2) + pp = extract_processing_parameters(result_obj) + assert pp is not None + assert pp.func_name == "derivative" + assert pp.source_uuid == src_uuid + entry = history[len(history)] + assert entry.kind == HistoryAction.KIND_COMPUTE + assert entry.func_name == "derivative" + assert entry.pattern == "1_to_1" + assert entry.state.selection.get(panel.PANEL_STR_ID) == [src_uuid] + + # --- scenario: recompute_processing does not add a history entry --- + n_before = len(history) + derived = panel.objmodel.get_object_from_number(2) + panel.objview.set_current_object(derived) + panel.recompute_processing() + assert len(history) == n_before + + # --- scenario: replay finds target by UUID after panel reorder --- + deriv_entry = history[len(history)] + panel.add_object(create_paracetamol_signal()) + assert get_uuid(panel.objmodel[src_uuid]) == src_uuid + n_before_replay = len(panel.objmodel) + deriv_entry.replay(win, restore_selection=True, edit=False) + assert len(panel.objmodel) == n_before_replay + 1 + new_obj = panel.objmodel.get_object_from_number(len(panel.objmodel)) + new_pp = extract_processing_parameters(new_obj) + assert new_pp is not None + assert new_pp.source_uuid == src_uuid + + # --- scenario: UI rename capture + replay --- + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) + obj = panel.objmodel.get_object_from_number(1) + original_title = obj.title + new_title = "renamed-by-test" + panel.objview.set_current_object(obj) + panel.set_current_object_title(new_title) + assert obj.title == new_title + rename_entry = history[len(history)] + assert rename_entry.kind == HistoryAction.KIND_UI + assert rename_entry.target == "signalpanel" + assert rename_entry.method_name == "set_current_object_title" + assert rename_entry.kwargs.get("title") == new_title + panel.set_current_object_title("transient-title") + assert obj.title == "transient-title" + rename_entry.replay(win, restore_selection=False, edit=False) + assert obj.title == new_title and obj.title != original_title + assert isinstance(rename_entry.state, WorkspaceState) + + # --- scenario: add_metadata capture --- + obj_uuid = get_uuid(obj) + panel.objview.select_objects([1]) + param = AddMetadataParam([obj]) + param.metadata_key = "history_gate6" + param.value_pattern = "value_{index}" + param.conversion = "string" + panel.add_metadata(param) + entry = history[len(history)] + assert entry.kind == HistoryAction.KIND_UI + assert entry.target == "signalpanel" + assert entry.method_name == "add_metadata" + captured = entry.kwargs.get("param") + assert captured is not None and captured is not param + assert captured.metadata_key == param.metadata_key + assert captured.value_pattern == param.value_pattern + assert captured.conversion == param.conversion + assert entry.state.selection.get(panel.PANEL_STR_ID) == [obj_uuid] + + # --- scenario: add_metadata replay --- + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) + obj = panel.objmodel.get_object_from_number(1) + panel.objview.select_objects([1]) + param = AddMetadataParam([obj]) + param.metadata_key = "replay_test_key" + param.value_pattern = "replay_value_{index}" + param.conversion = "string" + panel.add_metadata(param) + assert obj.metadata.get("replay_test_key") == "replay_value_1" + entry = history[len(history)] + del obj.metadata["replay_test_key"] + assert "replay_test_key" not in obj.metadata + entry.replay(win, restore_selection=False, edit=False) + assert obj.metadata.get("replay_test_key") == "replay_value_1" + + # --- scenario: ROI copy/paste capture + deterministic replay --- + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + src = create_paracetamol_signal() + src.roi = create_signal_roi([[26, 41]], indices=True) + panel.add_object(src) + dst = create_paracetamol_signal() + panel.add_object(dst) + src_uuid = get_uuid(src) + dst_uuid = get_uuid(dst) + panel.objview.set_current_item_id(src_uuid) + panel.copy_roi() + copy_entry = history[len(history)] + panel.objview.set_current_item_id(dst_uuid) + panel.paste_roi() + paste_entry = history[len(history)] + assert copy_entry.kind == HistoryAction.KIND_UI + assert copy_entry.target == "signalpanel" + assert copy_entry.method_name == "copy_roi" + assert "roi_data" in copy_entry.kwargs + assert copy_entry.state.selection.get(panel.PANEL_STR_ID) == [src_uuid] + assert paste_entry.kind == HistoryAction.KIND_UI + assert paste_entry.target == "signalpanel" + assert paste_entry.method_name == "paste_roi" + assert "roi_data" in paste_entry.kwargs + assert paste_entry.state.selection.get(panel.PANEL_STR_ID) == [dst_uuid] + # Deterministic replay: change source ROI then replay paste. + dst_obj = panel.objmodel.get_object_from_number(2) + assert dst_obj.roi is not None + src.roi = create_signal_roi([[100, 200]], indices=True) + dst_obj.roi = None + paste_entry.replay(win, restore_selection=False, edit=False) + assert dst_obj.roi is not None + assert dst_obj.roi.get_single_roi(0).coords.tolist() == [26, 41] + + # --- scenario: save_to_directory capture + replay --- + saved_paths: list[str] = [] + + def fake_save_to_file(_self, _obj, filename): + saved_paths.append(filename) + + monkeypatch.setattr( + BaseDataPanel, "_BaseDataPanel__save_to_file", fake_save_to_file + ) + with datalab_test_app_context() as win: + with helpers.WorkdirRestoringTempDir() as tmpdir: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) + obj = panel.objmodel.get_object_from_number(1) + obj_uuid = get_uuid(obj) + panel.objview.select_objects([1]) + param = sigima.params.SaveToDirectoryParam.create( + directory=tmpdir, + basename="history_gate6_{index}", + extension=".csv", + overwrite=True, + ) + panel.save_to_directory(param) + entry = history[len(history)] + assert entry.kind == HistoryAction.KIND_UI + assert entry.target == "signalpanel" + assert entry.method_name == "save_to_directory" + captured = entry.kwargs.get("param") + assert captured is not None and captured is not param + assert captured.directory == param.directory + assert captured.basename == param.basename + assert captured.extension == param.extension + assert captured.overwrite == param.overwrite + assert entry.state.selection.get(panel.PANEL_STR_ID) == [obj_uuid] + assert saved_paths == [os.path.join(tmpdir, "history_gate6_1.csv")] + # Replay: must call save again with same parameters. + n_before = len(saved_paths) + entry.replay(win, restore_selection=False, edit=False) + assert len(saved_paths) == n_before + 1 + assert saved_paths[-1] == saved_paths[-2] + + +# --------------------------------------------------------------------------- +# 4) Replay patterns (1_to_n, n_to_1, 2_to_1, multiple_1_to_1, normal) +# --------------------------------------------------------------------------- + + +def test_history_replay_patterns(monkeypatch): + """Replay behaviour for each compute pattern (persistent + non-persistent).""" + # --- scenario: multiple_1_to_1 replay raises NotImplementedError --- + with datalab_test_app_context() as win: + action = HistoryAction( + title="dummy multiple_1_to_1", + kind=HistoryAction.KIND_COMPUTE, + panel_str="signal", + func_name="some_compound_op", + pattern="multiple_1_to_1", + state=WorkspaceState(), + ) + with pytest.raises(NotImplementedError): + action.replay(win, restore_selection=False, edit=False) + + # --- scenario: normal processing outside replay still adds objects --- + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) + panel.objview.select_objects([1]) + n_before = len(panel.objmodel) + panel.processor.run_feature(sips.derivative) + assert len(panel.objmodel) == n_before + 1 + + # --- scenario: 1_to_n extract_roi replay (persistent direct replay) --- + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + sig = create_paracetamol_signal() + sig.roi = sigima.objects.create_signal_roi([[26, 41], [125, 146]], indices=True) + panel.add_object(sig) + src_uuid = get_uuid(panel.objmodel.get_object_from_number(1)) + n_objects_before = len(panel.objmodel) + panel.objview.select_objects([1]) + panel.processor.run_feature("extract_roi", params=sig.roi.to_params(sig)) + n_added_first = len(panel.objmodel) - n_objects_before + assert n_added_first >= 1 + entry = history[len(history)] + assert entry.kind == HistoryAction.KIND_COMPUTE + assert entry.pattern == "1_to_n" + assert entry.func_name == "extract_roi" + assert entry.state.selection.get(panel.PANEL_STR_ID) == [src_uuid] + n_before_replay = len(panel.objmodel) + entry.replay(win, restore_selection=True, edit=False) + assert len(panel.objmodel) - n_before_replay == n_added_first + + # --- scenario: 1_to_n via panel API does NOT add output (non-persistent) --- + _select_tree_item_for(history, entry) + n_before = len(panel.objmodel) + n_hist_before = len(history) + history.replay_restore_actions(replay=True, restore_selection=True) + assert len(panel.objmodel) == n_before + assert len(history) == n_hist_before + + # --- scenario: n_to_1 forces captured selection --- + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) + panel.add_object(create_paracetamol_signal()) + panel.add_object(create_paracetamol_signal()) + panel.objview.select_objects([1, 2, 3]) + panel.processor.run_feature(sips.average) + avg_entry = history[len(history)] + assert avg_entry.pattern == "n_to_1" + panel.objview.select_objects([1]) + assert len(panel.objview.get_sel_object_uuids()) == 1 + n_before = len(panel.objmodel) + avg_entry.replay(win, restore_selection=False, edit=False) + assert len(panel.objmodel) == n_before + 1 + + # --- scenario: n_to_1 via panel API does NOT add output --- + _select_tree_item_for(history, avg_entry) + n_before = len(panel.objmodel) + n_hist_before = len(history) + history.replay_restore_actions(replay=True, restore_selection=True) + assert len(panel.objmodel) == n_before + assert len(history) == n_hist_before + + # --- scenario: n_to_1 falls back when captured UUIDs are gone --- + win.reset_all() + panel.add_object(create_paracetamol_signal()) + panel.add_object(create_paracetamol_signal()) + panel.add_object(create_paracetamol_signal()) + panel.objview.select_objects([1, 2, 3]) + assert not avg_entry.state.is_current_state_compatible(win, False) + n_before = len(panel.objmodel) + avg_entry.replay(win, restore_selection=False, edit=False) + assert len(panel.objmodel) == n_before + 1 + + # --- scenario: n_to_1 passes recorded pairwise flag --- + with datalab_test_app_context() as win: + panel = win.signalpanel + captured: dict = {} + + def capture_compute_n_to_1(*_args, **kwargs): + captured.update(kwargs) + + monkeypatch.setattr(panel.processor, "compute_n_to_1", capture_compute_n_to_1) + action = HistoryAction( + title="average pairwise", + kind=HistoryAction.KIND_COMPUTE, + panel_str=panel.PANEL_STR_ID, + func_name="average", + pattern="n_to_1", + kwargs={"pairwise": True}, + state=WorkspaceState(), + ) + action._replay_compute(win, edit=False) # noqa: SLF001 + assert captured["pairwise"] is True + + # --- scenario: 2_to_1 with vanished obj2 raises ValueError --- + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) + panel.add_object(create_paracetamol_signal()) + obj2 = panel.objmodel.get_object_from_number(2) + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.difference, obj2) + diff_entry = history[len(history)] + assert diff_entry.pattern == "2_to_1" + panel.objview.set_current_object(obj2) + panel.remove_object(force=True) + with pytest.raises(ValueError): + diff_entry.replay(win, restore_selection=False, edit=False) + + # --- scenario: 2_to_1 replay translates obj2 UUIDs and passes pairwise --- + with datalab_test_app_context() as win: + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) + obj2 = panel.objmodel.get_object_from_number(1) + obj2_uuid = get_uuid(obj2) + captured = {} + + def capture_compute_2_to_1(obj2_arg, *_args, **kwargs): + captured["obj2"] = obj2_arg + captured.update(kwargs) + + monkeypatch.setattr(panel.processor, "compute_2_to_1", capture_compute_2_to_1) + action = HistoryAction( + title="difference pairwise", + kind=HistoryAction.KIND_COMPUTE, + panel_str=panel.PANEL_STR_ID, + func_name="difference", + pattern="2_to_1", + kwargs={"obj2_uuids": ["recorded-obj2"], "pairwise": True}, + state=WorkspaceState(), + ) + action._replay_compute( # noqa: SLF001 + win, + edit=False, + uuid_remap={panel.PANEL_STR_ID: {"recorded-obj2": obj2_uuid}}, + ) + assert captured["obj2"] is obj2 + assert captured["pairwise"] is True + + # --- scenario: replay_restore_actions(replay=True) on 1_to_1 does NOT add output --- + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.derivative) + deriv_entry = history[len(history)] + _select_tree_item_for(history, deriv_entry) + n_signal_before = len(panel.objmodel) + n_history_before = len(history) + history.replay_restore_actions(replay=True, restore_selection=True) + assert len(panel.objmodel) == n_signal_before + assert len(history) == n_history_before + + +# --------------------------------------------------------------------------- +# 5) Session-level replay (+ reset-starts-new-session) +# --------------------------------------------------------------------------- + + +def test_history_session_replay(): + """Full ``HistorySession.replay`` behaviour + reset/session boundaries.""" + # --- scenario: reset_all starts a new session and preserves history --- + with datalab_test_app_context() as win: + history = win.historypanel + panel = win.signalpanel + win.reset_all() + assert len(history) == 0 + assert _session_action_counts(history) == [] + history.toggle_record_mode(True) + panel.new_object(param=sigima.objects.GaussParam(), edit=False) + assert len(history) == 1 + assert _session_action_counts(history) == [1] + first_title = history[1].title + history.toggle_record_mode(False) + win.reset_all() + assert len(history) == 1 + assert _session_action_counts(history) == [1, 0] + assert history[1].title == first_title + history.toggle_record_mode(True) + panel.new_object(param=sigima.objects.LorentzParam(), edit=False) + assert len(history) == 2 + assert _session_action_counts(history) == [1, 1] + assert history[1].title == first_title + assert history[2].title == _("New signal") + + # --- scenario: full session replay on existing data --- + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) + panel.add_object(create_paracetamol_signal()) + panel.add_object(create_paracetamol_signal()) + assert len(panel.objmodel) == 3 + panel.objview.select_objects([1, 2, 3]) + panel.processor.run_feature(sips.average) + assert len(panel.objmodel) == 4 + session = history.history_sessions[-1] + n_before = len(panel.objmodel) + session.replay(win, restore_selection=False, edit=False) + assert len(panel.objmodel) == n_before + 1 + + # --- scenario: chained compute session replay (output queue remap) --- + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) + panel.add_object(create_paracetamol_signal()) + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.derivative) + panel.objview.select_objects([2]) + panel.processor.run_feature(sips.derivative) + panel.objview.select_objects([3, 4]) + panel.processor.run_feature(sips.average) + assert len(panel.objmodel) == 5 + session = history.history_sessions[-1] + n_before = len(panel.objmodel) + session.replay(win, restore_selection=False, edit=False) + assert len(panel.objmodel) == n_before + 3 + + # --- scenario: direct HistoryAction.replay() does NOT record new entries --- + with datalab_test_app_context() as win: + history = win.historypanel + panel = win.signalpanel + history.toggle_record_mode(True) + panel.new_object(param=NewSignalParam(), edit=False) + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.derivative) + assert len(panel.objmodel) == 2 + session = history.history_sessions[-1] + compute_action = [ + a for a in session.actions if a.kind == HistoryAction.KIND_COMPUTE + ][0] + n_before = sum(len(s.actions) for s in history.history_sessions) + panel.objview.select_objects([1]) + compute_action.replay(win, restore_selection=True, edit=False) + assert sum(len(s.actions) for s in history.history_sessions) == n_before + + # --- scenario: direct HistorySession.replay() does NOT record entries --- + with datalab_test_app_context() as win: + history = win.historypanel + panel = win.signalpanel + history.toggle_record_mode(True) + panel.add_object(create_paracetamol_signal()) + panel.add_object(create_paracetamol_signal()) + panel.objview.select_objects([1, 2]) + panel.processor.run_feature(sips.average) + assert len(panel.objmodel) == 3 + session = history.history_sessions[-1] + n_before = sum(len(s.actions) for s in history.history_sessions) + panel.objview.select_objects([1, 2]) + session.replay(win, restore_selection=False, edit=False) + assert sum(len(s.actions) for s in history.history_sessions) == n_before + + # --- scenario: panel API session replay skips UI-creation, no output --- + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + panel.new_object(param=NewSignalParam(), edit=False) + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.derivative) + session = history.history_sessions[-1] + _select_tree_session(history, session) + n_signal_before = len(panel.objmodel) + n_history_before = len(history) + history.replay_restore_actions(replay=True, restore_selection=True) + assert len(panel.objmodel) == n_signal_before + assert len(history) == n_history_before + + # --- scenario: replay whole session when no tree selection --- + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.derivative) + history.tree.clearSelection() + n_before = len(panel.objmodel) + n_history_before = len(history) + history.replay_restore_actions(replay=True, restore_selection=False) + assert len(panel.objmodel) == n_before + assert len(history) == n_history_before + + # --- scenario: 2_to_1 preserves operand order (primary = #2) --- + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) + panel.add_object(create_paracetamol_signal()) + obj2_for_diff = panel.objmodel.get_object_from_number(1) + panel.objview.select_objects([2]) + panel.processor.run_feature(sips.difference, obj2_for_diff) + assert len(panel.objmodel) == 3 + original_title = panel.objmodel.get_object_from_number(3).title + assert "s002" in original_title and "s001" in original_title + assert original_title.index("s002") < original_title.index("s001") + diff_entry = history[len(history)] + _select_tree_item_for(history, diff_entry) + n_before = len(panel.objmodel) + history.replay_restore_actions(replay=True, restore_selection=True) + assert len(panel.objmodel) == n_before + + # --- scenario: 2_to_1 with primary = #1, obj2 = #2 --- + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) + panel.add_object(create_paracetamol_signal()) + obj2_for_diff = panel.objmodel.get_object_from_number(2) + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.difference, obj2_for_diff) + assert len(panel.objmodel) == 3 + original_title = panel.objmodel.get_object_from_number(3).title + assert "s001" in original_title and "s002" in original_title + assert original_title.index("s001") < original_title.index("s002") + diff_entry = history[len(history)] + _select_tree_item_for(history, diff_entry) + n_before = len(panel.objmodel) + history.replay_restore_actions(replay=True, restore_selection=True) + assert len(panel.objmodel) == n_before + + # --- scenario: 1_to_1 on second signal (derivative on #2) --- + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) + panel.add_object(create_paracetamol_signal()) + panel.objview.select_objects([2]) + panel.processor.run_feature(sips.derivative) + assert len(panel.objmodel) == 3 + original_title = panel.objmodel.get_object_from_number(3).title + assert "s002" in original_title + deriv_entry = history[len(history)] + _select_tree_item_for(history, deriv_entry) + n_before = len(panel.objmodel) + history.replay_restore_actions(replay=True, restore_selection=True) + assert len(panel.objmodel) == n_before + + +# --------------------------------------------------------------------------- +# 6) Duplication +# --------------------------------------------------------------------------- + + +def test_history_duplication(): + """Duplication of actions/sessions + replay of duplicates + ordering.""" + # --- scenario: duplicating an action creates an independent copy --- + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) + param = sigima.params.MovingAverageParam() + param.n = 3 + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.moving_average, param) + original = history[len(history)] + _select_tree_item_for(history, original) + n_before = len(panel.objmodel) + history.duplicate_selected_entries() + sessions = history.history_sessions + duplicate_session = sessions[-1] + duplicate = duplicate_session.actions[0] + assert duplicate_session.title.endswith(_("Copy")) + assert duplicate is not original + assert duplicate.uuid != original.uuid + assert duplicate.kwargs["param"] is not original.kwargs["param"] + duplicate.kwargs["param"].n = 7 + assert original.kwargs["param"].n == 3 + assert duplicate.kwargs["param"].n == 7 + assert len(panel.objmodel) > n_before + + # --- scenario: duplicating a session copies all actions independently --- + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) + param = sigima.params.MovingAverageParam() + param.n = 3 + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.moving_average, param) + original_session = history.history_sessions[-1] + _select_tree_session(history, original_session) + history.duplicate_selected_entries() + sessions = history.history_sessions + duplicate_session = sessions[-1] + assert duplicate_session is not original_session + assert len(duplicate_session.actions) == len(original_session.actions) + assert duplicate_session.title.endswith(_("Copy")) + orig_a = original_session.actions[-1] + dup_a = duplicate_session.actions[-1] + assert dup_a is not orig_a + assert dup_a.kwargs["param"] is not orig_a.kwargs["param"] + + # --- scenario: duplicate clones data AND remaps UUIDs --- + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.derivative) + original_session = history.history_sessions[-1] + _select_tree_session(history, original_session) + n_obj_before = len(panel.objmodel) + n_sessions_before = len(history.history_sessions) + history.duplicate_selected_entries() + sessions = history.history_sessions + assert len(sessions) == n_sessions_before + 1 + dup_session = sessions[-1] + assert dup_session is not original_session + assert dup_session.title.endswith(_("Copy")) + assert len(panel.objmodel) > n_obj_before + for orig_action, dup_action in zip( + original_session.actions, dup_session.actions + ): + for pstr in orig_action.state.selection: + orig_uuids = set(orig_action.state.selection.get(pstr, [])) + dup_uuids = set(dup_action.state.selection.get(pstr, [])) + if orig_uuids and dup_uuids: + assert orig_uuids.isdisjoint(dup_uuids) + + # --- scenario: replay of duplicated session does NOT add output --- + _select_tree_session(history, dup_session) + n_before = len(panel.objmodel) + n_history_before = len(history) + history.replay_restore_actions(replay=True, restore_selection=False) + assert len(panel.objmodel) == n_before + assert len(history) == n_history_before + + # --- scenario: duplicated session preserves topological object order --- + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + _build_cascade_chain(panel, history) + # Extra step so the moving_average output is captured in metadata. + panel.objview.select_objects([4]) + panel.processor.run_feature(sips.derivative) + original_ids = panel.objmodel.get_object_ids() + original_titles = [panel.objmodel[uid].title for uid in original_ids] + assert len(original_titles) >= 3 + sessions = history.history_sessions + _select_tree_session(history, sessions[0]) + history.duplicate_selected_entries() + groups = panel.objmodel.get_groups() + assert len(groups) >= 2 + dup_group_id = get_uuid(groups[-1]) + dup_ids = [ + uid + for uid in panel.objmodel.get_object_ids() + if panel.objmodel.get_object_group_id(panel.objmodel[uid]) == dup_group_id + ] + dup_titles = [panel.objmodel[uid].title for uid in dup_ids] + + def _suffix(title: str) -> str: + parts = title.split("|", 1) + return parts[1].strip() if len(parts) > 1 else title.strip() + + orig_suffixes = [_suffix(t) for t in original_titles] + dup_suffixes = [_suffix(t) for t in dup_titles] + clonable = orig_suffixes[: len(dup_suffixes)] + assert clonable == dup_suffixes + + +# --------------------------------------------------------------------------- +# 7) Stepping + selection sync +# --------------------------------------------------------------------------- + + +def test_history_stepping_and_selection_sync(): + """Step-prev / step-next navigation + tree-to-panel selection sync.""" + # --- scenario: step_next walks forward through current session --- + with datalab_test_app_context() as win: + _panel, history = _record_three_action_session(win) + sessions = history.history_sessions + actions = sessions[-1].actions + assert len(actions) >= 2 + history.tree.clearSelection() + for action in actions: + history.step_next() + current = history.tree.currentItem() + assert current is not None + assert current.data(0, QC.Qt.UserRole) == action.uuid + # End -> no-op. + last_uuid = history.tree.currentItem().data(0, QC.Qt.UserRole) + history.step_next() + assert history.tree.currentItem().data(0, QC.Qt.UserRole) == last_uuid + + # --- scenario: step_prev walks backward through current session --- + _select_tree_item_for(history, actions[-1]) + for expected in reversed(actions[:-1]): + history.step_prev() + current = history.tree.currentItem() + assert current.data(0, QC.Qt.UserRole) == expected.uuid + first_uuid = history.tree.currentItem().data(0, QC.Qt.UserRole) + history.step_prev() + assert history.tree.currentItem().data(0, QC.Qt.UserRole) == first_uuid + + # --- scenario: step button enabled state reflects position --- + with datalab_test_app_context() as win: + history = win.historypanel + prev_btn = history._step_prev_action # noqa: SLF001 + next_btn = history._step_next_action # noqa: SLF001 + history.update_actions_state() + assert not prev_btn.isEnabled() + assert not next_btn.isEnabled() + _panel, history = _record_three_action_session(win) + sessions = history.history_sessions + actions = sessions[-1].actions + prev_btn = history._step_prev_action # noqa: SLF001 + next_btn = history._step_next_action # noqa: SLF001 + _select_tree_item_for(history, actions[0]) + assert not prev_btn.isEnabled() + assert next_btn.isEnabled() + if len(actions) >= 3: + _select_tree_item_for(history, actions[1]) + assert prev_btn.isEnabled() + assert next_btn.isEnabled() + _select_tree_item_for(history, actions[-1]) + assert prev_btn.isEnabled() + assert not next_btn.isEnabled() + + # --- scenario: selecting a compute action selects its output --- + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) + src_uuid = get_uuid(panel.objmodel.get_object_from_number(1)) + panel.objview.select_objects([1]) + panel.processor.run_feature( + sips.normalize, sigima.params.NormalizeParam.create(method="maximum") + ) + out_uuid = get_uuid(panel.objmodel.get_object_from_number(2)) + norm_entry = history[len(history)] + assert norm_entry.func_name == "normalize" + assert src_uuid in norm_entry.state.selection.get("signal", []) + panel.objview.select_objects([src_uuid]) + _select_tree_item_for(history, norm_entry) + assert panel.objview.get_sel_object_uuids() == [out_uuid] + + # --- scenario: deleted output -> selection falls back to input --- + panel.objview.select_objects([2]) + panel.remove_object(force=True) + assert len(panel.objmodel) == 1 + panel.objview.select_groups([1]) + _select_tree_item_for(history, norm_entry) + assert panel.objview.get_sel_object_uuids() == [src_uuid] + + +# --------------------------------------------------------------------------- +# 8) Processing-tab edit propagation + restore-selection-only +# --------------------------------------------------------------------------- + + +def test_history_edit_in_tree(): + """Processing-tab parameter edits propagate into the matching action.""" + # --- scenario: edit updates current session action and refreshes html --- + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + history.toggle_edit_mode(True) + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) + param = sigima.params.GaussianParam.create(sigma=1.5) + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.gaussian_filter, param) + result_obj = panel.objmodel.get_object_from_number(2) + action = history[len(history)] + assert action.func_name == "gaussian_filter" + assert action.kwargs["param"].sigma == 1.5 + html_before = action.description_html + panel.objview.select_objects([2]) + assert panel.objprop.setup_processing_tab(result_obj, reset_params=False) + editor = panel.objprop.processing_param_editor + assert editor is not None + editor.dataset.sigma = 3.5 + report = panel.objprop.apply_processing_parameters( + result_obj, interactive=False + ) + assert report.success + assert action.kwargs["param"].sigma == 3.5 + html_after = action.description_html + assert html_before != html_after + assert "3.5" in html_after + win.historypanel.refresh_action(action) + editor.dataset.sigma = 7.0 + assert action.kwargs["param"].sigma == 3.5 + + # --- scenario: edit does NOT touch a past session --- + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + history.toggle_edit_mode(True) + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) + panel.objview.select_objects([1]) + panel.processor.run_feature( + sips.gaussian_filter, sigima.params.GaussianParam.create(sigma=1.0) + ) + past_action = history[len(history)] + assert past_action.kwargs["param"].sigma == 1.0 + win.reset_all() + panel.add_object(create_paracetamol_signal()) + panel.objview.select_objects([1]) + panel.processor.run_feature( + sips.gaussian_filter, sigima.params.GaussianParam.create(sigma=2.0) + ) + new_obj = panel.objmodel.get_object_from_number(2) + new_action = history[len(history)] + assert new_action is not past_action + found = history.find_action_for_output(get_uuid(new_obj), "gaussian_filter") + assert found is new_action and found is not past_action + panel.objview.select_objects([2]) + assert panel.objprop.setup_processing_tab(new_obj, reset_params=False) + editor = panel.objprop.processing_param_editor + assert editor is not None + editor.dataset.sigma = 4.0 + report = panel.objprop.apply_processing_parameters(new_obj, interactive=False) + assert report.success + assert new_action.kwargs["param"].sigma == 4.0 + assert past_action.kwargs["param"].sigma == 1.0 + + # --- scenario: restore selection only (replay=False) --- + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) + src_uuid = get_uuid(panel.objmodel.get_object_from_number(1)) + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.derivative) + deriv_entry = history[len(history)] + derived = panel.objmodel.get_object_from_number(2) + panel.objview.set_current_object(derived) + derived_uuid = get_uuid(derived) + assert panel.objview.get_sel_object_uuids() == [derived_uuid] + _select_tree_item_for(history, deriv_entry) + n_before = len(panel.objmodel) + history.replay_restore_actions(replay=False, restore_selection=True) + assert len(panel.objmodel) == n_before + assert panel.objview.get_sel_object_uuids() == [src_uuid] + + +# --------------------------------------------------------------------------- +# 9) Cascade recompute +# --------------------------------------------------------------------------- + + +def test_history_cascade_recompute(): + """Downstream detection + cascade recompute + duplicated-session cascade.""" + # --- scenario: downstream detection --- + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + action_A, action_B, action_C, _ob, _oc = _build_cascade_chain(panel, history) + downstream = history.get_downstream_actions(action_A) + assert downstream == [action_B, action_C] + assert history.get_downstream_actions(action_C) == [] + assert history.get_downstream_actions(action_B) == [action_C] + + # --- scenario: cascade recompute updates downstream outputs in place --- + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + history.toggle_edit_mode(True) + panel = win.signalpanel + action_A, action_B, action_C, output_B, output_C = _build_cascade_chain( + panel, history + ) + uuid_B = get_uuid(output_B) + uuid_C = get_uuid(output_C) + data_B_before = output_B.xydata.copy() + data_C_before = output_C.xydata.copy() + n_objects_before = len(panel.objmodel) + result_obj_A = panel.objmodel.get_object_from_number(2) + panel.objview.select_objects([2]) + assert panel.objprop.setup_processing_tab(result_obj_A, reset_params=False) + editor = panel.objprop.processing_param_editor + assert editor is not None + editor.dataset.sigma = 6.0 + report = panel.objprop.apply_processing_parameters( + result_obj_A, interactive=False + ) + assert report.success + assert action_A.kwargs["param"].sigma == 6.0 + assert len(panel.objmodel) == n_objects_before + assert get_uuid(panel.objmodel[uuid_B]) == uuid_B + assert get_uuid(panel.objmodel[uuid_C]) == uuid_C + assert not np.array_equal(panel.objmodel[uuid_B].xydata, data_B_before) + assert not np.array_equal(panel.objmodel[uuid_C].xydata, data_C_before) + for a in (action_A, action_B, action_C): + assert a.is_stale is False + + # --- scenario: play on stale action triggers cascade --- + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + action_A, action_B, _aC, output_B, _oC = _build_cascade_chain(panel, history) + uuid_B = get_uuid(output_B) + output_B.xydata = output_B.xydata * 0.0 + tampered = output_B.xydata.copy() + action_A.is_stale = True + _select_tree_item_for(history, action_A) + history.replay_restore_actions(replay=True, restore_selection=False) + assert action_A.is_stale is False + assert action_B.is_stale is False + assert not np.array_equal(panel.objmodel[uuid_B].xydata, tampered) + + # --- scenario: cascade in a duplicated session that is NOT [-1] --- + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + history.toggle_edit_mode(True) + panel = win.signalpanel + action_A, _aB, _aC, _oB, output_C = _build_cascade_chain(panel, history) + uuid_C_orig = get_uuid(output_C) + data_C_orig = output_C.xydata.copy() + panel.objview.select_objects([4]) + panel.processor.run_feature(sips.derivative) + sessions = history.history_sessions + s1 = sessions[0] + history.create_new_session() + panel.add_object(create_paracetamol_signal()) + panel.objview.select_objects([6]) + panel.processor.run_feature(sips.derivative) + assert len(sessions) == 2 + _select_tree_session(history, s1) + history.duplicate_selected_entries() + assert len(sessions) == 3 + dup_session = sessions[1] + assert sessions[-1] is not dup_session + dup_action_A = next( + a for a in dup_session.actions if a.func_name == action_A.func_name + ) + dup_action_C = next( + a for a in dup_session.actions if a.func_name == "moving_average" + ) + dup_output_C_uuid = history._action_output_uuid(dup_action_C) # noqa: SLF001 + assert dup_output_C_uuid is not None + data_dup_C_before = panel.objmodel[dup_output_C_uuid].xydata.copy() + dup_result_obj_A_uuid = history._action_output_uuid( # noqa: SLF001 + dup_action_A + ) + assert dup_result_obj_A_uuid is not None + dup_result_obj_A = panel.objmodel[dup_result_obj_A_uuid] + panel.objview.select_objects([dup_result_obj_A_uuid]) + assert panel.objprop.setup_processing_tab(dup_result_obj_A, reset_params=False) + editor = panel.objprop.processing_param_editor + assert editor is not None + editor.dataset.sigma = 10.0 + report = panel.objprop.apply_processing_parameters( + dup_result_obj_A, interactive=False + ) + assert report.success + assert not np.array_equal( + panel.objmodel[dup_output_C_uuid].xydata, data_dup_C_before + ) + assert np.array_equal(panel.objmodel[uuid_C_orig].xydata, data_C_orig) + + +# --------------------------------------------------------------------------- +# 10) Chain reconnect after object deletion +# --------------------------------------------------------------------------- + + +def test_history_chain_reconnect(): + """Deleting an intermediate result rewires downstream actions to its source.""" + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) + src_uuid = get_uuid(panel.objmodel.get_object_from_number(1)) + + panel.objview.select_objects([1]) + panel.processor.run_feature( + sips.gaussian_filter, sigima.params.GaussianParam.create(sigma=1.5) + ) + s002_uuid = get_uuid(panel.objmodel.get_object_from_number(2)) + action_gaussian = history[len(history)] + assert action_gaussian.func_name == "gaussian_filter" + + panel.objview.select_objects([2]) + panel.processor.run_feature(sips.derivative) + action_deriv = history[len(history)] + assert action_deriv.func_name == "derivative" + assert s002_uuid in action_deriv.state.selection.get("signal", []) + + panel.objview.select_objects([2]) + panel.remove_object(force=True) + assert len(panel.objmodel) == 2 + + reconnected_uuids = action_deriv.state.selection.get("signal", []) + assert s002_uuid not in reconnected_uuids + assert src_uuid in reconnected_uuids diff --git a/datalab/tests/features/common/interactive_processing_test.py b/datalab/tests/features/common/interactive_processing_test.py index 9ea1351c3..705abec1f 100644 --- a/datalab/tests/features/common/interactive_processing_test.py +++ b/datalab/tests/features/common/interactive_processing_test.py @@ -164,6 +164,10 @@ def test_recompute(): filtered_sig = panel.objview.get_current_object() original_data = filtered_sig.y.copy() + # In-place recompute requires History panel edit mode (otherwise a + # new object is created instead of mutating the existing one). + win.historypanel.toggle_edit_mode(True) + # Recompute with different input signal data constant = 1.23098765 signal.y += constant @@ -402,6 +406,10 @@ def test_apply_processing_parameters_signal(): # Change constant from 5.0 to 15.0 editor.dataset.value = v1 = 15.0 + # In-place update requires History panel edit mode (otherwise a new + # object is created instead of mutating the existing one). + win.historypanel.toggle_edit_mode(True) + # Apply the new processing parameters report = objprop.apply_processing_parameters() @@ -463,6 +471,10 @@ def test_apply_processing_parameters_image(): # Change constant from 7.0 to 20.0 editor.dataset.value = v1 = 20.0 + # In-place update requires History panel edit mode (otherwise a new + # object is created instead of mutating the existing one). + win.historypanel.toggle_edit_mode(True) + # Apply the new processing parameters report = objprop.apply_processing_parameters() @@ -658,6 +670,10 @@ def test_cross_panel_image_to_signal(): editor.dataset.x0 = 40 editor.dataset.y0 = 40 + # In-place update + in-place recompute require History panel edit + # mode (otherwise new objects are created instead of mutating). + win.historypanel.toggle_edit_mode(True) + # Apply the new processing parameters report = signal_panel.objprop.apply_processing_parameters() @@ -1065,6 +1081,10 @@ def test_roi_mask_invalidation_on_processing_change(): editor.dataset.sx = 4 editor.dataset.sy = 4 + # In-place update requires History panel edit mode (otherwise a new + # object is created instead of mutating the existing one). + win.historypanel.toggle_edit_mode(True) + # Apply the new processing parameters report = objprop.apply_processing_parameters(binned) assert report.success diff --git a/datalab/widgets/historydescription.py b/datalab/widgets/historydescription.py new file mode 100644 index 000000000..8fdbd22de --- /dev/null +++ b/datalab/widgets/historydescription.py @@ -0,0 +1,90 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +"""Collapsible description widget used by the History panel.""" + +from __future__ import annotations + +import html + +from qtpy import QtCore as QC +from qtpy import QtWidgets as QW + +from datalab.config import _ + + +class CollapsibleDescriptionWidget(QW.QWidget): + """Compact, expandable cell widget for the history Description column. + + Shows a single-line summary by default; a chevron toggle reveals the full + HTML description (mirroring the *Properties* tab rendering). + """ + + toggled = QC.Signal(bool) + + def __init__( + self, + summary: str, + html_text: str, + expanded: bool = False, + parent: QW.QWidget | None = None, + ) -> None: + super().__init__(parent) + self._summary = summary + self._html = html_text + self._expanded = expanded + + self._toggle = QW.QToolButton(self) + self._toggle.setAutoRaise(True) + self._toggle.setCheckable(True) + self._toggle.setFocusPolicy(QC.Qt.NoFocus) + self._toggle.setArrowType(QC.Qt.RightArrow) + self._toggle.setToolTip(_("Show details")) + + self._label = QW.QLabel(self) + self._label.setTextFormat(QC.Qt.RichText) + self._label.setWordWrap(True) + self._label.setTextInteractionFlags(QC.Qt.TextSelectableByMouse) + self._label.setAlignment(QC.Qt.AlignTop | QC.Qt.AlignLeft) + + layout = QW.QHBoxLayout(self) + layout.setContentsMargins(0, 0, 0, 0) + layout.setSpacing(2) + layout.addWidget(self._toggle, 0, QC.Qt.AlignTop) + layout.addWidget(self._label, 1) + + # Hide the toggle when there is nothing more to show than the summary. + if not self._html or self.html_matches_summary(): + self._toggle.setVisible(False) + + self._toggle.toggled.connect(self.on_toggled) + self.refresh_widget() + + def html_matches_summary(self) -> bool: + """Return True when the HTML rendering would not add information.""" + return self._html.strip() == html.escape(self._summary).strip() + + def on_toggled(self, checked: bool) -> None: + self._expanded = checked + self.refresh_widget() + self.toggled.emit(checked) + + def refresh_widget(self) -> None: + if self._expanded: + self._toggle.setArrowType(QC.Qt.DownArrow) + self._toggle.setToolTip(_("Hide details")) + self._label.setText(self._html or html.escape(self._summary)) + else: + self._toggle.setArrowType(QC.Qt.RightArrow) + self._toggle.setToolTip(_("Show details")) + self._label.setText(html.escape(self._summary)) + self.updateGeometry() + + def is_expanded(self) -> bool: + """Return current expanded state.""" + return self._expanded + + def set_expanded(self, expanded: bool) -> None: + """Programmatically set the expanded state.""" + if expanded == self._expanded: + return + self._toggle.setChecked(expanded) diff --git a/datalab/widgets/historytree.py b/datalab/widgets/historytree.py new file mode 100644 index 000000000..6591285ea --- /dev/null +++ b/datalab/widgets/historytree.py @@ -0,0 +1,249 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +"""History tree widget used by the History panel.""" + +from __future__ import annotations + +from typing import TYPE_CHECKING + +from guidata.configtools import get_icon +from qtpy import QtCore as QC +from qtpy import QtGui as QG +from qtpy import QtWidgets as QW + +from datalab.config import _ +from datalab.history import HistoryAction, HistorySession +from datalab.widgets.historydescription import CollapsibleDescriptionWidget + +if TYPE_CHECKING: + from datalab.gui.main import DLMainWindow + + +class HistoryTree(QW.QTreeWidget): + """Tree widget for the history panel""" + + DESCRIPTION_COLUMN = 2 + COMPATIBILITY_ROLE = QC.Qt.UserRole + 1 + + def __init__(self, parent: QW.QWidget) -> None: + """Create a new history tree widget""" + super().__init__(parent) + self.setHeaderLabels([_("Title"), _("Date and time"), _("Description")]) + self.setContextMenuPolicy(QC.Qt.CustomContextMenu) + self.setSelectionMode(QW.QAbstractItemView.ContiguousSelection) + self.setUniformRowHeights(False) + header = self.header() + header.setSectionResizeMode(self.DESCRIPTION_COLUMN, QW.QHeaderView.Stretch) + # Per-action expanded state, preserved across repopulate (delete/replay). + self.__expanded_state: dict[str, bool] = {} + + def on_description_toggled(self, uuid: str, expanded: bool) -> None: + """Remember the expanded state of a description cell.""" + self.__expanded_state[uuid] = expanded + # Force the tree to recompute row heights now that the label content + # has changed. + self.scheduleDelayedItemsLayout() + + def install_description_widget( + self, item: QW.QTreeWidgetItem, action: HistoryAction + ) -> None: + """Attach the collapsible description widget to ``item`` (column 2). + + The item must already be inserted in the tree before calling this. + """ + expanded = self.__expanded_state.get(action.uuid, False) + widget = CollapsibleDescriptionWidget( + action.description_summary, + action.description_html, + expanded=expanded, + parent=self, + ) + widget.toggled.connect( + lambda checked, uuid=action.uuid: self.on_description_toggled(uuid, checked) + ) + # Clear any text the item may carry for that column to avoid double + # rendering behind the widget. + item.setText(self.DESCRIPTION_COLUMN, "") + self.setItemWidget(item, self.DESCRIPTION_COLUMN, widget) + + @classmethod + def action_to_tree_item(cls, action: HistoryAction) -> QW.QTreeWidgetItem: + """Convert an action to a tree item + + Args: + action: Action to convert + + Returns: + QW.QTreeWidgetItem: Tree item + """ + # Description column is left empty: a CollapsibleDescriptionWidget is + # installed by ``HistoryTree`` once the item is inserted in the tree. + item = QW.QTreeWidgetItem([action.title, action.dtstr, ""]) + item.setData(0, QC.Qt.UserRole, action.uuid) + item.setData(0, cls.COMPATIBILITY_ROLE, True) + return item + + def update_compatibility_states( + self, history_sessions: list[HistorySession], mainwindow: DLMainWindow + ) -> None: + """Update action item visual state from workspace compatibility.""" + default_brush = QG.QBrush() + disabled_brush = QG.QBrush( + self.palette().color(QG.QPalette.Disabled, QG.QPalette.Text) + ) + compatible_tip = _("Action is compatible with the current workspace state.") + incompatible_tip = _( + "Action is not compatible with the current workspace state." + ) + for i in range(self.topLevelItemCount()): + session_item = self.topLevelItem(i) + for j in range(session_item.childCount()): + child = session_item.child(j) + uuid = child.data(0, QC.Qt.UserRole) + action = self.get_action_from_uuid(uuid, history_sessions) + compatible = action.is_current_state_compatible( + mainwindow, restore_selection=True + ) + child.setData(0, self.COMPATIBILITY_ROLE, compatible) + brush = default_brush if compatible else disabled_brush + icon = get_icon("apply.svg") if compatible else get_icon("delete.svg") + child.setIcon(0, icon) + for col in range(self.columnCount()): + child.setForeground(col, brush) + child.setToolTip( + col, compatible_tip if compatible else incompatible_tip + ) + + def forget_orphan_expanded_states( + self, history_sessions: list[HistorySession] + ) -> None: + """Drop expanded-state entries for actions that no longer exist.""" + live_uuids = { + action.uuid for session in history_sessions for action in session.actions + } + self.__expanded_state = { + uuid: state + for uuid, state in self.__expanded_state.items() + if uuid in live_uuids + } + + def populate_tree(self, history_sessions: list[HistorySession]) -> None: + """Populate the history tree widget + + Args: + history_sessions: List of history sessions + """ + self.forget_orphan_expanded_states(history_sessions) + self.clear() + for session in history_sessions: + ritem = QW.QTreeWidgetItem([session.title, session.dtstr]) + ritem.setData(0, self.COMPATIBILITY_ROLE, True) + self.addTopLevelItem(ritem) + for action in session.actions: + child = self.action_to_tree_item(action) + ritem.addChild(child) + self.install_description_widget(child, action) + self.expandAll() + for col in (0, 1): + self.resizeColumnToContents(col) + + def rearrange_tree(self) -> None: + """Rearrange the history tree widget""" + self.expandAll() + for col in (0, 1): + self.resizeColumnToContents(col) + + def add_action_to_tree(self, action: HistoryAction) -> None: + """Add an action to the history tree widget + + Args: + action: Action to add + """ + item = self.action_to_tree_item(action) + ritem = self.topLevelItem(self.topLevelItemCount() - 1) + ritem.addChild(item) + self.install_description_widget(item, action) + + def refresh_action_item(self, action: HistoryAction) -> None: + """Refresh the tree item corresponding to ``action``. + + Re-installs the description widget so it reflects the current + ``action.kwargs`` (e.g. after the user edited a ``param`` via the + Processing tab of the Signal/Image panel). Also applies a light + orange background when ``action.is_stale`` is True, to signal that + the action is currently being recomputed in a cascade. + """ + target_uuid = action.uuid + stale_brush = QG.QBrush(QG.QColor(255, 220, 150)) # light orange + normal_brush = QG.QBrush() + iterator = QW.QTreeWidgetItemIterator(self) + while iterator.value(): + item = iterator.value() + if item.data(0, QC.Qt.UserRole) == target_uuid: + # Remove and re-install the collapsible description widget so + # it reflects the mutated ``action.kwargs``. + self.removeItemWidget(item, self.DESCRIPTION_COLUMN) + self.install_description_widget(item, action) + brush = stale_brush if action.is_stale else normal_brush + for col in range(self.columnCount()): + item.setBackground(col, brush) + self.scheduleDelayedItemsLayout() + return + iterator += 1 + + def get_action_from_uuid( + self, uuid: str, history_sessions: list[HistorySession] + ) -> HistoryAction: + """Get the action from its UUID + + Args: + uuid: Action UUID + history_sessions: List of history sessions + + Returns: + HistoryAction: Action + """ + for session in history_sessions: + for action in session.actions: + if action.uuid == uuid: + return action + raise ValueError("Action not found") + + def get_selected_actions_or_sessions( + self, history_sessions: list[HistorySession] + ) -> list[HistoryAction | HistorySession]: + """Get the selected actions or sessions + + Args: + history_sessions: List of history sessions + + Returns: + list[HistoryAction | HistorySession]: List of selected actions or sessions + """ + selected: list[HistoryAction | HistorySession] = [] + for item in self.selectedItems(): + if item.parent() is None: + index = self.indexOfTopLevelItem(item) + selected.append(history_sessions[index]) + else: + uuid = item.data(0, QC.Qt.UserRole) + selected.append(self.get_action_from_uuid(uuid, history_sessions)) + return selected + + def get_selected_actions( + self, history_sessions: list[HistorySession] + ) -> list[HistoryAction]: + """Get the selected actions + + Args: + history_sessions: List of history sessions + + Returns: + list[HistoryAction]: List of selected actions + """ + selected: list[HistoryAction] = [] + for item in self.selectedItems(): + if item.parent() is not None: + uuid = item.data(0, QC.Qt.UserRole) + selected.append(self.get_action_from_uuid(uuid, history_sessions)) + return selected diff --git a/datalab/widgets/workspacestate_widget.py b/datalab/widgets/workspacestate_widget.py new file mode 100644 index 000000000..50b81c9e8 --- /dev/null +++ b/datalab/widgets/workspacestate_widget.py @@ -0,0 +1,82 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +"""Workspace state display widget used by the History panel.""" + +from __future__ import annotations + +from typing import TYPE_CHECKING + +from qtpy import QtCore as QC +from qtpy import QtWidgets as QW + +from datalab.config import _ + +if TYPE_CHECKING: + from datalab.history import WorkspaceState + + +class WorkspaceStateWidget(QW.QWidget): + """Side-by-side tables showing the workspace state captured by a history action. + + Left table: signals (title + data shape). + Right table: images (title + data shape/dimensions). + """ + + def __init__(self, parent: QW.QWidget | None = None) -> None: + super().__init__(parent) + self._signal_table = QW.QTableWidget(0, 2, self) + self._signal_table.setHorizontalHeaderLabels([_("Signal"), _("Shape")]) + self._signal_table.horizontalHeader().setStretchLastSection(True) + self._signal_table.setEditTriggers(QW.QAbstractItemView.NoEditTriggers) + self._signal_table.setSelectionMode(QW.QAbstractItemView.NoSelection) + self._signal_table.verticalHeader().hide() + + self._image_table = QW.QTableWidget(0, 2, self) + self._image_table.setHorizontalHeaderLabels([_("Image"), _("Dimensions")]) + self._image_table.horizontalHeader().setStretchLastSection(True) + self._image_table.setEditTriggers(QW.QAbstractItemView.NoEditTriggers) + self._image_table.setSelectionMode(QW.QAbstractItemView.NoSelection) + self._image_table.verticalHeader().hide() + + splitter = QW.QSplitter(QC.Qt.Horizontal, self) + splitter.addWidget(self._signal_table) + splitter.addWidget(self._image_table) + layout = QW.QVBoxLayout(self) + layout.setContentsMargins(0, 0, 0, 0) + layout.addWidget(splitter) + + def update_from_state(self, state: WorkspaceState | None) -> None: + """Populate tables from a WorkspaceState.""" + self._signal_table.setRowCount(0) + self._image_table.setRowCount(0) + if state is None: + return + self.populate_table(self._signal_table, state, "signal") + self.populate_table(self._image_table, state, "image") + + @staticmethod + def populate_table( + table: QW.QTableWidget, state: WorkspaceState, panel_key: str + ) -> None: + """Fill a table from the state for a given panel key.""" + titles = state.titles.get(panel_key, []) + shapes = state.states.get(panel_key, []) + metadata = state.object_metadata.get(panel_key, {}) + uuids = state.selection.get(panel_key, []) + # Use metadata keyed by UUID when available + rows: list[tuple[str, str]] = [] + for i, uuid in enumerate(uuids): + title = titles[i] if i < len(titles) else uuid[:8] + meta = metadata.get(uuid, {}) + shape = meta.get("shape") + if shape is not None: + shape_str = " × ".join(str(s) for s in shape) + elif i < len(shapes): + shape_str = shapes[i] + else: + shape_str = "—" + rows.append((title, shape_str)) + table.setRowCount(len(rows)) + for row_idx, (title, shape_str) in enumerate(rows): + table.setItem(row_idx, 0, QW.QTableWidgetItem(title)) + table.setItem(row_idx, 1, QW.QTableWidgetItem(shape_str)) From 5cc3091950ce26fe6986bff927661213bb4e1974 Mon Sep 17 00:00:00 2001 From: Thomas MALLET <t.mallet@codra.fr> Date: Wed, 24 Jun 2026 16:26:31 +0200 Subject: [PATCH 022/108] run ruff linter and fix warnings --- datalab/gui/panel/base.py | 4 +--- datalab/gui/panel/history/recompute.py | 1 - datalab/gui/processor/base.py | 10 +++------- datalab/history/core.py | 4 +++- datalab/tests/features/common/history_test.py | 2 +- 5 files changed, 8 insertions(+), 13 deletions(-) diff --git a/datalab/gui/panel/base.py b/datalab/gui/panel/base.py index 810d75d2e..46e46de97 100644 --- a/datalab/gui/panel/base.py +++ b/datalab/gui/panel/base.py @@ -213,9 +213,7 @@ def __init__(self, panel: BaseDataPanel, objclass: SignalObj | ImageObj) -> None self.__auto_recompute_enabled: bool = False self.__auto_recompute_timer = QC.QTimer(self) self.__auto_recompute_timer.setSingleShot(True) - self.__auto_recompute_timer.timeout.connect( - self.__auto_recompute_trigger - ) + self.__auto_recompute_timer.timeout.connect(self.__auto_recompute_trigger) # Properties tab self.properties = gdq.DataSetEditGroupBox("", objclass) diff --git a/datalab/gui/panel/history/recompute.py b/datalab/gui/panel/history/recompute.py index 308d34e58..8016f5d1e 100644 --- a/datalab/gui/panel/history/recompute.py +++ b/datalab/gui/panel/history/recompute.py @@ -7,7 +7,6 @@ import logging from typing import TYPE_CHECKING -from coverage.debug import pp from qtpy import QtWidgets as QW from sigima.objects import ImageObj, SignalObj diff --git a/datalab/gui/processor/base.py b/datalab/gui/processor/base.py index 2cae348f4..dec384ffb 100644 --- a/datalab/gui/processor/base.py +++ b/datalab/gui/processor/base.py @@ -1,4 +1,4 @@ -# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. """ .. Base processor object (see parent package :mod:`datalab.gui.processor`) @@ -1510,9 +1510,7 @@ def recompute_1_to_0( ) historypanel = self.mainwindow.historypanel with historypanel.replaying(), Conf.proc.show_result_dialog.temp(False): - self.compute_1_to_0( - feature.function, param, edit=False, target_objs=[obj] - ) + self.compute_1_to_0(feature.function, param, edit=False, target_objs=[obj]) def _compute_1_to_1_subroutine( self, funcs: list[Callable], params: list, title: str @@ -1743,9 +1741,7 @@ def compute_multiple_1_to_1( panel_str=self.panel.PANEL_STR_ID, func_names=[f.__name__ for f in funcs], params=params if any(p is not None for p in params) else None, - plugin_origin=( - self._get_plugin_origin_for(funcs[0]) if funcs else None - ), + plugin_origin=(self._get_plugin_origin_for(funcs[0]) if funcs else None), ) with self.mainwindow.historypanel.capture_outputs(action): self._compute_1_to_1_subroutine(funcs, params, title) diff --git a/datalab/history/core.py b/datalab/history/core.py index 9ac7b3fcb..07ec11a4d 100644 --- a/datalab/history/core.py +++ b/datalab/history/core.py @@ -1,6 +1,8 @@ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. -"""History core utilities: schema constants, JSON codec, ``@add_to_history`` decorator.""" +""" +History core utilities: schema constants, JSON codec, ``@add_to_history`` decorator. +""" from __future__ import annotations diff --git a/datalab/tests/features/common/history_test.py b/datalab/tests/features/common/history_test.py index 6d03bf29a..be259cc4b 100644 --- a/datalab/tests/features/common/history_test.py +++ b/datalab/tests/features/common/history_test.py @@ -837,7 +837,7 @@ def capture_compute_2_to_1(obj2_arg, *_args, **kwargs): assert captured["obj2"] is obj2 assert captured["pairwise"] is True - # --- scenario: replay_restore_actions(replay=True) on 1_to_1 does NOT add output --- + # scenario: replay_restore_actions(replay=True) on 1_to_1 does NOT add output with datalab_test_app_context() as win: history = win.historypanel history.toggle_record_mode(True) From 8b88420b439cc369bb05f8c31a1f5bda98e2e589 Mon Sep 17 00:00:00 2001 From: Thomas MALLET <t.mallet@codra.fr> Date: Wed, 24 Jun 2026 16:40:49 +0200 Subject: [PATCH 023/108] fix translations after merge --- datalab/locale/fr/LC_MESSAGES/datalab.po | 129 ++--- .../features/common/historypanel.po | 531 ++++-------------- .../LC_MESSAGES/release_notes/release_1.03.po | 6 - 3 files changed, 135 insertions(+), 531 deletions(-) diff --git a/datalab/locale/fr/LC_MESSAGES/datalab.po b/datalab/locale/fr/LC_MESSAGES/datalab.po index 92d14a7e6..223581775 100644 --- a/datalab/locale/fr/LC_MESSAGES/datalab.po +++ b/datalab/locale/fr/LC_MESSAGES/datalab.po @@ -1,6 +1,6 @@ -# French translations for DataLab. +# French translations for datalab. # Copyright (C) 2026 DataLab Platform Developers -# This file is distributed under the same license as the DataLab project. +# This file is distributed under the same license as the datalab project. # msgid "" msgstr "" @@ -940,6 +940,15 @@ msgstr "Afficher le panneau de contraste" msgid "Show or hide contrast adjustment panel" msgstr "Afficher ou cacher le panneau de réglage du contraste" +msgid "Command palette" +msgstr "Palette de commandes" + +msgid "Type to search for a command…" +msgstr "Tapez pour rechercher une commande…" + +msgid "Search a command…" +msgstr "Rechercher une commande…" + msgid "Process signal" msgstr "Traiter le signal" @@ -1044,7 +1053,7 @@ msgstr "Ignorer ce message empêchera son affichage ultérieur." msgid "Plugins" msgstr "Plugins" -msgid "Third-party plugins are disabled. Enable them in the Settings dialog to use this feature." +msgid "Third-party plugins are disabled. Enable them again from the plugin configuration dialog to use this feature." msgstr "Les plugins tiers sont désactivés. Activez-les dans la boîte de dialogue des préférences pour utiliser cette fonctionnalité." #, python-format @@ -1075,18 +1084,9 @@ msgstr "Préférences..." msgid "Open settings dialog" msgstr "Ouvrir la boîte de dialogue des préférences" -msgid "Command palette" -msgstr "Palette de commandes" - msgid "Command palette..." msgstr "Palette de commandes..." -msgid "Search a command…" -msgstr "Rechercher une commande…" - -msgid "Type to search for a command…" -msgstr "Tapez pour rechercher une commande…" - msgid "Search and run any command by its menu path" msgstr "Rechercher et exécuter n'importe quelle commande par son chemin de menu" @@ -1398,9 +1398,6 @@ msgstr "Paramètres pour la fonction `%s`" msgid "Created" msgstr "Créé" -msgid "Created" -msgstr "Créé" - msgid "Original object" msgstr "Objet original" @@ -1872,12 +1869,6 @@ msgstr "Fichiers Python" msgid "Clear console" msgstr "Effacer la console" -msgid "Python files" -msgstr "Fichiers Python" - -msgid "Clear console" -msgstr "Effacer la console" - msgid "-***- Macro Console -***-" msgstr "-***- Console des macros -***-" @@ -1993,30 +1984,30 @@ msgstr "Modifier le répertoire" msgid "Remove directory" msgstr "Supprimer le répertoire" +msgid "from" +msgstr "depuis" + msgid "Plugin Configuration" msgstr "Configuration des plugins" msgid "Enable/disable plugins" msgstr "Activer/désactiver les plugins" -msgid "Plugin search paths" -msgstr "Chemins de recherche des plugins" +msgid "Plugin settings" +msgstr "Paramètres des plugins" msgid "Apply and reload plugins" msgstr "Appliquer et recharger les plugins" +msgid "Third-party plugins are globally disabled." +msgstr "Les plugins tiers sont désactivés globalement." + msgid "Changes will be applied after clicking OK and reloading plugins." msgstr "Les modifications seront appliquées après avoir cliqué sur OK et rechargé les plugins." msgid "The following directories are scanned at startup for plugins:" msgstr "Les répertoires suivants sont analysés au démarrage pour détecter les plugins :" -msgid "from" -msgstr "depuis" - -msgid "from" -msgstr "depuis" - msgid "Default plugin directories" msgstr "Répertoires de plugins par défaut" @@ -2036,6 +2027,15 @@ msgstr "Aucun répertoire de plugins supplémentaire n'est configuré." msgid "Directories provided via the <code>%s</code> environment variable (multiple paths separated by '<code>%s</code>') also appear above as read-only entries. Changes take effect at DataLab startup." msgstr "Les répertoires fournis via la variable d'environnement <code>%s</code> (plusieurs chemins séparés par '<code>%s</code>') apparaissent également ci-dessus en lecture seule. Les modifications prennent effet au démarrage de DataLab." +msgid "Compatibility warnings" +msgstr "Avertissements de compatibilité" + +msgid "Hide warnings for incompatible DataLab v0.20 plugins" +msgstr "Masquer les avertissements pour les plugins DataLab v0.20 incompatibles" + +msgid "If enabled, DataLab will not warn you about v0.20 plugins that are no longer compatible with v1.0." +msgstr "Si activé, DataLab ne vous avertira pas des plugins v0.20 qui ne sont plus compatibles avec v1.0." + msgid "Select plugin directory" msgstr "Sélectionner un répertoire de plugins" @@ -2057,32 +2057,17 @@ msgstr "Plugins désactivés" msgid "Plugins with errors" msgstr "Plugins en erreur" -msgid "Reload Plugins" -msgstr "Recharger les plugins" - -msgid "Plugin configuration has been saved. Do you want to reload plugins now to apply changes?" -msgstr "La configuration des plugins a été enregistrée. Voulez-vous recharger les plugins maintenant pour appliquer les modifications ?" - -msgid "Plugin settings" -msgstr "Paramètres des plugins" - -msgid "Third-party plugins are globally disabled." -msgstr "Les plugins tiers sont désactivés globalement." - -msgid "Compatibility warnings" -msgstr "Avertissements de compatibilité" - -msgid "Hide warnings for incompatible DataLab v0.20 plugins" -msgstr "Masquer les avertissements pour les plugins DataLab v0.20 incompatibles" - msgid "Disable plugins globally" msgstr "Désactiver globalement les plugins" msgid "Enable plugins globally" msgstr "Activer globalement les plugins" -msgid "Enable them again from the plugin configuration dialog to use this feature." -msgstr "Réactivez-les depuis la boîte de dialogue de configuration des plugins pour utiliser cette fonctionnalité." +msgid "Reload Plugins" +msgstr "Recharger les plugins" + +msgid "Plugin configuration has been saved. Do you want to reload plugins now to apply changes?" +msgstr "La configuration des plugins a été enregistrée. Voulez-vous recharger les plugins maintenant pour appliquer les modifications ?" msgid "Failed to deserialize processing parameters from JSON." msgstr "Échec de la désérialisation des paramètres de traitement depuis le format JSON." @@ -2941,21 +2926,6 @@ msgstr "Mo" msgid "Memory threshold below which a warning is displayed before loading any new data" msgstr "Seuil de mémoire en dessous duquel un avertissement est affiché avant de charger de nouvelles données" -msgid "Third-party plugins" -msgstr "Plugins tiers" - -msgid "Enable or disable third-party plugins immediately. Changes are applied without restarting DataLab" -msgstr "Activer ou désactiver immédiatement les plugins tiers. Les changements sont appliqués sans redémarrer DataLab" - -msgid "Ignore compatibility issues warning" -msgstr "Ignorer l'avertissement de compatibilité" - -msgid "DataLab v0.20 plugins" -msgstr "Plugins DataLab v0.20" - -msgid "If enabled, DataLab will not warn you about v0.20 plugins that are no longer compatible with v1.0." -msgstr "Si activé, DataLab ne vous avertira pas des plugins v0.20 qui ne sont plus compatibles avec v1.0." - msgid "Settings for internal console, used for debugging or advanced users" msgstr "Réglages de la console interne, utilisée pour le débogage ou les utilisateurs avancés" @@ -3523,9 +3493,6 @@ msgstr "Créer une image avec un anneau" msgid "Create image with a grid of gaussian spots" msgstr "Créer une image avec une grille de spots gaussiens" -msgid "New signal" -msgstr "Nouveau signal" - msgid "Host application" msgstr "Application hôte" @@ -3877,30 +3844,12 @@ msgstr "Afficher les détails" msgid "Hide details" msgstr "Masquer les détails" -msgid "Date and time" -msgstr "Date et heure" - msgid "Title" msgstr "Titre" -msgid "Action is compatible with the current workspace state." -msgstr "L'action est compatible avec l'état actuel de l'espace de travail." - -msgid "Action is not compatible with the current workspace state." -msgstr "L'action n'est pas compatible avec l'état actuel de l'espace de travail." - -msgid "Show details" -msgstr "Afficher les détails" - -msgid "Hide details" -msgstr "Masquer les détails" - msgid "Date and time" msgstr "Date et heure" -msgid "Title" -msgstr "Titre" - msgid "Action is compatible with the current workspace state." msgstr "L'action est compatible avec l'état actuel de l'espace de travail." @@ -3949,6 +3898,9 @@ msgstr "±{n} points" msgid "±{n} rows × ±{n} columns" msgstr "±{n} lignes × ±{n} colonnes" +msgid "This image uses an integer data type, so it cannot contain NaN or infinite values. Replace special values is therefore not applicable." +msgstr "Cette image utilise un type de données entier, elle ne peut donc pas contenir de valeurs NaN ou infinies. Le remplacement des valeurs spéciales n'est donc pas applicable." + msgid "Signal baseline selection" msgstr "Sélection de la ligne de base du signal" @@ -3976,9 +3928,6 @@ msgstr "Détection de pics 1D" msgid "Peaks:" msgstr "Pics :" -msgid "Peaks:" -msgstr "Pics :" - msgid "Internal console" msgstr "Console interne" @@ -4293,9 +4242,6 @@ msgstr "Image" msgid "Dimensions" msgstr "Dimensions" -msgid "This image uses an integer data type, so it cannot contain NaN or infinite values. Replace special values is therefore not applicable." -msgstr "Cette image utilise un type de données entier, elle ne peut donc pas contenir de valeurs NaN ou infinies. Le remplacement des valeurs spéciales n'est donc pas applicable." - msgid "Minimum value" msgstr "Valeur minimum" @@ -4344,4 +4290,3 @@ msgstr "Aucun contour n'a été trouvé pour la plage de niveaux sélectionnée. msgid "Show contour plot..." msgstr "Afficher le tracé de contours..." - diff --git a/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po b/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po index 8183e3c0c..daf1be0d6 100644 --- a/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po +++ b/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po @@ -5,32 +5,17 @@ # msgid "" msgstr "" -"Project-Id-Version: DataLab \n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-02 15:49+0200\n" -"PO-Revision-Date: 2026-05-16 11:35+0200\n" -"Last-Translator: DataLab Platform Developers\n" "Language: fr\n" -"Language-Team: fr <LL@li.org>\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.18.0\n" -msgid "" -"History Panel in DataLab, the open-source scientific data analysis and " -"visualization platform" -msgstr "" -"Panneau historique de DataLab, la plateforme open-source d'analyse et de " -"visualisation de données scientifiques" +msgid "History Panel in DataLab, the open-source scientific data analysis and visualization platform" +msgstr "Panneau historique de DataLab, la plateforme open-source d'analyse et de visualisation de données scientifiques" -msgid "" -"DataLab, history, record, replay, session, scientific, data, analysis, " -"visualization, platform" -msgstr "" -"DataLab, historique, enregistrement, rejeu, session, scientifique, " -"données, analyse, visualisation, plateforme" +msgid "DataLab, history, record, replay, session, scientific, data, analysis, visualization, platform" +msgstr "DataLab, historique, enregistrement, rejeu, session, scientifique, données, analyse, visualisation, plateforme" msgid "History Panel" msgstr "Panneau historique" @@ -38,74 +23,32 @@ msgstr "Panneau historique" msgid "Overview" msgstr "Vue d'ensemble" -msgid "" -"The \"History Panel\" records the sequence of actions performed by the " -"user on signals and images, organized into **sessions**. Each session is " -"a chronological list of either:" -msgstr "" -"Le « Panneau historique » enregistre la séquence des actions effectuées " -"par l'utilisateur sur les signaux et les images, organisée en " -"**sessions**. Chaque session est une liste chronologique constituée soit " -":" +msgid "The \"History Panel\" records the sequence of actions performed by the user on signals and images, organized into **sessions**. Each session is a chronological list of either:" +msgstr "Le « Panneau historique » enregistre la séquence des actions effectuées par l'utilisateur sur les signaux et les images, organisée en **sessions**. Chaque session est une liste chronologique constituée soit :" -msgid "" -"**UI actions** (creating a new signal, removing selected objects, saving " -"the workspace to HDF5, ...), or" -msgstr "" -"d'**actions de l'interface** (création d'un nouveau signal, suppression " -"des objets sélectionnés, enregistrement de l'espace de travail au format " -"HDF5, ...), soit" +msgid "**UI actions** (creating a new signal, removing selected objects, saving the workspace to HDF5, ...), or" +msgstr "d'**actions de l'interface** (création d'un nouveau signal, suppression des objets sélectionnés, enregistrement de l'espace de travail au format HDF5, ...), soit" -msgid "" -"**computations** (FFT, average, Gaussian fit, ...) dispatched through the" -" Sigima processor." -msgstr "" -"de **calculs** (FFT, moyenne, ajustement gaussien, ...) exécutés via le " -"processeur Sigima." +msgid "**computations** (FFT, average, Gaussian fit, ...) dispatched through the Sigima processor." +msgstr "de **calculs** (FFT, moyenne, ajustement gaussien, ...) exécutés via le processeur Sigima." msgid "A recorded session can be:" msgstr "Une session enregistrée peut être :" -msgid "" -"**Replayed** in validation mode, without adding new signal/image outputs " -"to the workspace;" -msgstr "" -"**rejouée** en mode validation, sans ajouter de nouvelles sorties " -"signal/image à l'espace de travail ;" +msgid "**Replayed** in validation mode, without adding new signal/image outputs to the workspace;" +msgstr "**rejouée** en mode validation, sans ajouter de nouvelles sorties signal/image à l'espace de travail ;" -msgid "" -"**Duplicated and applied**, to create an explicit comparison branch with " -"new outputs in the signal/image panels;" -msgstr "" -"**dupliquée et appliquée**, afin de créer une branche de comparaison " -"explicite avec de nouvelles sorties dans les panneaux signal/image ;" +msgid "**Duplicated and applied**, to create an explicit comparison branch with new outputs in the signal/image panels;" +msgstr "**dupliquée et appliquée**, afin de créer une branche de comparaison explicite avec de nouvelles sorties dans les panneaux signal/image ;" -msgid "" -"**Restored to a given selection state** without re-executing anything, to" -" quickly jump back to a previous working context;" -msgstr "" -"**restaurée dans un état de sélection donné** sans rien réexécuter, afin " -"de revenir rapidement à un contexte de travail antérieur ;" +msgid "**Restored to a given selection state** without re-executing anything, to quickly jump back to a previous working context;" +msgstr "**restaurée dans un état de sélection donné** sans rien réexécuter, afin de revenir rapidement à un contexte de travail antérieur ;" -msgid "" -"**Saved to a standalone history file** (``.dlhist``) or **embedded in the" -" workspace** when saving to HDF5, so that the full processing chain " -"travels with the data." -msgstr "" -"**sauvegardée dans un fichier d'historique autonome** (``.dlhist``) ou " -"**intégrée à l'espace de travail** lors de l'enregistrement au format " -"HDF5, de sorte que toute la chaîne de traitement accompagne les données." +msgid "**Saved to a standalone history file** (``.dlhist``) or **embedded in the workspace** when saving to HDF5, so that the full processing chain travels with the data." +msgstr "**sauvegardée dans un fichier d'historique autonome** (``.dlhist``) ou **intégrée à l'espace de travail** lors de l'enregistrement au format HDF5, de sorte que toute la chaîne de traitement accompagne les données." -msgid "" -"The History Panel after recording a representative session: create three " -"signals (Voigt, Lorentzian, Lorentzian), remove one of them, create a " -"Gaussian signal, compute the average, add Gaussian noise to the result " -"and run a Gaussian fit." -msgstr "" -"Le Panneau historique après l'enregistrement d'une session représentative" -" : création de trois signaux (Voigt, lorentzien, lorentzien), suppression" -" de l'un d'eux, création d'un signal gaussien, calcul de la moyenne, " -"ajout d'un bruit gaussien au résultat et ajustement par une gaussienne." +msgid "The History Panel after recording a representative session: create three signals (Voigt, Lorentzian, Lorentzian), remove one of them, create a Gaussian signal, compute the average, add Gaussian noise to the result and run a Gaussian fit." +msgstr "Le Panneau historique après l'enregistrement d'une session représentative : création de trois signaux (Voigt, lorentzien, lorentzien), suppression de l'un d'eux, création d'un signal gaussien, calcul de la moyenne, ajout d'un bruit gaussien au résultat et ajustement par une gaussienne." msgid "Toolbar" msgstr "Barre d'outils" @@ -113,276 +56,131 @@ msgstr "Barre d'outils" msgid "The toolbar at the top of the panel exposes the following actions:" msgstr "La barre d'outils en haut du panneau expose les actions suivantes :" -msgid "" -"|record| **Record mode**: toggle the recording of new actions. When off, " -"no new entry is added to the history (existing sessions are preserved)." -msgstr "" -"|record| **Mode enregistrement** : active ou désactive l'enregistrement " -"des nouvelles actions. Lorsqu'il est désactivé, aucune nouvelle entrée " -"n'est ajoutée à l'historique (les sessions existantes sont conservées)." +msgid "|record| **Record mode**: toggle the recording of new actions. When off, no new entry is added to the history (existing sessions are preserved)." +msgstr "|record| **Mode enregistrement** : active ou désactive l'enregistrement des nouvelles actions. Lorsqu'il est désactivé, aucune nouvelle entrée n'est ajoutée à l'historique (les sessions existantes sont conservées)." msgid "record" msgstr "record" -msgid "" -"|open_history| **Open history file**: load recorded sessions from a " -"standalone ``.dlhist`` file." -msgstr "" -"|open_history| **Ouvrir un fichier d'historique** : charge des sessions " -"enregistrées depuis un fichier ``.dlhist`` autonome." +msgid "|open_history| **Open history file**: load recorded sessions from a standalone ``.dlhist`` file." +msgstr "|open_history| **Ouvrir un fichier d'historique** : charge des sessions enregistrées depuis un fichier ``.dlhist`` autonome." msgid "open_history" msgstr "open_history" -msgid "" -"|save_history| **Save history file**: save the current recorded sessions " -"to a standalone ``.dlhist`` file." -msgstr "" -"|save_history| **Enregistrer le fichier d'historique** : enregistre les " -"sessions actuellement enregistrées dans un fichier ``.dlhist`` autonome." +msgid "|save_history| **Save history file**: save the current recorded sessions to a standalone ``.dlhist`` file." +msgstr "|save_history| **Enregistrer le fichier d'historique** : enregistre les sessions actuellement enregistrées dans un fichier ``.dlhist`` autonome." msgid "save_history" msgstr "save_history" -msgid "" -"|replay| **Replay**: validate/replay the selected action (or the whole " -"session if a session row is selected) without changing the current " -"workspace selection beforehand and without adding new outputs to the " -"signal/image panels." -msgstr "" -"|replay| **Rejouer** : valide/rejoue l'action sélectionnée (ou la session" -" entière si une ligne de session est sélectionnée) sans modifier au " -"préalable la sélection courante de l'espace de travail et sans ajouter de" -" nouvelles sorties aux panneaux signal/image." +msgid "|replay| **Replay**: validate/replay the selected action (or the whole session if a session row is selected) without changing the current workspace selection beforehand and without adding new outputs to the signal/image panels." +msgstr "|replay| **Rejouer** : valide/rejoue l'action sélectionnée (ou la session entière si une ligne de session est sélectionnée) sans modifier au préalable la sélection courante de l'espace de travail et sans ajouter de nouvelles sorties aux panneaux signal/image." msgid "replay" msgstr "replay" -msgid "" -"|restore_selection| **Restore selection**: only re-select the objects " -"that were selected when the action was originally executed; no " -"computation is re-run." -msgstr "" -"|restore_selection| **Restaurer la sélection** : ré-sélectionne " -"uniquement les objets qui étaient sélectionnés lors de l'exécution " -"initiale de l'action ; aucun calcul n'est ré-exécuté." +msgid "|restore_selection| **Restore selection**: only re-select the objects that were selected when the action was originally executed; no computation is re-run." +msgstr "|restore_selection| **Restaurer la sélection** : ré-sélectionne uniquement les objets qui étaient sélectionnés lors de l'exécution initiale de l'action ; aucun calcul n'est ré-exécuté." msgid "restore_selection" msgstr "restore_selection" -msgid "" -"|edit_mode| **Edit mode**: when on, replaying a computation opens the " -"parameters dialog so the user can tweak the parameters before re-running." -msgstr "" -"|edit_mode| **Mode édition** : lorsqu'il est activé, rejouer un calcul " -"ouvre la boîte de dialogue des paramètres afin que l'utilisateur puisse " -"les ajuster avant de relancer l'exécution." +msgid "|edit_mode| **Edit mode**: when on, replaying a computation opens the parameters dialog so the user can tweak the parameters before re-running. When replaying a *whole session*, the parameter dialogs open in a **read-only** mode — all fields are shown with their recorded values but cannot be edited." +msgstr "|edit_mode| **Mode édition** : lorsqu'il est activé, le rejeu d'un calcul ouvre la boîte de dialogue des paramètres afin que l'utilisateur puisse ajuster les paramètres avant de relancer. Lors du rejeu d'une *session entière*, les boîtes de dialogue des paramètres s'ouvrent en mode **lecture seule** — tous les champs affichent les valeurs enregistrées mais ne peuvent pas être édités." msgid "edit_mode" msgstr "edit_mode" -msgid "" -"|duplicate| **Duplicate**: copy the selected action or session into a new" -" history session. The copied parameters are independent from the original" -" record." -msgstr "" -"|duplicate| **Dupliquer** : copie l'action ou la session sélectionnée " -"dans une nouvelle session d'historique. Les paramètres copiés sont " -"indépendants de l'enregistrement d'origine." +msgid "|duplicate| **Duplicate**: copy the selected action or session into a new history session. The copied parameters are independent from the original record." +msgstr "|duplicate| **Dupliquer** : copie l'action ou la session sélectionnée dans une nouvelle session d'historique. Les paramètres copiés sont indépendants de l'enregistrement d'origine." msgid "duplicate" msgstr "duplicate" -msgid "" -"|generate_macro| **Generate macro**: generate a Python macro script from " -"the selected actions (or all actions if nothing is selected). The " -"generated script is copied to the clipboard." -msgstr "" -"|generate_macro| **Générer une macro** : génère un script macro Python à " -"partir des actions sélectionnées (ou de toutes les actions si rien n'est " -"sélectionné). Le script généré est copié dans le presse-papiers." +msgid "|generate_macro| **Generate macro**: generate a Python macro script from the selected actions (or all actions if nothing is selected). The generated script is copied to the clipboard." +msgstr "|generate_macro| **Générer une macro** : génère un script macro Python à partir des actions sélectionnées (ou de toutes les actions si rien n'est sélectionné). Le script généré est copié dans le presse-papiers." msgid "generate_macro" msgstr "generate_macro" -msgid "" -"|remove_incompatible| **Remove incompatible**: remove all actions whose " -"workspace state is no longer compatible with the current workspace. A " -"confirmation dialog shows how many actions will be removed." -msgstr "" -"|remove_incompatible| **Supprimer les incompatibles** : supprime toutes " -"les actions dont l'état de l'espace de travail n'est plus compatible avec " -"l'espace de travail actuel. Une boîte de dialogue de confirmation indique " -"combien d'actions seront supprimées." +msgid "|remove_incompatible| **Remove incompatible**: remove all actions whose workspace state is no longer compatible with the current workspace. A confirmation dialog shows how many actions will be removed." +msgstr "|remove_incompatible| **Supprimer les incompatibles** : supprime toutes les actions dont l'état de l'espace de travail n'est plus compatible avec l'espace de travail actuel. Une boîte de dialogue de confirmation indique combien d'actions seront supprimées." msgid "remove_incompatible" msgstr "remove_incompatible" -msgid "" -"|delete| **Delete**: remove the selected actions or sessions from the " -"history." -msgstr "" -"|delete| **Supprimer** : retire de l'historique les actions ou sessions " -"sélectionnées." +msgid "|delete| **Delete**: remove the selected actions or sessions from the history." +msgstr "|delete| **Supprimer** : retire de l'historique les actions ou sessions sélectionnées." msgid "delete" msgstr "delete" -msgid "" -"|step_prev| **Previous step**: select the preceding action in the current" -" session (keyboard shortcut: :kbd:`Ctrl+Left`)." -msgstr "" -"|step_prev| **Étape précédente** : sélectionne l'action précédente dans " -"la session courante (raccourci clavier : :kbd:`Ctrl+Gauche`)." +msgid "|step_prev| **Previous step**: select the preceding action in the current session (keyboard shortcut: :kbd:`Ctrl+Left`)." +msgstr "|step_prev| **Étape précédente** : sélectionne l'action précédente dans la session courante (raccourci clavier : :kbd:`Ctrl+Gauche`)." msgid "step_prev" msgstr "step_prev" -msgid "" -"|step_next| **Next step**: select the following action in the current " -"session (keyboard shortcut: :kbd:`Ctrl+Right`)." -msgstr "" -"|step_next| **Étape suivante** : sélectionne l'action suivante dans la " -"session courante (raccourci clavier : :kbd:`Ctrl+Droite`)." +msgid "|step_next| **Next step**: select the following action in the current session (keyboard shortcut: :kbd:`Ctrl+Right`)." +msgstr "|step_next| **Étape suivante** : sélectionne l'action suivante dans la session courante (raccourci clavier : :kbd:`Ctrl+Droite`)." msgid "step_next" msgstr "step_next" msgid "Double-clicking on an action row in the tree is equivalent to **Replay**." -msgstr "" -"Un double-clic sur la ligne d'une action dans l'arborescence équivaut à " -"**Rejouer**." +msgstr "Un double-clic sur la ligne d'une action dans l'arborescence équivaut à **Rejouer**." msgid "Tree view" msgstr "Arborescence" msgid "The tree view organizes recorded actions into expandable sessions:" -msgstr "" -"L'arborescence organise les actions enregistrées dans des sessions " -"dépliables :" +msgstr "L'arborescence organise les actions enregistrées dans des sessions dépliables :" -msgid "" -"Each top-level row is a **session**, automatically created when recording" -" is enabled and a new application context is started." -msgstr "" -"Chaque ligne de premier niveau est une **session**, créée automatiquement" -" lorsque l'enregistrement est activé et qu'un nouveau contexte " -"d'application est démarré." +msgid "Each top-level row is a **session**, automatically created when recording is enabled and a new application context is started." +msgstr "Chaque ligne de premier niveau est une **session**, créée automatiquement lorsque l'enregistrement est activé et qu'un nouveau contexte d'application est démarré." -msgid "" -"Each child row is an **action**, with its title, date/time and a " -"description summarising the parameters (for computations) or the call " -"(for UI actions)." -msgstr "" -"Chaque ligne enfant est une **action**, accompagnée de son titre, de sa " -"date et de son heure, ainsi que d'une description résumant les paramètres" -" (pour les calculs) ou l'appel (pour les actions de l'interface)." +msgid "Each child row is an **action**, with its title, date/time and a description summarising the parameters (for computations) or the call (for UI actions)." +msgstr "Chaque ligne enfant est une **action**, accompagnée de son titre, de sa date et de son heure, ainsi que d'une description résumant les paramètres (pour les calculs) ou l'appel (pour les actions de l'interface)." -msgid "" -"The selection of one or several rows drives which actions are targeted by" -" the toolbar buttons." -msgstr "" -"La sélection d'une ou de plusieurs lignes détermine les actions ciblées " -"par les boutons de la barre d'outils." +msgid "The selection of one or several rows drives which actions are targeted by the toolbar buttons." +msgstr "La sélection d'une ou de plusieurs lignes détermine les actions ciblées par les boutons de la barre d'outils." -msgid "" -"Actions that are not compatible with the current workspace state (for " -"example because a referenced object identifier no longer exists, or " -"because its data shape changed) are shown with a disabled foreground and " -"an explanatory tooltip. They cannot be replayed until the workspace " -"matches the recorded state again." -msgstr "" -"Les actions qui ne sont pas compatibles avec l'état courant de l'espace " -"de travail (par exemple parce qu'un identifiant d'objet référencé " -"n'existe plus, ou parce que la forme de ses données a changé) sont " -"affichées avec un texte désactivé et une infobulle explicative. Elles ne " -"peuvent pas être rejouées tant que l'espace de travail ne correspond pas " -"de nouveau à l'état enregistré." +msgid "Actions that are not compatible with the current workspace state (for example because a referenced object identifier no longer exists, or because its data shape changed) are shown with a disabled foreground and an explanatory tooltip. They cannot be replayed until the workspace matches the recorded state again." +msgstr "Les actions qui ne sont pas compatibles avec l'état courant de l'espace de travail (par exemple parce qu'un identifiant d'objet référencé n'existe plus, ou parce que la forme de ses données a changé) sont affichées avec un texte désactivé et une infobulle explicative. Elles ne peuvent pas être rejouées tant que l'espace de travail ne correspond pas de nouveau à l'état enregistré." msgid "Workspace state display" msgstr "Affichage de l'état de l'espace de travail" -msgid "" -"Below the action tree, a split-view widget shows the **workspace state** " -"captured at the time of the selected action:" -msgstr "" -"Sous l'arborescence des actions, un widget en vue divisée affiche " -"l'**état de l'espace de travail** tel qu'il était au moment de l'action " -"sélectionnée :" +msgid "Below the action tree, a split-view widget shows the **workspace state** captured at the time of the selected action:" +msgstr "Sous l'arborescence des actions, un widget en vue divisée affiche l'**état de l'espace de travail** tel qu'il était au moment de l'action sélectionnée :" -msgid "" -"**Left table**: lists the signals that were selected, with their data " -"shape." -msgstr "" -"**Tableau de gauche** : liste les signaux qui étaient sélectionnés, avec " -"leur forme de données." +msgid "**Left table**: lists the signals that were selected, with their data shape." +msgstr "**Tableau de gauche** : liste les signaux qui étaient sélectionnés, avec leur forme de données." -msgid "" -"**Right table**: lists the images that were selected, with their " -"dimensions." -msgstr "" -"**Tableau de droite** : liste les images qui étaient sélectionnées, avec " -"leurs dimensions." +msgid "**Right table**: lists the images that were selected, with their dimensions." +msgstr "**Tableau de droite** : liste les images qui étaient sélectionnées, avec leurs dimensions." -msgid "" -"This information helps the user understand the context in which each " -"action was originally executed and diagnose compatibility issues when " -"replaying sessions on a different workspace." -msgstr "" -"Ces informations aident l'utilisateur à comprendre le contexte dans " -"lequel chaque action a été exécutée à l'origine et à diagnostiquer les " -"problèmes de compatibilité lors du rejeu de sessions sur un espace de " -"travail différent." +msgid "This information helps the user understand the context in which each action was originally executed and diagnose compatibility issues when replaying sessions on a different workspace." +msgstr "Ces informations aident l'utilisateur à comprendre le contexte dans lequel chaque action a été exécutée à l'origine et à diagnostiquer les problèmes de compatibilité lors du rejeu de sessions sur un espace de travail différent." msgid "Session replay across workspaces" msgstr "Rejeu d'une session entre espaces de travail" -msgid "" -"A full session can be replayed on a workspace that no longer contains the" -" objects originally referenced by the recorded actions -- typically after" -" loading a saved session into a fresh workspace. In that case, the panel " -"**remaps the recorded object identifiers** to the newly-created ones on " -"the fly:" -msgstr "" -"Une session complète peut être rejouée sur un espace de travail qui ne " -"contient plus les objets référencés à l'origine par les actions " -"enregistrées -- typiquement après le chargement d'une session sauvegardée" -" dans un espace de travail vierge. Dans ce cas, le panneau **réassocie à " -"la volée les identifiants d'objets enregistrés** aux nouveaux " -"identifiants créés :" +msgid "A full session can be replayed on a workspace that no longer contains the objects originally referenced by the recorded actions -- typically after loading a saved session into a fresh workspace. In that case, the panel **remaps the recorded object identifiers** to the newly-created ones on the fly:" +msgstr "Une session complète peut être rejouée sur un espace de travail qui ne contient plus les objets référencés à l'origine par les actions enregistrées -- typiquement après le chargement d'une session sauvegardée dans un espace de travail vierge. Dans ce cas, le panneau **réassocie à la volée les identifiants d'objets enregistrés** aux nouveaux identifiants créés :" -msgid "" -"UI actions creating new objects (e.g. *New signal*) enqueue the freshly " -"created identifiers;" -msgstr "" -"les actions de l'interface qui créent de nouveaux objets (par exemple " -"*Nouveau signal*) empilent les identifiants fraîchement créés ;" +msgid "UI actions creating new objects (e.g. *New signal*) enqueue the freshly created identifiers;" +msgstr "les actions de l'interface qui créent de nouveaux objets (par exemple *Nouveau signal*) empilent les identifiants fraîchement créés ;" -msgid "" -"subsequent computations claim the identifiers they need from that queue, " -"in the same order as the original recording;" -msgstr "" -"les calculs ultérieurs récupèrent dans cette file les identifiants dont " -"ils ont besoin, dans l'ordre de l'enregistrement initial ;" +msgid "subsequent computations claim the identifiers they need from that queue, in the same order as the original recording;" +msgstr "les calculs ultérieurs récupèrent dans cette file les identifiants dont ils ont besoin, dans l'ordre de l'enregistrement initial ;" -msgid "" -"UI actions removing objects keep the queue in sync with the live " -"workspace contents, so chained creation/removal sequences replay " -"correctly." -msgstr "" -"les actions de l'interface qui suppriment des objets maintiennent la file" -" synchronisée avec le contenu réel de l'espace de travail, de sorte que " -"les séquences enchaînées de création et de suppression se rejouent " -"correctement." +msgid "UI actions removing objects keep the queue in sync with the live workspace contents, so chained creation/removal sequences replay correctly." +msgstr "les actions de l'interface qui suppriment des objets maintiennent la file synchronisée avec le contenu réel de l'espace de travail, de sorte que les séquences enchaînées de création et de suppression se rejouent correctement." -msgid "" -"This makes it possible, for instance, to record a full processing chain " -"on one dataset, save it, then re-apply the exact same chain on a " -"different but structurally identical input." -msgstr "" -"Cela permet par exemple d'enregistrer une chaîne de traitement complète " -"sur un jeu de données, de la sauvegarder, puis de la ré-appliquer telle " -"quelle à une entrée différente mais structurellement identique." +msgid "This makes it possible, for instance, to record a full processing chain on one dataset, save it, then re-apply the exact same chain on a different but structurally identical input." +msgstr "Cela permet par exemple d'enregistrer une chaîne de traitement complète sur un jeu de données, de la sauvegarder, puis de la ré-appliquer telle quelle à une entrée différente mais structurellement identique." msgid "Persistence" msgstr "Persistance" @@ -390,177 +188,44 @@ msgstr "Persistance" msgid "The history can be persisted in two complementary ways:" msgstr "L'historique peut être persisté de deux manières complémentaires :" -msgid "" -"**Embedded in the workspace**: when the workspace is saved to HDF5 " -"(``File > Save to HDF5 file``), the History Panel content is " -"automatically saved alongside the signals and images. Reloading the " -"workspace restores the recorded sessions." -msgstr "" -"**Intégré à l'espace de travail** : lorsque l'espace de travail est " -"enregistré au format HDF5 (``Fichier > Enregistrer dans un fichier " -"HDF5``), le contenu du Panneau historique est automatiquement sauvegardé " -"aux côtés des signaux et des images. Le rechargement de l'espace de " -"travail restaure les sessions enregistrées." +msgid "**Embedded in the workspace**: when the workspace is saved to HDF5 (``File > Save to HDF5 file``), the History Panel content is automatically saved alongside the signals and images. Reloading the workspace restores the recorded sessions." +msgstr "**Intégré à l'espace de travail** : lorsque l'espace de travail est enregistré au format HDF5 (``Fichier > Enregistrer dans un fichier HDF5``), le contenu du Panneau historique est automatiquement sauvegardé aux côtés des signaux et des images. Le rechargement de l'espace de travail restaure les sessions enregistrées." -msgid "" -"**Standalone history file**: the panel can also be serialised to a " -"dedicated ``.dlhist`` file, which is convenient to share or version a " -"processing chain independently of the data it was applied to." -msgstr "" -"**Fichier d'historique autonome** : le panneau peut également être " -"sérialisé dans un fichier ``.dlhist`` dédié, ce qui est pratique pour " -"partager ou versionner une chaîne de traitement indépendamment des " -"données auxquelles elle a été appliquée." +msgid "**Standalone history file** (``.dlhist``): the file embeds both the recorded sessions **and** all signal/image objects referenced by those sessions. This makes the file fully self-contained:" +msgstr "**Fichier d'historique autonome** (``.dlhist``) : le fichier embarque à la fois les sessions enregistrées **et** tous les objets signal/image référencés par ces sessions. Cela rend le fichier entièrement autonome :" -msgid "" -"Replaying a session that depends on external files (e.g. opening a " -"dataset from disk) will only succeed if those files are still available " -"at the same locations as when the session was recorded." -msgstr "" -"Le rejeu d'une session qui dépend de fichiers externes (par exemple " -"l'ouverture d'un jeu de données depuis le disque) ne réussira que si ces " -"fichiers sont toujours disponibles aux mêmes emplacements qu'au moment de" -" l'enregistrement de la session." +msgid "Opening a ``.dlhist`` into an **empty workspace** loads sessions and objects directly, restoring the workspace to its recorded state." +msgstr "Ouvrir un fichier ``.dlhist`` dans un **espace de travail vide** charge les sessions et les objets directement, restaurant l'espace de travail dans son état enregistré." -msgid "Auto-recompute" -msgstr "Recalcul automatique" +msgid "Opening a ``.dlhist`` into a **non-empty workspace** creates new signal/image groups for the imported objects (with remapped identifiers to avoid collisions) and appends new history sessions that reference those fresh identifiers." +msgstr "Ouvrir un fichier ``.dlhist`` dans un **espace de travail non vide** crée de nouveaux groupes signal/image pour les objets importés (avec des identifiants remappés pour éviter les collisions) et ajoute de nouvelles sessions d'historique référençant ces nouveaux identifiants." -msgid "" -"When a result object is selected in the signal/image panel and it has " -"processing parameters (i.e. was produced by a 1-to-1 computation), a " -"**Processing** tab appears in the Properties panel. Checking **Auto-" -"recompute on edit** in that tab will re-run the computation automatically" -" 300 ms after any parameter modification." -msgstr "" -"Lorsqu'un objet résultat est sélectionné dans le panneau signal/image et " -"qu'il possède des paramètres de traitement (c'est-à-dire qu'il a été " -"produit par un calcul 1-à-1), un onglet **Traitement** apparaît dans le " -"panneau Propriétés. Cocher **Recalcul automatique lors de l'édition** " -"dans cet onglet relancera automatiquement le calcul 300 ms après toute " -"modification d'un paramètre." - -msgid "" -"When replaying a *whole session*, the parameter dialogs open in a " -"**read-only** mode — all fields are shown with their recorded values but " -"cannot be edited." -msgstr "" -"Lors du rejeu d'une *session entière*, les boîtes de dialogue des " -"paramètres s'ouvrent en mode **lecture seule** — tous les champs " -"affichent les valeurs enregistrées mais ne peuvent pas être édités." +msgid "Replaying a session that depends on external files (e.g. opening a dataset from disk) will only succeed if those files are still available at the same locations as when the session was recorded." +msgstr "Le rejeu d'une session qui dépend de fichiers externes (par exemple l'ouverture d'un jeu de données depuis le disque) ne réussira que si ces fichiers sont toujours disponibles aux mêmes emplacements qu'au moment de l'enregistrement de la session." msgid "Chain reconnection on deletion" msgstr "Reconnexion de la chaîne lors d'une suppression" -msgid "" -"When a result object is deleted from the **signal or image panel** (not " -"from the History Panel tree), and that object was produced by a recorded " -"processing step, the History Panel automatically reconnects the processing " -"chain:" -msgstr "" -"Lorsqu'un objet résultat est supprimé depuis le **panneau signal ou image** " -"(et non depuis l'arborescence du panneau historique), et que cet objet a " -"été produit par une étape de traitement enregistrée, le Panneau historique " -"reconnecte automatiquement la chaîne de traitement :" +msgid "When a result object is deleted from the **signal or image panel** (not from the History Panel tree), and that object was produced by a recorded processing step, the History Panel automatically reconnects the processing chain:" +msgstr "Lorsqu'un objet résultat est supprimé depuis le **panneau signal ou image** (et non depuis l'arborescence du panneau historique), et que cet objet a été produit par une étape de traitement enregistrée, le Panneau historique reconnecte automatiquement la chaîne de traitement :" -msgid "" -"All downstream steps that consumed the deleted object are rewired to use " -"the source of the deleted step as their new input." -msgstr "" -"Toutes les étapes aval qui consommaient l'objet supprimé sont recâblées " -"pour utiliser la source de l'étape supprimée comme nouvelle entrée." - -msgid "" -"For ``2_to_1`` operations (e.g. *difference*), the first source is used " -"for reconnection." -msgstr "" -"Pour les opérations ``2_to_1`` (par exemple *différence*), la première " -"source est utilisée pour la reconnexion." - -msgid "" -"If no valid source can be determined (e.g. the source itself was already " -"deleted), a warning is displayed listing the unreconnectable operations, " -"but the deletion is allowed to proceed." -msgstr "" -"Si aucune source valide ne peut être déterminée (par exemple la source " -"elle-même a déjà été supprimée), un avertissement est affiché listant les " -"opérations non reconnectables, mais la suppression est néanmoins autorisée." +msgid "All downstream steps that consumed the deleted object are rewired to use the source of the deleted step as their new input." +msgstr "Toutes les étapes aval qui consommaient l'objet supprimé sont recâblées pour utiliser la source de l'étape supprimée comme nouvelle entrée." -msgid "" -"This behaviour mirrors removing a link from a chain: the adjacent links " -"reconnect to preserve the processing flow." -msgstr "" -"Ce comportement reproduit la suppression d'un maillon d'une chaîne : les " -"maillons adjacents se reconnectent pour préserver le flux de traitement." +msgid "For ``2_to_1`` operations (e.g. *difference*), the first source is used for reconnection." +msgstr "Pour les opérations ``2_to_1`` (par exemple *différence*), la première source est utilisée pour la reconnexion." -msgid "" -"Reconnection is only triggered by deletions initiated from the " -"signal/image panels. Deleting an action directly from the History Panel " -"tree removes it and all subsequent actions in that session." -msgstr "" -"La reconnexion n'est déclenchée que par les suppressions initiées depuis " -"les panneaux signal/image. Supprimer une action directement depuis " -"l'arborescence du Panneau historique la retire ainsi que toutes les " -"actions suivantes de cette session." +msgid "If no valid source can be determined (e.g. the source itself was already deleted), a warning is displayed listing the unreconnectable operations, but the deletion is allowed to proceed." +msgstr "Si aucune source valide ne peut être déterminée (par exemple la source elle-même a déjà été supprimée), un avertissement est affiché listant les opérations non reconnectables, mais la suppression est néanmoins autorisée." -msgid "" -"**Standalone history file** (``.dlhist``): the file embeds both the " -"recorded sessions **and** all signal/image objects referenced by those " -"sessions. This makes the file fully self-contained:" -msgstr "" -"**Fichier d'historique autonome** (``.dlhist``) : le fichier embarque à " -"la fois les sessions enregistrées **et** tous les objets signal/image " -"référencés par ces sessions. Cela rend le fichier entièrement autonome :" +msgid "This behaviour mirrors removing a link from a chain: the adjacent links reconnect to preserve the processing flow." +msgstr "Ce comportement reproduit la suppression d'un maillon d'une chaîne : les maillons adjacents se reconnectent pour préserver le flux de traitement." -msgid "" -"Opening a ``.dlhist`` into an **empty workspace** loads sessions and " -"objects directly, restoring the workspace to its recorded state." -msgstr "" -"Ouvrir un fichier ``.dlhist`` dans un **espace de travail vide** charge " -"les sessions et les objets directement, restaurant l'espace de travail " -"dans son état enregistré." +msgid "Reconnection is only triggered by deletions initiated from the signal/image panels. Deleting an action directly from the History Panel tree removes it and all subsequent actions in that session." +msgstr "La reconnexion n'est déclenchée que par les suppressions initiées depuis les panneaux signal/image. Supprimer une action directement depuis l'arborescence du Panneau historique la retire ainsi que toutes les actions suivantes de cette session." -msgid "" -"Opening a ``.dlhist`` into a **non-empty workspace** creates new " -"signal/image groups for the imported objects (with remapped identifiers " -"to avoid collisions) and appends new history sessions that reference " -"those fresh identifiers." -msgstr "" -"Ouvrir un fichier ``.dlhist`` dans un **espace de travail non vide** crée " -"de nouveaux groupes signal/image pour les objets importés (avec des " -"identifiants remappés pour éviter les collisions) et ajoute de nouvelles " -"sessions d'historique référençant ces nouveaux identifiants." - -#~ msgid "" -#~ "|restore_and_replay| **Restore selection and " -#~ "replay**: combine the two previous " -#~ "actions -- restore the selection first," -#~ " then replay." -#~ msgstr "" -#~ "|restore_and_replay| **Restaurer la sélection " -#~ "et rejouer** : combine les deux " -#~ "actions précédentes -- restaure d'abord " -#~ "la sélection, puis rejoue." - -#~ msgid "restore_and_replay" -#~ msgstr "restore_and_replay" - -#~ msgid "" -#~ "|replay| **Apply duplicate**: replay the " -#~ "selected duplicate persistently, adding " -#~ "comparison outputs to the signal/image " -#~ "panels. Outputs without an existing " -#~ "destination group are placed in a " -#~ "``Replay duplicate`` group, and their " -#~ "titles are prefixed with ``Replay " -#~ "duplicate -``." -#~ msgstr "" -#~ "|replay| **Appliquer le duplicata** : " -#~ "rejoue le duplicata sélectionné de façon" -#~ " persistante, en ajoutant des sorties " -#~ "de comparaison aux panneaux signal/image. " -#~ "Les sorties sans groupe de destination" -#~ " existant sont placées dans un groupe" -#~ " ``Rejeu du duplicata``, et leurs " -#~ "titres sont préfixés par ``Rejeu du " -#~ "duplicata -``." +msgid "Auto-recompute" +msgstr "Recalcul automatique" +msgid "When a result object is selected in the signal/image panel and it has processing parameters (i.e. was produced by a 1-to-1 computation), a **Processing** tab appears in the Properties panel. Checking **Auto-recompute on edit** in that tab will re-run the computation automatically 300 ms after any parameter modification." +msgstr "Lorsqu'un objet résultat est sélectionné dans le panneau signal/image et qu'il possède des paramètres de traitement (c'est-à-dire qu'il a été produit par un calcul 1-à-1), un onglet **Traitement** apparaît dans le panneau Propriétés. Cocher **Recalcul automatique lors de l'édition** dans cet onglet relancera automatiquement le calcul 300 ms après toute modification d'un paramètre." diff --git a/doc/locale/fr/LC_MESSAGES/release_notes/release_1.03.po b/doc/locale/fr/LC_MESSAGES/release_notes/release_1.03.po index d261ac539..96083084f 100644 --- a/doc/locale/fr/LC_MESSAGES/release_notes/release_1.03.po +++ b/doc/locale/fr/LC_MESSAGES/release_notes/release_1.03.po @@ -5,17 +5,11 @@ # msgid "" msgstr "" -"Project-Id-Version: PROJECT VERSION\n" -"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2026-05-28 17:03+0200\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.18.0\n" msgid "Version 1.3" msgstr "Version 1.3" From c8359efbcb381cbcc419db7590388ef6b6c97b33 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Thu, 25 Jun 2026 14:01:54 +0200 Subject: [PATCH 024/108] style: run ruff and fix pylint warnings on history panel Follow-up to a review noting that ruff/pylint had not been run on the History panel refactor after it was split into submodules. Cross-module access to underscore-prefixed members triggered W0212, plus a batch of other lint warnings that were addressed without disabling any checks. --- datalab/gui/historysession_ops.py | 16 +-- datalab/gui/historytools_ops.py | 8 +- datalab/gui/main.py | 1 + datalab/gui/panel/history/chain.py | 76 +++++------ .../gui/panel/history/interactive_replay.py | 39 +++--- datalab/gui/panel/history/panel.py | 108 +++++++--------- datalab/gui/panel/history/recompute.py | 44 ++++--- datalab/h5/history.py | 15 +-- datalab/history/action.py | 25 ++-- datalab/history/session.py | 53 +++++--- datalab/tests/features/common/history_test.py | 118 +++++++++--------- datalab/widgets/historydescription.py | 2 + 12 files changed, 254 insertions(+), 251 deletions(-) diff --git a/datalab/gui/historysession_ops.py b/datalab/gui/historysession_ops.py index 67102cdf6..1d31be238 100644 --- a/datalab/gui/historysession_ops.py +++ b/datalab/gui/historysession_ops.py @@ -166,10 +166,10 @@ def register_action_outputs( create new objects). """ # Drop previous outputs for this action from the reverse index. - previous = panel._action_output_uuids.get(action.uuid, []) + previous = panel.action_output_uuids.get(action.uuid, []) for prev_uuid in previous: - if panel._output_to_action.get(prev_uuid) == action.uuid: - panel._output_to_action.pop(prev_uuid, None) + if panel.output_to_action.get(prev_uuid) == action.uuid: + panel.output_to_action.pop(prev_uuid, None) new_outputs = list(output_uuids) # Ownership transfer: if an output_uuid already belongs to a # *different* action, remove it from that action's output list so the @@ -178,16 +178,16 @@ def register_action_outputs( # sessions to locate the object would be expensive; the panel-level # dicts are the source of truth. for out_uuid in new_outputs: - old_action_uuid = panel._output_to_action.get(out_uuid) + old_action_uuid = panel.output_to_action.get(out_uuid) if old_action_uuid is not None and old_action_uuid != action.uuid: - old_list = panel._action_output_uuids.get(old_action_uuid) + old_list = panel.action_output_uuids.get(old_action_uuid) if old_list is not None: try: old_list.remove(out_uuid) except ValueError: pass if not old_list: - del panel._action_output_uuids[old_action_uuid] + del panel.action_output_uuids[old_action_uuid] _logger.debug( "Output %s transferred from action %s to %s", out_uuid, @@ -195,9 +195,9 @@ def register_action_outputs( action.uuid, ) action.output_uuids = list(new_outputs) - panel._action_output_uuids[action.uuid] = new_outputs + panel.action_output_uuids[action.uuid] = new_outputs for out_uuid in new_outputs: - panel._output_to_action[out_uuid] = action.uuid + panel.output_to_action[out_uuid] = action.uuid @contextmanager diff --git a/datalab/gui/historytools_ops.py b/datalab/gui/historytools_ops.py index 3e326df92..e4d29c8bb 100644 --- a/datalab/gui/historytools_ops.py +++ b/datalab/gui/historytools_ops.py @@ -154,13 +154,13 @@ def duplicate_selected_entries(panel: HistoryPanel) -> None: new_sessions.append(new_session) # Register output mappings for cloned actions so that - # _resolve_target_outputs / get_downstream_actions work on - # the duplicated session (same logic as read_h5_data). + # resolve_target_outputs / get_downstream_actions work on + # the duplicated session (same logic as deserialize_from_hdf5). for action in new_session.actions: if action.output_uuids: - panel._action_output_uuids[action.uuid] = list(action.output_uuids) + panel.action_output_uuids[action.uuid] = list(action.output_uuids) for out_uuid in action.output_uuids: - panel._output_to_action[out_uuid] = action.uuid + panel.output_to_action[out_uuid] = action.uuid # Insert each duplicated session immediately after its original. offset = 0 diff --git a/datalab/gui/main.py b/datalab/gui/main.py index 9d99592ba..cc98e81da 100644 --- a/datalab/gui/main.py +++ b/datalab/gui/main.py @@ -198,6 +198,7 @@ def __init__(self, console=None, hide_on_close=False): # pylint: disable=too-ma self.saveh5_action: QW.QAction | None = None self.browseh5_action: QW.QAction | None = None self.settings_action: QW.QAction | None = None + self.command_palette_action: QW.QAction | None = None self.quit_action: QW.QAction | None = None self.autorefresh_action: QW.QAction | None = None self.showfirstonly_action: QW.QAction | None = None diff --git a/datalab/gui/panel/history/chain.py b/datalab/gui/panel/history/chain.py index 48e3a935c..67d0906d4 100644 --- a/datalab/gui/panel/history/chain.py +++ b/datalab/gui/panel/history/chain.py @@ -11,6 +11,7 @@ from datalab.config import _ from datalab.env import execenv +from datalab.gui.panel.history import recompute as hrec from datalab.gui.processor.base import ( ProcessingParameters, extract_processing_parameters, @@ -30,7 +31,7 @@ def find_parent_session( panel: HistoryPanel, action: HistoryAction ) -> HistorySession | None: """Return the session that contains ``action``, or None.""" - for session in panel._history_sessions: + for session in panel.history_sessions: if action in session.actions: return session return None @@ -57,7 +58,7 @@ def find_output_object_uuid( Primary path: consult the bijective ``action_output_uuids`` mapping. Fallback path: legacy heuristic on ``processing_parameters`` metadata. """ - registered = panel._action_output_uuids.get(action.uuid) + registered = panel.action_output_uuids.get(action.uuid) if registered: existing_ids = set(panel_data.objmodel.get_object_ids()) for out_uuid in registered: @@ -83,16 +84,21 @@ def find_action_for_output( panel: HistoryPanel, output_uuid: str, func_name: str ) -> HistoryAction | None: """Find the :class:`HistoryAction` that produced ``output_uuid``.""" - if not panel._history_sessions: + if not panel.history_sessions: return None - action_uuid = panel._output_to_action.get(output_uuid) + action_uuid = panel.output_to_action.get(output_uuid) if action_uuid is not None: - for session in panel._history_sessions: - for action in session.actions: - if action.uuid == action_uuid: - if action.func_name == func_name: - return action - return None + mapped = next( + ( + action + for session in panel.history_sessions + for action in session.actions + if action.uuid == action_uuid + ), + None, + ) + if mapped is not None: + return mapped if mapped.func_name == func_name else None panel_data: BaseDataPanel | None = None output_obj = None for p in (panel.mainwindow.signalpanel, panel.mainwindow.imagepanel): @@ -103,12 +109,10 @@ def find_action_for_output( if panel_data is None or output_obj is None: return None pp = extract_processing_parameters(output_obj) - if pp is None or pp.func_name != func_name: + if pp is None or pp.func_name != func_name or pp.source_uuid is None: return None target_source_uuid = pp.source_uuid - if target_source_uuid is None: - return None - for current_session in reversed(panel._history_sessions): + for current_session in reversed(panel.history_sessions): for action in reversed(current_session.actions): if action.kind != HistoryAction.KIND_COMPUTE: continue @@ -124,7 +128,7 @@ def find_action_for_output( def get_session_of(panel: HistoryPanel, action: HistoryAction) -> HistorySession | None: """Return the session that contains ``action``, or None.""" - for session in panel._history_sessions: + for session in panel.history_sessions: if action in session.actions: return session return None @@ -155,7 +159,7 @@ def action_consumes_any(action: HistoryAction, uuids: set[str]) -> bool: def collect_downstream_uuids(panel: HistoryPanel, action: HistoryAction) -> set[str]: """Return the transitive closure of output UUIDs descending from ``action``.""" - if not panel._history_sessions: + if not panel.history_sessions: return set() current = get_session_of(panel, action) if current is None: @@ -181,7 +185,7 @@ def get_downstream_actions( panel: HistoryPanel, action: HistoryAction ) -> list[HistoryAction]: """Return the actions of the current session that depend on ``action``.""" - if not panel._history_sessions: + if not panel.history_sessions: return [] current = get_session_of(panel, action) if current is None: @@ -208,7 +212,7 @@ def resolve_target_outputs( panel: HistoryPanel, panel_data: BaseDataPanel, action: HistoryAction ) -> tuple[list[str], list[str]]: """Return ``(existing, missing)`` UUIDs registered for ``action``.""" - registered = list(panel._action_output_uuids.get(action.uuid, [])) + registered = list(panel.action_output_uuids.get(action.uuid, [])) existing_ids = set(panel_data.objmodel.get_object_ids()) existing: list[str] = [u for u in registered if u in existing_ids] missing: list[str] = [u for u in registered if u not in existing_ids] @@ -222,15 +226,15 @@ def existing_input_uuids(panel_data: BaseDataPanel, action: HistoryAction) -> li def prune_output_mapping(panel: HistoryPanel) -> None: - """Drop entries of :attr:`_output_to_action` whose object no longer exists.""" - if not panel._output_to_action: + """Drop entries of :attr:`output_to_action` whose object no longer exists.""" + if not panel.output_to_action: return alive: set[str] = set() for pdata in (panel.mainwindow.signalpanel, panel.mainwindow.imagepanel): alive.update(pdata.objmodel.get_object_ids()) - stale = [u for u in panel._output_to_action if u not in alive] + stale = [u for u in panel.output_to_action if u not in alive] for u in stale: - panel._output_to_action.pop(u, None) + panel.output_to_action.pop(u, None) def rewrite_action_source( @@ -253,15 +257,15 @@ def rewrite_action_source( def remove_single_action(panel: HistoryPanel, action: HistoryAction) -> None: """Remove a single action from its session (splice, not truncate).""" - for session in panel._history_sessions: + for session in panel.history_sessions: if action in session.actions: session.actions.remove(action) - outs = panel._action_output_uuids.pop(action.uuid, []) + outs = panel.action_output_uuids.pop(action.uuid, []) for out_uuid in outs: - if panel._output_to_action.get(out_uuid) == action.uuid: - panel._output_to_action.pop(out_uuid, None) + if panel.output_to_action.get(out_uuid) == action.uuid: + panel.output_to_action.pop(out_uuid, None) if not session.actions: - panel._history_sessions.remove(session) + panel.history_sessions.remove(session) break @@ -275,9 +279,9 @@ def reconnect_single_removed( """Reconnect consumers of a single deleted object ``x_uuid``.""" pstr = panel_data.PANEL_STR_ID action_a = None - action_a_uuid = panel._output_to_action.get(x_uuid) + action_a_uuid = panel.output_to_action.get(x_uuid) if action_a_uuid is not None: - for session in panel._history_sessions: + for session in panel.history_sessions: for a in session.actions: if a.uuid == action_a_uuid: action_a = a @@ -331,7 +335,7 @@ def reconnect_single_removed( if action_b not in roots_to_recompute: roots_to_recompute.append(action_b) if action_a is not None: - outs = panel._action_output_uuids.get(action_a.uuid, []) + outs = panel.action_output_uuids.get(action_a.uuid, []) if not any(o in alive_ids for o in outs): remove_single_action(panel, action_a) @@ -340,15 +344,13 @@ def reconnect_chain_after_removal( panel: HistoryPanel, panel_data: BaseDataPanel ) -> None: """Reconnect the processing chain after object(s) were deleted from a data panel.""" - from datalab.gui.panel.history import recompute as hrec - pstr = panel_data.PANEL_STR_ID - previous = panel._obj_ids_snapshot.get(pstr, set()) + previous = panel.obj_ids_snapshot.get(pstr, set()) current = set(panel_data.objmodel.get_object_ids()) removed = previous - current - if not removed or panel._reconnecting: + if not removed or panel.reconnecting: return - panel._reconnecting = True + panel.reconnecting = True try: warnings: list[str] = [] roots_to_recompute: list[HistoryAction] = [] @@ -367,9 +369,9 @@ def reconnect_chain_after_removal( + "\n\n• " + "\n• ".join(warnings), ) - panel.tree.populate_tree(panel._history_sessions) + panel.tree.populate_tree(panel.history_sessions) panel.refresh_compatibility_items() panel.update_actions_state() finally: - panel._reconnecting = False + panel.reconnecting = False panel.refresh_obj_ids_snapshot() diff --git a/datalab/gui/panel/history/interactive_replay.py b/datalab/gui/panel/history/interactive_replay.py index 2514981d9..07fa37356 100644 --- a/datalab/gui/panel/history/interactive_replay.py +++ b/datalab/gui/panel/history/interactive_replay.py @@ -28,11 +28,11 @@ def replay_restore_actions( ) -> None: """Replay and/or restore selection for the selected actions.""" panel.refresh_compatibility_items() - selected = panel.tree.get_selected_actions_or_sessions(panel._history_sessions) + selected = panel.tree.get_selected_actions_or_sessions(panel.history_sessions) if not selected: - if not panel._history_sessions: + if not panel.history_sessions: return - selected = [panel._history_sessions[-1]] + selected = [panel.history_sessions[-1]] for session_or_action in selected: if isinstance(session_or_action, HistoryAction) and session_or_action.is_stale: hrec.recompute_cascade(panel, session_or_action) @@ -48,19 +48,19 @@ def replay_restore_actions( ) return if replay: - if panel._edit_mode and isinstance(session_or_action, HistoryAction): + if panel.edit_mode and isinstance(session_or_action, HistoryAction): edit_mode_replay(panel, session_or_action) - elif panel._edit_mode and isinstance(session_or_action, HistorySession): + elif panel.edit_mode and isinstance(session_or_action, HistorySession): view_only_session_replay(panel, session_or_action, restore_selection) else: with panel.replaying(), panel.output_suppressed(): session_or_action.replay( panel.mainwindow, restore_selection=restore_selection, - edit=panel._edit_mode, + edit=panel.edit_mode, ) elif restore_selection: - if panel._edit_mode or panel.has_any_pending_edits(): + if panel.edit_mode or panel.has_any_pending_edits(): restore_action_params(panel, session_or_action) else: session_or_action.restore(panel.mainwindow) @@ -76,23 +76,22 @@ def prompt_edit_action_params( if param is None: return None edited = copy.deepcopy(param) - if not edited.edit(parent=panel.mainwindow): - return False - action.snapshot_kwargs() - action.kwargs["param"] = edited - return True - if pattern == "1_to_n": + dialog_target: gds.DataSet | gds.DataSetGroup = edited + new_kwargs = {"param": edited} + elif pattern == "1_to_n": params = action.kwargs.get("params") or [] if not params: return None edited_params = [copy.deepcopy(p) for p in params] - group = gds.DataSetGroup(edited_params, title=_("Parameters")) - if not group.edit(parent=panel.mainwindow): - return False - action.snapshot_kwargs() - action.kwargs["params"] = edited_params - return True - return None + dialog_target = gds.DataSetGroup(edited_params, title=_("Parameters")) + new_kwargs = {"params": edited_params} + else: + return None + if not dialog_target.edit(parent=panel.mainwindow): + return False + action.snapshot_kwargs() + action.kwargs.update(new_kwargs) + return True def edit_mode_replay(panel: HistoryPanel, action: HistoryAction) -> None: diff --git a/datalab/gui/panel/history/panel.py b/datalab/gui/panel/history/panel.py index c060e361d..e4c74b722 100644 --- a/datalab/gui/panel/history/panel.py +++ b/datalab/gui/panel/history/panel.py @@ -58,15 +58,15 @@ def __init__(self, parent: DLMainWindow) -> None: self.setOrientation(QC.Qt.Vertical) self._record_mode = False - self._edit_mode = False + self.edit_mode = False self._replaying = False self._output_suppressed = False self._syncing = False - self._cascade_in_progress = False + self.cascade_in_progress = False self._delete_action: QW.QAction | None = None self._duplicate_action: QW.QAction | None = None - self._step_prev_action: QW.QAction | None = None - self._step_next_action: QW.QAction | None = None + self.step_prev_action: QW.QAction | None = None + self.step_next_action: QW.QAction | None = None self._restore_selection_action: QW.QAction | None = None self._edit_action: QW.QAction | None = None self._record_action: QW.QAction | None = None @@ -94,14 +94,14 @@ def __init__(self, parent: DLMainWindow) -> None: self.addWidget(widget) - self._history_sessions: list[HistorySession] = [] + self.history_sessions: list[HistorySession] = [] self._session_increment = 0 - self._action_output_uuids: dict[str, list[str]] = {} - self._output_to_action: dict[str, str] = {} - self._cascade_warnings: list[str] = [] - self._broken_actions: set[str] = set() - self._reconnecting = False - self._obj_ids_snapshot: dict[str, set[str]] = {} + self.action_output_uuids: dict[str, list[str]] = {} + self.output_to_action: dict[str, str] = {} + self.cascade_warnings: list[str] = [] + self.broken_actions: set[str] = set() + self.reconnecting = False + self.obj_ids_snapshot: dict[str, set[str]] = {} for panel in (self.mainwindow.signalpanel, self.mainwindow.imagepanel): panel.SIG_OBJECT_ADDED.connect(self.refresh_compatibility_items) panel.SIG_OBJECT_ADDED.connect(self.refresh_obj_ids_snapshot) @@ -120,7 +120,7 @@ def __init__(self, parent: DLMainWindow) -> None: def refresh_obj_ids_snapshot(self) -> None: """Cache the current object ids of both data panels.""" - self._obj_ids_snapshot = { + self.obj_ids_snapshot = { self.mainwindow.signalpanel.PANEL_STR_ID: set( self.mainwindow.signalpanel.objmodel.get_object_ids() ), @@ -135,27 +135,15 @@ def update_actions_state(self) -> None: for action in (self._delete_action, self._duplicate_action): if action is not None: action.setEnabled(has_history) - if self._step_prev_action is not None: - self._step_prev_action.setEnabled(self.can_step_prev()) - if self._step_next_action is not None: - self._step_next_action.setEnabled(self.can_step_next()) + if self.step_prev_action is not None: + self.step_prev_action.setEnabled(self.can_step_prev()) + if self.step_next_action is not None: + self.step_next_action.setEnabled(self.can_step_next()) if self._restore_selection_action is not None: self._restore_selection_action.setEnabled( - self._edit_mode or self.has_any_pending_edits() + self.edit_mode or self.has_any_pending_edits() ) - __update_actions_state = update_actions_state - - @property - def history_sessions(self) -> list[HistorySession]: - """Return mutable history sessions storage.""" - return self._history_sessions - - @history_sessions.setter - def history_sessions(self, sessions: list[HistorySession]) -> None: - """Replace history sessions storage.""" - self._history_sessions = sessions - @property def session_increment(self) -> int: """Return the current session counter.""" @@ -176,7 +164,7 @@ def has_any_pending_edits(self) -> bool: mode snapshot (i.e. uncommitted edits that Restore can revert).""" return any( action.has_pending_edits - for session in self._history_sessions + for session in self.history_sessions for action in session.actions ) @@ -196,7 +184,7 @@ def create_menu_actions(self) -> list[QW.QAction]: toggled=self.toggle_edit_mode, icon=get_icon("edit_mode.svg"), ) - edit_action.setChecked(self._edit_mode) + edit_action.setChecked(self.edit_mode) self._edit_action = edit_action record_action = create_action( self, @@ -240,7 +228,7 @@ def create_menu_actions(self) -> list[QW.QAction]: icon=get_icon("duplicate.svg"), tip=_("Duplicate selected history action/session"), ) - self._step_prev_action = create_action( + self.step_prev_action = create_action( self, _("Previous step"), triggered=self.step_prev, @@ -248,7 +236,7 @@ def create_menu_actions(self) -> list[QW.QAction]: tip=_("Select the previous action in the current session"), shortcut=QG.QKeySequence("Ctrl+Left"), ) - self._step_next_action = create_action( + self.step_next_action = create_action( self, _("Next step"), triggered=self.step_next, @@ -284,8 +272,8 @@ def create_menu_actions(self) -> list[QW.QAction]: open_action, save_action, None, - self._step_prev_action, - self._step_next_action, + self.step_prev_action, + self.step_next_action, None, create_action( self, @@ -334,9 +322,9 @@ def toggle_edit_mode(self, checked: bool) -> None: self._edit_action.setChecked(True) self._edit_action.blockSignals(False) return - self._edit_mode = checked + self.edit_mode = checked if not checked: - for session in self._history_sessions: + for session in self.history_sessions: for action in session.actions: action.discard_snapshot() self.update_actions_state() @@ -347,7 +335,7 @@ def toggle_record_mode(self, checked: bool) -> None: def is_edit_mode(self) -> bool: """Return True when the History panel is in edit mode.""" - return self._edit_mode + return self.edit_mode @contextmanager def replaying(self) -> Generator[None, None, None]: @@ -386,7 +374,7 @@ def show_context_menu(self, pos: QC.QPoint) -> None: def get_action_from_uuid(self, uuid: str) -> HistoryAction: """Get the action from its UUID.""" - for session in self._history_sessions: + for session in self.history_sessions: for action in session.actions: if action.uuid == uuid: return action @@ -456,8 +444,6 @@ def action_output_uuid(self, action: HistoryAction) -> str | None: """Return the UUID of the object produced by ``action``, or ``None``.""" return hchain.action_output_uuid(self, action) - _action_output_uuid = action_output_uuid - def action_consumes_any(self, action: HistoryAction, uuids: set[str]) -> bool: """Return True if ``action``'s input UUIDs intersect ``uuids``.""" return hchain.action_consumes_any(action, uuids) @@ -483,7 +469,7 @@ def existing_input_uuids( return hchain.existing_input_uuids(panel, action) def prune_output_mapping(self) -> None: - """Drop entries of :attr:`_output_to_action` whose object no longer exists.""" + """Drop entries of :attr:`output_to_action` whose object no longer exists.""" return hchain.prune_output_mapping(self) def rewrite_action_source( @@ -589,21 +575,21 @@ def sync_panel_selection(self) -> None: return if item.parent() is None: index = self.tree.indexOfTopLevelItem(item) - if index < 0 or index >= len(self._history_sessions): + if index < 0 or index >= len(self.history_sessions): return - session = self._history_sessions[index] + session = self.history_sessions[index] action = next( (a for a in session.actions if a.kind == HistoryAction.KIND_COMPUTE), None, ) - if action is None: - return else: uuid = item.data(0, QC.Qt.UserRole) try: - action = self.tree.get_action_from_uuid(uuid, self._history_sessions) + action = self.tree.get_action_from_uuid(uuid, self.history_sessions) except ValueError: - return + action = None + if action is None: + return panel = self.resolve_panel_for_action(action) if panel is None: @@ -638,7 +624,7 @@ def current_action(self) -> HistoryAction | None: return None uuid = item.data(0, QC.Qt.UserRole) try: - return self.tree.get_action_from_uuid(uuid, self._history_sessions) + return self.tree.get_action_from_uuid(uuid, self.history_sessions) except ValueError: return None @@ -648,14 +634,14 @@ def current_session(self) -> HistorySession | None: if item is not None: if item.parent() is None: index = self.tree.indexOfTopLevelItem(item) - if 0 <= index < len(self._history_sessions): - return self._history_sessions[index] + if 0 <= index < len(self.history_sessions): + return self.history_sessions[index] else: action = self.current_action() if action is not None: return self.find_parent_session(action) - if self._history_sessions: - return self._history_sessions[-1] + if self.history_sessions: + return self.history_sessions[-1] return None def can_step_prev(self) -> bool: @@ -700,8 +686,6 @@ def step_prev(self) -> None: self.select_action_in_tree(session.actions[idx - 1]) self.update_actions_state() - _step_prev = step_prev - def step_next(self) -> None: """Select the next action in the current session.""" if not self.can_step_next(): @@ -715,8 +699,6 @@ def step_next(self) -> None: self.select_action_in_tree(target) self.update_actions_state() - _step_next = step_next - # ------------------------------------------------------------------ # History tools delegations # ------------------------------------------------------------------ @@ -733,7 +715,7 @@ def select_sessions(self, sessions: list[HistorySession]) -> None: """Select top-level tree items matching ``sessions``.""" self.tree.clearSelection() for session in sessions: - index = self._history_sessions.index(session) + index = self.history_sessions.index(session) item = self.tree.topLevelItem(index) item.setSelected(True) self.tree.setCurrentItem(item) @@ -778,11 +760,11 @@ def deserialize_from_hdf5( def __len__(self) -> int: """Return number of objects.""" - return sum(len(session.actions) for session in self._history_sessions) + return sum(len(session.actions) for session in self.history_sessions) def __getitem__(self, nb: int) -> HistoryAction: """Return object from its number (1 to N).""" - for session in self._history_sessions: + for session in self.history_sessions: if nb <= len(session.actions): return session.actions[nb - 1] nb -= len(session.actions) @@ -790,7 +772,7 @@ def __getitem__(self, nb: int) -> HistoryAction: def __iter__(self) -> Generator[HistoryAction, None, None]: """Iterate over objects.""" - for session in self._history_sessions: + for session in self.history_sessions: yield from session.actions # ------------------------------------------------------------------ @@ -898,5 +880,5 @@ def add_object(self, obj: HistoryAction) -> None: def remove_all_objects(self) -> None: """Remove all objects.""" super().remove_all_objects() - self._action_output_uuids.clear() - self._output_to_action.clear() + self.action_output_uuids.clear() + self.output_to_action.clear() diff --git a/datalab/gui/panel/history/recompute.py b/datalab/gui/panel/history/recompute.py index 8016f5d1e..1505d6cbe 100644 --- a/datalab/gui/panel/history/recompute.py +++ b/datalab/gui/panel/history/recompute.py @@ -101,7 +101,7 @@ def record_missing_outputs( action.uuid, name, ) - panel._cascade_warnings.append( + panel.cascade_warnings.append( _( "Action %s has been edited but its target output object(s) " "no longer exist — skipping." @@ -127,7 +127,7 @@ def recompute_action_in_place(panel: HistoryPanel, action: HistoryAction) -> Non action.pattern, action.uuid, ) - panel._cascade_warnings.append( + panel.cascade_warnings.append( _("Action %s uses pattern %r which is not recomputable yet.") % (action.func_name or action.uuid, action.pattern) ) @@ -143,7 +143,7 @@ def recompute_action_in_place(panel: HistoryPanel, action: HistoryAction) -> Non action.func_name, exc, ) - panel._cascade_warnings.append( + panel.cascade_warnings.append( _("Recompute failed for action %s: %s") % (action.func_name or action.uuid, exc) ) @@ -154,7 +154,7 @@ def handle_missing_feature( ) -> None: """Flag ``action`` as broken (missing plugin) and queue a user warning.""" action.is_stale = True - panel._broken_actions.add(action.uuid) + panel.broken_actions.add(action.uuid) plugin_origin = action.plugin_origin or exc.plugin_origin or {} directory = (plugin_origin.get("directory") if plugin_origin else None) or "?" param = action.kwargs.get("param") @@ -169,7 +169,7 @@ def handle_missing_feature( func_name, location, ) - panel._cascade_warnings.append( + panel.cascade_warnings.append( _( "Action %(name)s skipped: plugin '%(loc)s' is missing.\n" "Required parameter class: %(param)s\n" @@ -200,7 +200,7 @@ def recompute_1_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> Non if pp is None or pp.source_uuid is None: return if not panel_data.objmodel.has_uuid(pp.source_uuid): - panel._cascade_warnings.append( + panel.cascade_warnings.append( _("Action %s: source object was deleted — skipping.") % (action.func_name or action.uuid) ) @@ -236,16 +236,14 @@ def recompute_1_to_n_in_place(panel: HistoryPanel, action: HistoryAction) -> Non return existing, missing = panel.resolve_target_outputs(panel_data, action) record_missing_outputs(panel, action, missing) - if not existing: - return - if not panel_data.objmodel.has_uuid(existing[0]): + if not existing or not panel_data.objmodel.has_uuid(existing[0]): return first_obj = panel_data.objmodel[existing[0]] pp = extract_processing_parameters(first_obj) if pp is None or pp.source_uuid is None: return if not panel_data.objmodel.has_uuid(pp.source_uuid): - panel._cascade_warnings.append( + panel.cascade_warnings.append( _("Action %s: source object was deleted — skipping.") % (action.func_name or action.uuid) ) @@ -315,7 +313,7 @@ def recompute_n_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> Non if panel_data.objmodel.has_uuid(uuid): src_objs.append(panel_data.objmodel[uuid]) if not src_objs: - panel._cascade_warnings.append( + panel.cascade_warnings.append( _("Action %s: all source objects were deleted — skipping.") % (action.func_name or action.uuid) ) @@ -373,7 +371,7 @@ def recompute_2_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> Non ) ) if len(src_uuids) < 2: - panel._cascade_warnings.append( + panel.cascade_warnings.append( _("Action %s: missing source(s) for output #%d — skipping.") % (action.func_name or action.uuid, idx + 1) ) @@ -382,7 +380,7 @@ def recompute_2_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> Non panel_data.objmodel.has_uuid(src_uuids[0]) and panel_data.objmodel.has_uuid(src_uuids[1]) ): - panel._cascade_warnings.append( + panel.cascade_warnings.append( _("Action %s: source object(s) were deleted — skipping.") % (action.func_name or action.uuid) ) @@ -435,7 +433,7 @@ def recompute_1_to_0_in_place(panel: HistoryPanel, action: HistoryAction) -> Non ) refresh_target(panel_data, uuid) if missing: - panel._cascade_warnings.append( + panel.cascade_warnings.append( _("Action %s: %d analysed object(s) were deleted — skipping.") % (action.func_name or action.uuid, len(missing)) ) @@ -451,14 +449,14 @@ def recompute_cascade( descendants = panel.get_downstream_actions(root_action) if root_action.is_stale: descendants = [root_action] + descendants - if getattr(panel, "_cascade_in_progress", False): + if getattr(panel, "cascade_in_progress", False): flush_cascade_warnings(panel) return if not descendants: flush_cascade_warnings(panel) return - panel._broken_actions.clear() - panel._cascade_in_progress = True + panel.broken_actions.clear() + panel.cascade_in_progress = True try: for action in descendants: action.is_stale = True @@ -468,27 +466,27 @@ def recompute_cascade( try: recompute_action_in_place(panel, action) finally: - if action.uuid not in panel._broken_actions: + if action.uuid not in panel.broken_actions: action.is_stale = False panel.tree.refresh_action_item(action) QW.QApplication.processEvents() finally: for action in descendants: - if action.is_stale and action.uuid not in panel._broken_actions: + if action.is_stale and action.uuid not in panel.broken_actions: action.is_stale = False panel.tree.refresh_action_item(action) - panel._cascade_in_progress = False + panel.cascade_in_progress = False flush_cascade_warnings(panel) def flush_cascade_warnings(panel: HistoryPanel) -> None: """Show + clear accumulated cascade warnings (no-op when empty).""" - if panel._cascade_warnings and not execenv.unattended: + if panel.cascade_warnings and not execenv.unattended: QW.QMessageBox.warning( panel.mainwindow, _("Cascade recompute"), _("Some downstream actions could not be recomputed:") + "\n\n• " - + "\n• ".join(panel._cascade_warnings), + + "\n• ".join(panel.cascade_warnings), ) - panel._cascade_warnings = [] + panel.cascade_warnings = [] diff --git a/datalab/h5/history.py b/datalab/h5/history.py index 55060006c..0b5b39c15 100644 --- a/datalab/h5/history.py +++ b/datalab/h5/history.py @@ -200,12 +200,12 @@ def import_dlhist_into_new_session(panel: HistoryPanel, reader: NativeH5Reader) new_session.number = panel.session_increment new_sessions.append(new_session) # Register output mappings for imported actions so that - # _resolve_target_outputs / get_downstream_actions work. + # resolve_target_outputs / get_downstream_actions work. for action in new_session.actions: if action.output_uuids: - panel._action_output_uuids[action.uuid] = list(action.output_uuids) + panel.action_output_uuids[action.uuid] = list(action.output_uuids) for out_uuid in action.output_uuids: - panel._output_to_action[out_uuid] = action.uuid + panel.output_to_action[out_uuid] = action.uuid panel.history_sessions.extend(new_sessions) panel.tree.populate_tree(panel.history_sessions) panel.refresh_compatibility_items() @@ -236,6 +236,7 @@ def deserialize_from_hdf5( reader: HDF5 reader reset_all: Unused (kept for compatibility with panel API) """ + del reset_all # required by the polymorphic panel API; unused here if panel.H5_PREFIX not in reader.h5: panel.history_sessions = [] panel.session_increment = 0 @@ -250,14 +251,14 @@ def deserialize_from_hdf5( # Rebuild the bijective mapping from the loaded actions. Legacy # (v1) actions have empty ``output_uuids`` and contribute nothing # to the index — the heuristic fallback handles them. - panel._action_output_uuids = {} - panel._output_to_action = {} + panel.action_output_uuids = {} + panel.output_to_action = {} for session in panel.history_sessions: for action in session.actions: if action.output_uuids: - panel._action_output_uuids[action.uuid] = list(action.output_uuids) + panel.action_output_uuids[action.uuid] = list(action.output_uuids) for out_uuid in action.output_uuids: - panel._output_to_action[out_uuid] = action.uuid + panel.output_to_action[out_uuid] = action.uuid panel.tree.populate_tree(panel.history_sessions) panel.refresh_compatibility_items() panel.update_actions_state() diff --git a/datalab/history/action.py b/datalab/history/action.py index 4d1907976..f415367fc 100644 --- a/datalab/history/action.py +++ b/datalab/history/action.py @@ -9,16 +9,13 @@ import json import logging import os +from contextlib import nullcontext from typing import TYPE_CHECKING, Any, Callable, Generator from uuid import uuid4 import sigima.proc.image import sigima.proc.signal from guidata.dataset.datatypes import DataSet -from sigima.objects import ( # noqa: F401 (kept for downstream consumers) - ImageObj, - SignalObj, -) from datalab.config import _ from datalab.gui import ObjItf @@ -60,6 +57,11 @@ class HistoryAction(ObjItf): # Methods that create new data objects. During non-persistent (output-suppressed) # replay, these UI actions are skipped so the panel object count stays stable. UI_CREATION_METHODS: frozenset[str] = frozenset({"new_object"}) + # UI methods that destroy data objects. Replaying these requires that the + # captured selection still resolves to existing objects (see ``_replay_ui``). + DESTRUCTIVE_METHODS: frozenset[str] = frozenset( + {"remove_object", "remove_group", "delete_all_objects"} + ) def __init__( self, @@ -375,8 +377,8 @@ def to_macro_code( imports.add(f"from {param_module} import {param_class}") lines.append(f"{param_var} = {param_class}()") # Reconstruct each attribute - for item in param._items: # noqa: SLF001 - attr_name = item._name # noqa: SLF001 + for item in param.get_items(): + attr_name = item.get_name() value = getattr(param, attr_name, None) if value is not None: lines.append(f"{param_var}.{attr_name} = {value!r}") @@ -495,8 +497,6 @@ def replay( if hpanel is not None: ctx = hpanel.replaying() else: - from contextlib import nullcontext - ctx = nullcontext() with ctx: self._replay_inner(mainwindow, restore_selection, edit, uuid_remap) @@ -523,7 +523,7 @@ def _replay_inner( translated = self._translate_state(uuid_remap) if translated.is_current_state_compatible(mainwindow, False): translated.restore(mainwindow) - self._replay_compute(mainwindow, edit, uuid_remap) + self.replay_compute(mainwindow, edit, uuid_remap) else: if restore_selection: self.state.restore(mainwindow) @@ -548,7 +548,7 @@ def _translate_state(self, uuid_remap: dict[str, dict[str, str]]) -> WorkspaceSt } return translated - def _replay_compute( + def replay_compute( self, mainwindow: DLMainWindow, edit: bool, @@ -615,8 +615,7 @@ def _replay_ui(self, mainwindow: DLMainWindow, edit: bool) -> None: # objects but the captured selection no longer resolves to existing # UUIDs in the target panel, skip the call rather than delete whatever # is currently selected (which would silently destroy unrelated data). - DESTRUCTIVE_METHODS = {"remove_object", "remove_group", "delete_all_objects"} - if self.method_name in DESTRUCTIVE_METHODS: + if self.method_name in self.DESTRUCTIVE_METHODS: if target is None: _logger.warning( "Skipping destructive replay '%s': target '%s' not found", @@ -632,7 +631,7 @@ def _replay_ui(self, mainwindow: DLMainWindow, edit: bool) -> None: if o is not None } captured = set(self.state.selection.get(panel_str, [])) - if not (captured & existing_uuids): + if not captured & existing_uuids: _logger.warning( "Skipping destructive replay '%s': none of the captured " "UUIDs %s exist in panel '%s' anymore", diff --git a/datalab/history/session.py b/datalab/history/session.py index 24a78a2f7..7566ed9e6 100644 --- a/datalab/history/session.py +++ b/datalab/history/session.py @@ -328,22 +328,7 @@ def _claim_unmapped( # (intermediate actions are implicitly "closed" by the next # iteration's input restore). if self.actions: - last = self.actions[-1] - if last.kind == HistoryAction.KIND_COMPUTE: - hpanel = getattr(mainwindow, "historypanel", None) - if hpanel is not None: - output_uuid = hpanel._action_output_uuid(last) - if output_uuid: - panel_str = last.panel_str or "" - panel_map = uuid_remap.get(panel_str, {}) - mapped_uuid = panel_map.get(output_uuid, output_uuid) - for panel in panels: - if panel.PANEL_STR_ID == panel_str: - try: - panel.objview.select_objects([mapped_uuid]) - except KeyError: - pass - break + select_last_compute_output(mainwindow, panels, uuid_remap, self.actions[-1]) def serialize(self, writer: NativeH5Writer) -> None: """Serialize this history session @@ -390,3 +375,39 @@ def remove_action(self, action: HistoryAction) -> None: if action in self.actions: index = self.actions.index(action) self.actions = self.actions[:index] + + +def select_last_compute_output( + mainwindow: DLMainWindow, + panels: tuple, + uuid_remap: dict[str, dict[str, str]], + last_action: HistoryAction, +) -> None: + """Select the output of the last compute action after a session replay. + + Visually closes the replay by highlighting the final result in its panel. + No-op when the last action is not a compute action or its output is gone. + + Args: + mainwindow: DataLab's main window + panels: signal and image panels + uuid_remap: per-panel ``{old_uuid: new_uuid}`` mapping built during replay + last_action: last action of the replayed session + """ + if last_action.kind != HistoryAction.KIND_COMPUTE: + return + hpanel = getattr(mainwindow, "historypanel", None) + if hpanel is None: + return + output_uuid = hpanel.action_output_uuid(last_action) + if not output_uuid: + return + panel_str = last_action.panel_str or "" + mapped_uuid = uuid_remap.get(panel_str, {}).get(output_uuid, output_uuid) + target_panel = next((p for p in panels if p.PANEL_STR_ID == panel_str), None) + if target_panel is None: + return + try: + target_panel.objview.select_objects([mapped_uuid]) + except KeyError: + pass diff --git a/datalab/tests/features/common/history_test.py b/datalab/tests/features/common/history_test.py index be259cc4b..9e6f51af4 100644 --- a/datalab/tests/features/common/history_test.py +++ b/datalab/tests/features/common/history_test.py @@ -147,27 +147,27 @@ def _record_three_action_session(win): def _build_cascade_chain(panel, history): """Build chain s001 -> gaussian -> s002 -> derivative -> s003 -> mavg -> s004. - Returns ``(action_A, action_B, action_C, output_B, output_C)``. + Returns ``(action_a, action_b, action_c, output_b, output_c)``. """ panel.add_object(create_paracetamol_signal()) panel.objview.select_objects([1]) panel.processor.run_feature( sips.gaussian_filter, sigima.params.GaussianParam.create(sigma=1.5) ) - action_A = history[len(history)] + action_a = history[len(history)] panel.objview.select_objects([2]) panel.processor.run_feature(sips.derivative) - action_B = history[len(history)] - output_B = panel.objmodel.get_object_from_number(3) + action_b = history[len(history)] + output_b = panel.objmodel.get_object_from_number(3) panel.objview.select_objects([3]) mavg = sigima.params.MovingAverageParam() mavg.n = 3 panel.processor.run_feature(sips.moving_average, mavg) - action_C = history[len(history)] - output_C = panel.objmodel.get_object_from_number(4) - return action_A, action_B, action_C, output_B, output_C + action_c = history[len(history)] + output_c = panel.objmodel.get_object_from_number(4) + return action_a, action_b, action_c, output_b, output_c # --------------------------------------------------------------------------- @@ -787,7 +787,7 @@ def capture_compute_n_to_1(*_args, **kwargs): kwargs={"pairwise": True}, state=WorkspaceState(), ) - action._replay_compute(win, edit=False) # noqa: SLF001 + action.replay_compute(win, edit=False) assert captured["pairwise"] is True # --- scenario: 2_to_1 with vanished obj2 raises ValueError --- @@ -829,7 +829,7 @@ def capture_compute_2_to_1(obj2_arg, *_args, **kwargs): kwargs={"obj2_uuids": ["recorded-obj2"], "pairwise": True}, state=WorkspaceState(), ) - action._replay_compute( # noqa: SLF001 + action.replay_compute( win, edit=False, uuid_remap={panel.PANEL_STR_ID: {"recorded-obj2": obj2_uuid}}, @@ -1209,16 +1209,16 @@ def test_history_stepping_and_selection_sync(): # --- scenario: step button enabled state reflects position --- with datalab_test_app_context() as win: history = win.historypanel - prev_btn = history._step_prev_action # noqa: SLF001 - next_btn = history._step_next_action # noqa: SLF001 + prev_btn = history.step_prev_action + next_btn = history.step_next_action history.update_actions_state() assert not prev_btn.isEnabled() assert not next_btn.isEnabled() _panel, history = _record_three_action_session(win) sessions = history.history_sessions actions = sessions[-1].actions - prev_btn = history._step_prev_action # noqa: SLF001 - next_btn = history._step_next_action # noqa: SLF001 + prev_btn = history.step_prev_action + next_btn = history.step_next_action _select_tree_item_for(history, actions[0]) assert not prev_btn.isEnabled() assert next_btn.isEnabled() @@ -1364,11 +1364,11 @@ def test_history_cascade_recompute(): history = win.historypanel history.toggle_record_mode(True) panel = win.signalpanel - action_A, action_B, action_C, _ob, _oc = _build_cascade_chain(panel, history) - downstream = history.get_downstream_actions(action_A) - assert downstream == [action_B, action_C] - assert history.get_downstream_actions(action_C) == [] - assert history.get_downstream_actions(action_B) == [action_C] + action_a, action_b, action_c, _ob, _oc = _build_cascade_chain(panel, history) + downstream = history.get_downstream_actions(action_a) + assert downstream == [action_b, action_c] + assert not history.get_downstream_actions(action_c) + assert history.get_downstream_actions(action_b) == [action_c] # --- scenario: cascade recompute updates downstream outputs in place --- with datalab_test_app_context() as win: @@ -1376,31 +1376,31 @@ def test_history_cascade_recompute(): history.toggle_record_mode(True) history.toggle_edit_mode(True) panel = win.signalpanel - action_A, action_B, action_C, output_B, output_C = _build_cascade_chain( + action_a, action_b, action_c, output_b, output_c = _build_cascade_chain( panel, history ) - uuid_B = get_uuid(output_B) - uuid_C = get_uuid(output_C) - data_B_before = output_B.xydata.copy() - data_C_before = output_C.xydata.copy() + uuid_b = get_uuid(output_b) + uuid_c = get_uuid(output_c) + data_b_before = output_b.xydata.copy() + data_c_before = output_c.xydata.copy() n_objects_before = len(panel.objmodel) - result_obj_A = panel.objmodel.get_object_from_number(2) + result_obj_a = panel.objmodel.get_object_from_number(2) panel.objview.select_objects([2]) - assert panel.objprop.setup_processing_tab(result_obj_A, reset_params=False) + assert panel.objprop.setup_processing_tab(result_obj_a, reset_params=False) editor = panel.objprop.processing_param_editor assert editor is not None editor.dataset.sigma = 6.0 report = panel.objprop.apply_processing_parameters( - result_obj_A, interactive=False + result_obj_a, interactive=False ) assert report.success - assert action_A.kwargs["param"].sigma == 6.0 + assert action_a.kwargs["param"].sigma == 6.0 assert len(panel.objmodel) == n_objects_before - assert get_uuid(panel.objmodel[uuid_B]) == uuid_B - assert get_uuid(panel.objmodel[uuid_C]) == uuid_C - assert not np.array_equal(panel.objmodel[uuid_B].xydata, data_B_before) - assert not np.array_equal(panel.objmodel[uuid_C].xydata, data_C_before) - for a in (action_A, action_B, action_C): + assert get_uuid(panel.objmodel[uuid_b]) == uuid_b + assert get_uuid(panel.objmodel[uuid_c]) == uuid_c + assert not np.array_equal(panel.objmodel[uuid_b].xydata, data_b_before) + assert not np.array_equal(panel.objmodel[uuid_c].xydata, data_c_before) + for a in (action_a, action_b, action_c): assert a.is_stale is False # --- scenario: play on stale action triggers cascade --- @@ -1408,16 +1408,16 @@ def test_history_cascade_recompute(): history = win.historypanel history.toggle_record_mode(True) panel = win.signalpanel - action_A, action_B, _aC, output_B, _oC = _build_cascade_chain(panel, history) - uuid_B = get_uuid(output_B) - output_B.xydata = output_B.xydata * 0.0 - tampered = output_B.xydata.copy() - action_A.is_stale = True - _select_tree_item_for(history, action_A) + action_a, action_b, _ac, output_b, _oc = _build_cascade_chain(panel, history) + uuid_b = get_uuid(output_b) + output_b.xydata = output_b.xydata * 0.0 + tampered = output_b.xydata.copy() + action_a.is_stale = True + _select_tree_item_for(history, action_a) history.replay_restore_actions(replay=True, restore_selection=False) - assert action_A.is_stale is False - assert action_B.is_stale is False - assert not np.array_equal(panel.objmodel[uuid_B].xydata, tampered) + assert action_a.is_stale is False + assert action_b.is_stale is False + assert not np.array_equal(panel.objmodel[uuid_b].xydata, tampered) # --- scenario: cascade in a duplicated session that is NOT [-1] --- with datalab_test_app_context() as win: @@ -1425,9 +1425,9 @@ def test_history_cascade_recompute(): history.toggle_record_mode(True) history.toggle_edit_mode(True) panel = win.signalpanel - action_A, _aB, _aC, _oB, output_C = _build_cascade_chain(panel, history) - uuid_C_orig = get_uuid(output_C) - data_C_orig = output_C.xydata.copy() + action_a, _ab, _ac, _ob, output_c = _build_cascade_chain(panel, history) + uuid_c_orig = get_uuid(output_c) + data_c_orig = output_c.xydata.copy() panel.objview.select_objects([4]) panel.processor.run_feature(sips.derivative) sessions = history.history_sessions @@ -1442,33 +1442,31 @@ def test_history_cascade_recompute(): assert len(sessions) == 3 dup_session = sessions[1] assert sessions[-1] is not dup_session - dup_action_A = next( - a for a in dup_session.actions if a.func_name == action_A.func_name + dup_action_a = next( + a for a in dup_session.actions if a.func_name == action_a.func_name ) - dup_action_C = next( + dup_action_c = next( a for a in dup_session.actions if a.func_name == "moving_average" ) - dup_output_C_uuid = history._action_output_uuid(dup_action_C) # noqa: SLF001 - assert dup_output_C_uuid is not None - data_dup_C_before = panel.objmodel[dup_output_C_uuid].xydata.copy() - dup_result_obj_A_uuid = history._action_output_uuid( # noqa: SLF001 - dup_action_A - ) - assert dup_result_obj_A_uuid is not None - dup_result_obj_A = panel.objmodel[dup_result_obj_A_uuid] - panel.objview.select_objects([dup_result_obj_A_uuid]) - assert panel.objprop.setup_processing_tab(dup_result_obj_A, reset_params=False) + dup_output_c_uuid = history.action_output_uuid(dup_action_c) + assert dup_output_c_uuid is not None + data_dup_c_before = panel.objmodel[dup_output_c_uuid].xydata.copy() + dup_result_obj_a_uuid = history.action_output_uuid(dup_action_a) + assert dup_result_obj_a_uuid is not None + dup_result_obj_a = panel.objmodel[dup_result_obj_a_uuid] + panel.objview.select_objects([dup_result_obj_a_uuid]) + assert panel.objprop.setup_processing_tab(dup_result_obj_a, reset_params=False) editor = panel.objprop.processing_param_editor assert editor is not None editor.dataset.sigma = 10.0 report = panel.objprop.apply_processing_parameters( - dup_result_obj_A, interactive=False + dup_result_obj_a, interactive=False ) assert report.success assert not np.array_equal( - panel.objmodel[dup_output_C_uuid].xydata, data_dup_C_before + panel.objmodel[dup_output_c_uuid].xydata, data_dup_c_before ) - assert np.array_equal(panel.objmodel[uuid_C_orig].xydata, data_C_orig) + assert np.array_equal(panel.objmodel[uuid_c_orig].xydata, data_c_orig) # --------------------------------------------------------------------------- diff --git a/datalab/widgets/historydescription.py b/datalab/widgets/historydescription.py index 8fdbd22de..e2ca7945a 100644 --- a/datalab/widgets/historydescription.py +++ b/datalab/widgets/historydescription.py @@ -64,11 +64,13 @@ def html_matches_summary(self) -> bool: return self._html.strip() == html.escape(self._summary).strip() def on_toggled(self, checked: bool) -> None: + """Handle the expand/collapse toggle being toggled.""" self._expanded = checked self.refresh_widget() self.toggled.emit(checked) def refresh_widget(self) -> None: + """Refresh the widget contents to match the current expanded state.""" if self._expanded: self._toggle.setArrowType(QC.Qt.DownArrow) self._toggle.setToolTip(_("Hide details")) From b95c62e97264d1f7315fc04f06055c351be873e7 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Mon, 29 Jun 2026 15:05:00 +0200 Subject: [PATCH 025/108] Feat: Make object creation actions editable in the history panel Creation actions (new signal/image) were recorded in the history but, unlike process actions, could not be edited, recomputed or reverted. Editing a creation left downstream steps inconsistent. This makes creations first-class history actions: their parameters can be re-edited, the result is recomputed in place (keeping the UUID and downstream references), and the chain cascades correctly. * [NEW] : Allow editing creation (new_object) parameters via dialog and recompute in place, preserving the output UUID so downstream actions stay linked * [NEW] : Resolve target panel for UI creation actions so they replay and cascade like compute actions * [CHG] : add_ui_entry now returns the created HistoryAction, enabling creation output_uuids to be registered for downstream resolution * [CHG] : Restore/undo without saving now covers creation actions for both single action and full session * [FIX] : Snapshot creation parameters on edit for proper export/import and revert --- datalab/gui/historysession_ops.py | 9 +- datalab/gui/panel/history/chain.py | 8 +- .../gui/panel/history/interactive_replay.py | 32 ++++++- datalab/gui/panel/history/panel.py | 2 +- datalab/gui/panel/history/recompute.py | 44 +++++++++ datalab/gui/panel/image.py | 6 +- datalab/gui/panel/signal.py | 7 +- datalab/tests/features/common/history_test.py | 89 +++++++++++++++++++ 8 files changed, 189 insertions(+), 8 deletions(-) diff --git a/datalab/gui/historysession_ops.py b/datalab/gui/historysession_ops.py index 1d31be238..fd9ef2378 100644 --- a/datalab/gui/historysession_ops.py +++ b/datalab/gui/historysession_ops.py @@ -239,7 +239,7 @@ def add_ui_entry( method_name: str, save_state: bool = True, **kwargs: Any, -) -> None: +) -> HistoryAction | None: """Record a *UI* action in the current history session. Args: @@ -250,9 +250,13 @@ def add_ui_entry( save_state: If True, capture the workspace state for replay. **kwargs: Method keyword arguments. ``DataSet`` instances are serialised as JSON; other values must be HDF5-friendly primitives. + + Returns: + The created :class:`HistoryAction`, or ``None`` if recording is + disabled (record mode off or replay in progress). """ if not panel.record_mode_enabled or panel.is_replaying(): - return + return None state = WorkspaceState() if save_state: state.save(panel.mainwindow) @@ -267,6 +271,7 @@ def add_ui_entry( state=state, ) panel.add_object(action) + return action def add_entry( diff --git a/datalab/gui/panel/history/chain.py b/datalab/gui/panel/history/chain.py index 67d0906d4..17384b382 100644 --- a/datalab/gui/panel/history/chain.py +++ b/datalab/gui/panel/history/chain.py @@ -41,7 +41,13 @@ def resolve_panel_for_action( panel: HistoryPanel, action: HistoryAction ) -> BaseDataPanel | None: """Return the data panel targeted by ``action``, or ``None``.""" - if action.kind != HistoryAction.KIND_COMPUTE: + if action.kind == HistoryAction.KIND_UI: + if action.method_name not in HistoryAction.UI_CREATION_METHODS: + return None + if action.target == "signalpanel": + return panel.mainwindow.signalpanel + if action.target == "imagepanel": + return panel.mainwindow.imagepanel return None if action.panel_str == "signal": return panel.mainwindow.signalpanel diff --git a/datalab/gui/panel/history/interactive_replay.py b/datalab/gui/panel/history/interactive_replay.py index 07fa37356..fd8063845 100644 --- a/datalab/gui/panel/history/interactive_replay.py +++ b/datalab/gui/panel/history/interactive_replay.py @@ -70,6 +70,19 @@ def prompt_edit_action_params( panel: HistoryPanel, action: HistoryAction ) -> bool | None: """Open the parameter dialog for *action* according to its pattern.""" + if ( + action.kind == HistoryAction.KIND_UI + and action.method_name in HistoryAction.UI_CREATION_METHODS + ): + param = action.kwargs.get("param") + if param is None: + return None + edited = copy.deepcopy(param) + if not edited.edit(parent=panel.mainwindow): + return False + action.snapshot_kwargs() + action.kwargs["param"] = edited + return True pattern = action.pattern if pattern in {"1_to_1", "1_to_0", "n_to_1", "2_to_1"}: param = action.kwargs.get("param") @@ -96,7 +109,14 @@ def prompt_edit_action_params( def edit_mode_replay(panel: HistoryPanel, action: HistoryAction) -> None: """Replay a single action in edit mode: open param dialog, update kwargs.""" - if action.kind != HistoryAction.KIND_COMPUTE or action.pattern is None: + is_creation = ( + action.kind == HistoryAction.KIND_UI + and action.method_name in HistoryAction.UI_CREATION_METHODS + ) + is_compute = ( + action.kind == HistoryAction.KIND_COMPUTE and action.pattern is not None + ) + if not is_creation and not is_compute: with panel.replaying(), panel.output_suppressed(): action.replay(panel.mainwindow, restore_selection=True, edit=True) return @@ -181,7 +201,15 @@ def restore_action_params( """Restore original kwargs from snapshot and recompute in-place.""" actions: list[HistoryAction] if isinstance(item, HistorySession): - actions = [a for a in item.actions if a.kind == HistoryAction.KIND_COMPUTE] + actions = [ + a + for a in item.actions + if a.kind == HistoryAction.KIND_COMPUTE + or ( + a.kind == HistoryAction.KIND_UI + and a.method_name in HistoryAction.UI_CREATION_METHODS + ) + ] else: actions = [item] for action in actions: diff --git a/datalab/gui/panel/history/panel.py b/datalab/gui/panel/history/panel.py index e4c74b722..2cfc88b74 100644 --- a/datalab/gui/panel/history/panel.py +++ b/datalab/gui/panel/history/panel.py @@ -852,7 +852,7 @@ def add_ui_entry( method_name: str, save_state: bool = True, **kwargs: Any, - ) -> None: + ) -> HistoryAction | None: """Add a UI entry to the history.""" return hsess.add_ui_entry( self, action_title, target, method_name, save_state, **kwargs diff --git a/datalab/gui/panel/history/recompute.py b/datalab/gui/panel/history/recompute.py index 1505d6cbe..2f0fde07e 100644 --- a/datalab/gui/panel/history/recompute.py +++ b/datalab/gui/panel/history/recompute.py @@ -112,6 +112,12 @@ def record_missing_outputs( def recompute_action_in_place(panel: HistoryPanel, action: HistoryAction) -> None: """Re-run ``action`` on the existing output object(s) (same UUIDs).""" + if ( + action.kind == HistoryAction.KIND_UI + and action.method_name in HistoryAction.UI_CREATION_METHODS + ): + recompute_creation_in_place(panel, action) + return if action.kind != HistoryAction.KIND_COMPUTE: return method = { @@ -179,6 +185,44 @@ def handle_missing_feature( ) +def recompute_creation_in_place(panel: HistoryPanel, action: HistoryAction) -> None: + """Recompute a creation (``new_object``) action in place. + + Rebuild the object from the edited ``param`` and copy it onto the + existing output object so its UUID (and downstream references) are kept. + """ + # Local import to avoid a circular dependency at module load time. + from datalab.gui.newobject import ( + create_image_gui, + create_signal_gui, + insert_creation_parameters, + ) + + panel_data = panel.resolve_panel_for_action(action) + if panel_data is None: + return + existing, missing = panel.resolve_target_outputs(panel_data, action) + record_missing_outputs(panel, action, missing) + if not existing: + return + output_uuid = existing[0] + if not panel_data.objmodel.has_uuid(output_uuid): + return + output_obj = panel_data.objmodel[output_uuid] + param = action.kwargs.get("param") + if param is None: + return + if action.target == "signalpanel": + new_obj = create_signal_gui(param, edit=False) + else: + new_obj = create_image_gui(param, edit=False) + if new_obj is None: + return + update_obj_in_place(output_obj, new_obj) + insert_creation_parameters(output_obj, param) + refresh_target(panel_data, output_uuid) + + def recompute_1_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> None: """Recompute a single 1-to-1 action in place.""" panel_data = panel.resolve_panel_for_action(action) diff --git a/datalab/gui/panel/image.py b/datalab/gui/panel/image.py index 75c727fec..c41bbddeb 100644 --- a/datalab/gui/panel/image.py +++ b/datalab/gui/panel/image.py @@ -255,7 +255,7 @@ def new_object( image = create_image_gui(param, edit=edit, parent=self.parentWidget()) if image is None: return None - self.mainwindow.historypanel.add_ui_entry( + action = self.mainwindow.historypanel.add_ui_entry( _("New image"), target="imagepanel", method_name="new_object", @@ -265,6 +265,10 @@ def new_object( ) if add_to_panel: self.add_object(image) + if action is not None: + self.mainwindow.historypanel.register_action_outputs( + action, [get_uuid(image)] + ) return image def toggle_show_contrast(self, state: bool) -> None: diff --git a/datalab/gui/panel/signal.py b/datalab/gui/panel/signal.py index d147f363a..5dcb83449 100644 --- a/datalab/gui/panel/signal.py +++ b/datalab/gui/panel/signal.py @@ -32,6 +32,7 @@ from datalab.gui.panel.base import BaseDataPanel from datalab.gui.plothandler import SignalPlotHandler from datalab.gui.processor.signal import SignalProcessor +from datalab.objectmodel import get_uuid if TYPE_CHECKING: from qtpy import QtWidgets as QW @@ -146,7 +147,7 @@ def new_object( signal = create_signal_gui(param, edit=edit, parent=self.parentWidget()) if signal is None: return None - self.mainwindow.historypanel.add_ui_entry( + action = self.mainwindow.historypanel.add_ui_entry( _("New signal"), target="signalpanel", method_name="new_object", @@ -156,6 +157,10 @@ def new_object( ) if add_to_panel: self.add_object(signal) + if action is not None: + self.mainwindow.historypanel.register_action_outputs( + action, [get_uuid(signal)] + ) return signal # ------Plotting-------------------------------------------------------------------- diff --git a/datalab/tests/features/common/history_test.py b/datalab/tests/features/common/history_test.py index 9e6f51af4..d1a857fa0 100644 --- a/datalab/tests/features/common/history_test.py +++ b/datalab/tests/features/common/history_test.py @@ -1469,6 +1469,95 @@ def test_history_cascade_recompute(): assert np.array_equal(panel.objmodel[uuid_c_orig].xydata, data_c_orig) +# --------------------------------------------------------------------------- +# 9b) Creation action editing +# --------------------------------------------------------------------------- + + +def test_history_edit_creation(): + """Edit a creation action: update params, cascade downstream, restore.""" + from datalab.gui.panel.history import recompute as hrec + + # --- scenario: editing a created Gauss signal cascades to downstream --- + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + history.toggle_edit_mode(True) + panel = win.signalpanel + gparam = sigima.objects.create_signal_parameters( + sigima.objects.SignalTypes.GAUSS, size=200, sigma=20.0 + ) + signal = panel.new_object(gparam, edit=False) + assert signal is not None + creation = history[len(history)] + assert creation.kind == HistoryAction.KIND_UI + assert creation.method_name == "new_object" + creation_uuid = get_uuid(signal) + assert history.action_output_uuid(creation) == creation_uuid + + panel.objview.select_objects([1]) + panel.processor.run_feature( + sips.gaussian_filter, sigima.params.GaussianParam.create(sigma=1.5) + ) + filter_action = history[len(history)] + output_filter = panel.objmodel.get_object_from_number(2) + uuid_filter = get_uuid(output_filter) + + assert history.get_downstream_actions(creation) == [filter_action] + + creation_data_before = signal.xydata.copy() + filter_data_before = output_filter.xydata.copy() + desc_before = creation.description + + creation.snapshot_kwargs() + creation.kwargs["param"].sigma = 60.0 + hrec.recompute_action_in_place(history, creation) + hrec.recompute_cascade(history, creation, descendants=[filter_action]) + + assert creation.has_pending_edits + assert "60" in creation.description + assert creation.description != desc_before + assert not np.array_equal(signal.xydata, creation_data_before) + assert not np.array_equal( + panel.objmodel[uuid_filter].xydata, filter_data_before + ) + + creation.restore_kwargs() + hrec.recompute_action_in_place(history, creation) + hrec.recompute_cascade(history, creation, descendants=[filter_action]) + assert not creation.has_pending_edits + assert creation.kwargs["param"].sigma == 20.0 + assert np.allclose(signal.xydata, creation_data_before) + + # --- scenario: edited snapshot survives HDF5 round-trip --- + gparam = sigima.objects.create_signal_parameters( + sigima.objects.SignalTypes.GAUSS, size=64, sigma=20.0 + ) + action = HistoryAction( + title="New signal", + kind=HistoryAction.KIND_UI, + target="signalpanel", + method_name="new_object", + kwargs={"param": gparam}, + state=WorkspaceState(), + ) + action.snapshot_kwargs() + action.kwargs["param"].sigma = 50.0 + session = HistorySession(number=1) + session.add_action(action) + with tempfile.TemporaryDirectory() as tmpdir: + path = os.path.join(tmpdir, "creation_roundtrip.dlhist") + with NativeH5Writer(path) as writer: + writer.write_object_list([session], "history_session") + with NativeH5Reader(path) as reader: + restored_sessions = reader.read_object_list( + "history_session", HistorySession + ) + restored_action = restored_sessions[0].actions[0] + assert restored_action.has_pending_edits + assert restored_action.kwargs["param"].sigma == 50.0 + + # --------------------------------------------------------------------------- # 10) Chain reconnect after object deletion # --------------------------------------------------------------------------- From 2a1e7f600e1faf16c0b2d801c9b11129243691f6 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Mon, 29 Jun 2026 15:35:00 +0200 Subject: [PATCH 026/108] Fix: Redundant edit-mode replay dialogs and incomplete downstream recompute Edit-mode replay opened parameter dialogs per selected action, each editing its own downstream chain. Overlapping chains caused repeated prompts and inconsistent state. Recompute also stopped at the edited action instead of cascading to the full downstream. * [FIX] : Process selected actions once via edit_mode_replay_actions, with deduplication, session-order sorting and a re-entrance guard, instead of calling edit_mode_replay per action * [FIX] : Replay only the selected actions; on param change, recompute in place then cascade fully downstream from the most upstream edited action * [CHG] : Cancel restores parameter snapshots for already-edited actions --- .../gui/panel/history/interactive_replay.py | 111 +++++++++++++----- 1 file changed, 79 insertions(+), 32 deletions(-) diff --git a/datalab/gui/panel/history/interactive_replay.py b/datalab/gui/panel/history/interactive_replay.py index fd8063845..1fa27dd05 100644 --- a/datalab/gui/panel/history/interactive_replay.py +++ b/datalab/gui/panel/history/interactive_replay.py @@ -33,6 +33,7 @@ def replay_restore_actions( if not panel.history_sessions: return selected = [panel.history_sessions[-1]] + edit_actions: list[HistoryAction] = [] for session_or_action in selected: if isinstance(session_or_action, HistoryAction) and session_or_action.is_stale: hrec.recompute_cascade(panel, session_or_action) @@ -49,7 +50,8 @@ def replay_restore_actions( return if replay: if panel.edit_mode and isinstance(session_or_action, HistoryAction): - edit_mode_replay(panel, session_or_action) + # Defer: edit only the selected actions, no automatic cascade + edit_actions.append(session_or_action) elif panel.edit_mode and isinstance(session_or_action, HistorySession): view_only_session_replay(panel, session_or_action, restore_selection) else: @@ -64,6 +66,8 @@ def replay_restore_actions( restore_action_params(panel, session_or_action) else: session_or_action.restore(panel.mainwindow) + if edit_actions: + edit_mode_replay_actions(panel, edit_actions) def prompt_edit_action_params( @@ -108,41 +112,84 @@ def prompt_edit_action_params( def edit_mode_replay(panel: HistoryPanel, action: HistoryAction) -> None: - """Replay a single action in edit mode: open param dialog, update kwargs.""" - is_creation = ( - action.kind == HistoryAction.KIND_UI - and action.method_name in HistoryAction.UI_CREATION_METHODS - ) - is_compute = ( - action.kind == HistoryAction.KIND_COMPUTE and action.pattern is not None - ) - if not is_creation and not is_compute: - with panel.replaying(), panel.output_suppressed(): - action.replay(panel.mainwindow, restore_selection=True, edit=True) - return + """Replay a single action in edit mode: open param dialog, update kwargs. - chain: list[HistoryAction] = [action] + panel.get_downstream_actions(action) - edited_actions: list[HistoryAction] = [] - for a in chain: - result = prompt_edit_action_params(panel, a) - if result is False: - for done in edited_actions: - done.restore_kwargs() - panel.tree.refresh_action_item(done) - return - if result is True: - edited_actions.append(a) + Only the given action is edited and recomputed in place: no automatic + cascade towards unselected downstream actions. + """ + edit_mode_replay_actions(panel, [action]) - for a in edited_actions: - panel.tree.refresh_action_item(a) - downstream = chain[1:] - hrec.recompute_action_in_place(panel, action) - hrec.recompute_cascade(panel, action, descendants=downstream) +def edit_mode_replay_actions(panel: HistoryPanel, actions: list[HistoryAction]) -> None: + """Edit and recompute only the selected actions, in session order. - for a in chain: - panel.tree.refresh_action_item(a) - QW.QApplication.processEvents() + Each selected action gets exactly one parameter dialog; non-selected + downstream actions are left untouched (no automatic cascade). A + re-entrance guard prevents nested prompt loops. + """ + if getattr(panel, "_edit_replay_in_progress", False): + return + # Deduplicate and sort the selected actions in their session order + ordered = _order_selected_actions(panel, actions) + if not ordered: + return + panel._edit_replay_in_progress = True + try: + edited_actions: list[HistoryAction] = [] + recomputable: list[HistoryAction] = [] + for action in ordered: + is_creation = ( + action.kind == HistoryAction.KIND_UI + and action.method_name in HistoryAction.UI_CREATION_METHODS + ) + is_compute = ( + action.kind == HistoryAction.KIND_COMPUTE and action.pattern is not None + ) + if not is_creation and not is_compute: + with panel.replaying(), panel.output_suppressed(): + action.replay(panel.mainwindow, restore_selection=True, edit=True) + continue + result = prompt_edit_action_params(panel, action) + if result is False: + for done in edited_actions: + done.restore_kwargs() + panel.tree.refresh_action_item(done) + return + if result is True: + edited_actions.append(action) + recomputable.append(action) + + for action in edited_actions: + panel.tree.refresh_action_item(action) + for action in recomputable: + hrec.recompute_action_in_place(panel, action) + panel.tree.refresh_action_item(action) + if edited_actions: + hrec.recompute_cascade(panel, edited_actions[0]) + QW.QApplication.processEvents() + finally: + panel._edit_replay_in_progress = False + + +def _order_selected_actions( + panel: HistoryPanel, actions: list[HistoryAction] +) -> list[HistoryAction]: + """Deduplicate ``actions`` and sort them by (session, position) order.""" + rank: dict[str, int] = {} + pos = 0 + for session in panel.history_sessions: + for action in session.actions: + rank[action.uuid] = pos + pos += 1 + seen: set[str] = set() + unique: list[HistoryAction] = [] + for action in actions: + if action.uuid in seen: + continue + seen.add(action.uuid) + unique.append(action) + unique.sort(key=lambda a: rank.get(a.uuid, 0)) + return unique def show_readonly_param_dialog( From 25bd3ec57193ef290f6c4afeb1dd4a48544a9539 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Mon, 29 Jun 2026 16:05:00 +0200 Subject: [PATCH 027/108] Feat: Creation parameters tab cascades downstream recompute + plugin/macro objects recorded in history Editing parameters in the 'Creation parameters' tab only warned that the object was modified in-place, leaving downstream computations stale; users had to redo them manually. Objects added programmatically (plugins, macros, remote control) were also absent from the history, and non-native cross-panel computes created a spurious creation entry duplicating the recorded compute. * [CHG] : Apply creation parameters now finds the originating creation action (via output_to_action with creation-method fallback), snapshots the params, refreshes the tree and cascades recompute to downstream actions, replacing the static 'modified in-place' warning * [NEW] : Objects added through add_object (plugins, macros, remote) are recorded as creation entries in the history, including the very first one * [FIX] : Route non-native cross-panel computes directly to the target panel.add_object instead of mainwindow.add_object, avoiding a duplicate creation entry alongside the compute entry --- datalab/gui/main.py | 16 ++++++++++++- datalab/gui/panel/base.py | 30 ++++++++++++++++-------- datalab/gui/panel/history/chain.py | 37 ++++++++++++++++++++++++++++++ datalab/gui/panel/history/panel.py | 4 ++++ datalab/gui/processor/base.py | 11 +++++++-- 5 files changed, 85 insertions(+), 13 deletions(-) diff --git a/datalab/gui/main.py b/datalab/gui/main.py index cc98e81da..fe73dbc1c 100644 --- a/datalab/gui/main.py +++ b/datalab/gui/main.py @@ -78,7 +78,7 @@ from datalab.gui.panel import base, history, image, macro, signal from datalab.gui.pluginconfig import PluginConfigDialog from datalab.gui.settings import AI_OPTION_NAMES, edit_settings -from datalab.objectmodel import ObjectGroup +from datalab.objectmodel import ObjectGroup, get_uuid from datalab.plugins import PluginRegistry, discover_plugins, discover_v020_plugins from datalab.utils import qthelpers as qth from datalab.utils.qthelpers import ( @@ -2337,10 +2337,24 @@ def add_object( if self.confirm_memory_state(): if isinstance(obj, SignalObj): self.signalpanel.add_object(obj, group_id, set_current) + panel_str = "signal" elif isinstance(obj, ImageObj): self.imagepanel.add_object(obj, group_id, set_current) + panel_str = "image" else: raise TypeError(f"Unsupported object type {type(obj)}") + # Record a creation entry so objects added programmatically (plugins, + # macros, remote control) appear in the history. ``panel.add_object`` + # deliberately does not record, so creations entering through this + # proxy boundary would otherwise be lost (notably the very first one). + action = self.historypanel.add_ui_entry( + _("New %s") % panel_str, + target=panel_str + "panel", + method_name="new_object", + save_state=False, + ) + if action is not None: + self.historypanel.register_action_outputs(action, [get_uuid(obj)]) @remote_controlled def set_object(self, obj: SignalObj | ImageObj) -> None: diff --git a/datalab/gui/panel/base.py b/datalab/gui/panel/base.py index 46e46de97..f641e17e2 100644 --- a/datalab/gui/panel/base.py +++ b/datalab/gui/panel/base.py @@ -597,16 +597,6 @@ def apply_creation_parameters(self) -> None: editor = self.creation_param_editor if editor is None or self.current_creation_obj is None: return - if isinstance(self.current_creation_obj, SignalObj): - otext = _("Signal was modified in-place.") - else: - otext = _("Image was modified in-place.") - text = f"⚠️ {otext} ⚠️ " - text += _( - "If computation were performed based on this object, " - "they may need to be redone." - ) - self.panel.SIG_STATUS_MESSAGE.emit(text, 20000) # Recreate object with new parameters # (serialization is done automatically in create_signal/image_from_param) @@ -645,6 +635,20 @@ def apply_creation_parameters(self) -> None: obj_processor = self.__get_processor_associated_to(self.current_creation_obj) obj_processor.auto_recompute_analysis(self.current_creation_obj) + # Propagate the edited param to the History panel: mutate the matching + # creation action (snapshot originals first), refresh its tree display, + # then cascade recompute to downstream actions so the chain stays + # consistent with the new creation parameters. Creation actions are + # KIND_UI without a func_name, so look them up via output_to_action. + hpanel = getattr(self.panel.mainwindow, "historypanel", None) + if hpanel is not None: + action = hpanel.find_creation_action_for_output(obj_uuid) + if action is not None: + action.snapshot_kwargs() + action.kwargs["param"] = copy.deepcopy(param) + hpanel.refresh_action(action) + hpanel.recompute_cascade(action) + # Update the tree view item (to show new title if it changed) self.panel.objview.update_item(obj_uuid) @@ -657,6 +661,12 @@ def apply_creation_parameters(self) -> None: # (e.g., data type, dimensions, etc.) self.__update_properties_dataset(self.current_creation_obj) + if isinstance(self.current_creation_obj, SignalObj): + text = _("Signal was recreated.") + else: + text = _("Image was recreated.") + self.panel.SIG_STATUS_MESSAGE.emit("✅ " + text, 5000) + # Refresh the Creation tab with the new parameters # Use QTimer to defer this until after the current event is processed # Set the Creation tab as current to keep it visible after refresh diff --git a/datalab/gui/panel/history/chain.py b/datalab/gui/panel/history/chain.py index 17384b382..954db42b5 100644 --- a/datalab/gui/panel/history/chain.py +++ b/datalab/gui/panel/history/chain.py @@ -132,6 +132,43 @@ def find_action_for_output( return None +def find_creation_action_for_output( + panel: HistoryPanel, output_uuid: str +) -> HistoryAction | None: + """Find the creation (``new_object``) action that produced ``output_uuid``. + + Creation actions are ``KIND_UI`` entries without a ``func_name`` so the + standard :func:`find_action_for_output` lookup cannot match them. The + bijective ``output_to_action`` mapping is consulted first; if no mapping + exists, a fallback scan looks for a creation action whose registered + output UUIDs include ``output_uuid``. + """ + if not panel.history_sessions: + return None + action_uuid = panel.output_to_action.get(output_uuid) + if action_uuid is not None: + mapped = next( + ( + action + for session in panel.history_sessions + for action in session.actions + if action.uuid == action_uuid + ), + None, + ) + if mapped is not None and mapped.kind == HistoryAction.KIND_UI: + return mapped + for session in reversed(panel.history_sessions): + for action in reversed(session.actions): + if ( + action.kind == HistoryAction.KIND_UI + and action.method_name in HistoryAction.UI_CREATION_METHODS + and output_uuid in panel.action_output_uuids.get(action.uuid, []) + ): + return action + return None + + def get_session_of(panel: HistoryPanel, action: HistoryAction) -> HistorySession | None: """Return the session that contains ``action``, or None.""" for session in panel.history_sessions: diff --git a/datalab/gui/panel/history/panel.py b/datalab/gui/panel/history/panel.py index 2cfc88b74..bfed85742 100644 --- a/datalab/gui/panel/history/panel.py +++ b/datalab/gui/panel/history/panel.py @@ -436,6 +436,10 @@ def find_action_for_output( """Find the action that produced ``output_uuid``.""" return hchain.find_action_for_output(self, output_uuid, func_name) + def find_creation_action_for_output(self, output_uuid: str) -> HistoryAction | None: + """Find the creation action that produced ``output_uuid``.""" + return hchain.find_creation_action_for_output(self, output_uuid) + def get_session_of(self, action: HistoryAction) -> HistorySession | None: """Return the session that contains ``action``, or None.""" return hchain.get_session_of(self, action) diff --git a/datalab/gui/processor/base.py b/datalab/gui/processor/base.py index dec384ffb..66124c238 100644 --- a/datalab/gui/processor/base.py +++ b/datalab/gui/processor/base.py @@ -941,10 +941,17 @@ def _add_object_to_appropriate_panel( if is_new_obj_native: self.panel.add_object(new_obj, group_id=group_id) else: + # Route directly to the target panel to avoid the creation entry + # that mainwindow.add_object records (which would duplicate the + # compute entry already recorded by the processor). + if isinstance(new_obj, SignalObj): + target_panel = self.panel.mainwindow.signalpanel + else: + target_panel = self.panel.mainwindow.imagepanel if use_group_for_non_native: - self.panel.mainwindow.add_object(new_obj, group_id=group_id) + target_panel.add_object(new_obj, group_id=group_id) else: - self.panel.mainwindow.add_object(new_obj) + target_panel.add_object(new_obj) def _create_group_for_result( self, new_obj: SignalObj | ImageObj, group_name: str From 3e7bb5a41aac99ca9b758e8bef0c37a5c8b36a82 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Mon, 29 Jun 2026 16:20:00 +0200 Subject: [PATCH 028/108] Fix: Deleting an image history action no longer switches to Signal panel --- datalab/gui/historytools_ops.py | 38 ++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/datalab/gui/historytools_ops.py b/datalab/gui/historytools_ops.py index e4d29c8bb..25d980d68 100644 --- a/datalab/gui/historytools_ops.py +++ b/datalab/gui/historytools_ops.py @@ -386,6 +386,17 @@ def delete_selected(panel: HistoryPanel) -> None: ) if reply != QW.QMessageBox.Yes: return + # Memorize affected session for post-deletion selection + affected_session: HistorySession | None = None + for item in selected: + if isinstance(item, HistoryAction): + for session in panel.history_sessions: + if item in session.actions: + affected_session = session + break + if affected_session is not None: + break + sessions_to_remove: set[int] = set() for item in selected: if isinstance(item, HistorySession): @@ -404,11 +415,28 @@ def delete_selected(panel: HistoryPanel) -> None: panel.tree.populate_tree(panel.history_sessions) panel.refresh_compatibility_items() panel.update_actions_state() - # Auto-select the first available item after deletion - if panel.tree.topLevelItemCount() > 0: - first = panel.tree.topLevelItem(0) - panel.tree.setCurrentItem(first) - first.setSelected(True) + # Auto-select an item in the same session to avoid panel switch + target_item = None + if affected_session is not None and id(affected_session) not in sessions_to_remove: + # Find the tree item for the affected session (same index in list) + try: + session_idx = panel.history_sessions.index(affected_session) + except ValueError: + session_idx = -1 + if session_idx >= 0: + top = panel.tree.topLevelItem(session_idx) + if top is not None: + if top.childCount() > 0: + target_item = top.child(top.childCount() - 1) + else: + target_item = top + if target_item is None and panel.tree.topLevelItemCount() > 0: + # Fallback: last top-level item (least likely to switch panels) + last_top = panel.tree.topLevelItem(panel.tree.topLevelItemCount() - 1) + target_item = last_top + if target_item is not None: + panel.tree.setCurrentItem(target_item) + target_item.setSelected(True) def remove_incompatible_actions(panel: HistoryPanel) -> None: From 70dc975fa4ac02ef0391a0e3d2596b1454880292 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Mon, 29 Jun 2026 16:38:00 +0200 Subject: [PATCH 029/108] Fix: Generated macro 'object has no attribute uuid' error for 2-to-1 pipelines --- datalab/gui/historytools_ops.py | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/datalab/gui/historytools_ops.py b/datalab/gui/historytools_ops.py index 25d980d68..5342c68b3 100644 --- a/datalab/gui/historytools_ops.py +++ b/datalab/gui/historytools_ops.py @@ -316,27 +316,31 @@ def generate_macro(panel: HistoryPanel) -> None: "signal" if obj_type == "SignalObj" else "image" ) script_lines.append(f' proxy.set_current_panel("{panel_str}")') - script_lines.append(" src = proxy.get_object()") - script_lines.append(" if src is None:") - script_lines.append( - f' raise RuntimeError("No current object in panel: {panel_str}")' - ) if extra_inputs: n_extra = len(extra_inputs) - script_lines.append( - " _uuids = [u for u in proxy.get_sel_object_uuids() if u != src.uuid]" - ) - script_lines.append(f" if len(_uuids) < {n_extra}:") + script_lines.append(" _uuids = proxy.get_sel_object_uuids()") + script_lines.append(f" if len(_uuids) < {n_extra + 1}:") script_lines.append(" raise RuntimeError(") script_lines.append( - f' "Pipeline needs {n_extra} extra selected' - ' object(s) besides the current one"' + f' "Pipeline needs {n_extra + 1} selected' + f' object(s): 1 source + {n_extra} extra"' ) script_lines.append(" )") + script_lines.append(f' src = proxy.get_object(_uuids[0], "{panel_str}")') + script_lines.append(" if src is None:") + script_lines.append( + f' raise RuntimeError("No current object in panel: {panel_str}")' + ) for idx, extra in enumerate(extra_inputs): script_lines.append( - f' {extra} = proxy.get_object(_uuids[{idx}], "{panel_str}")' + f' {extra} = proxy.get_object(_uuids[{idx + 1}], "{panel_str}")' ) + else: + script_lines.append(" src = proxy.get_object()") + script_lines.append(" if src is None:") + script_lines.append( + f' raise RuntimeError("No current object in panel: {panel_str}")' + ) extra_args = "".join(f", {e}" for e in extra_inputs) script_lines.append(f" result = process(src{extra_args})") script_lines.append(" proxy.add_object(result)") From 45239dd975e9e9a90feef34d34181e0988872392 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Tue, 30 Jun 2026 11:52:23 +0200 Subject: [PATCH 030/108] =?UTF-8?q?Feat(history):=20Panel-scoped=20workspa?= =?UTF-8?q?ce=20state=20=E2=80=94=20fix=20misleading=20cross-panel=20incom?= =?UTF-8?q?patibility=20(P1)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- datalab/gui/historysession_ops.py | 10 ++++-- datalab/history/workspace_state.py | 21 +++++++++-- datalab/tests/features/common/history_test.py | 36 ++++++++++++++++++- 3 files changed, 61 insertions(+), 6 deletions(-) diff --git a/datalab/gui/historysession_ops.py b/datalab/gui/historysession_ops.py index fd9ef2378..8e68c857d 100644 --- a/datalab/gui/historysession_ops.py +++ b/datalab/gui/historysession_ops.py @@ -77,7 +77,7 @@ def add_compute_entry( return None state = WorkspaceState() if save_state: - state.save(panel.mainwindow) + state.save(panel.mainwindow, panel_str=panel_str) # Deep-copy kwargs so each action owns independent parameter # instances. Without this, consecutive applications of the same # function (e.g. two gaussian_filter calls with different sigma) @@ -257,9 +257,15 @@ def add_ui_entry( """ if not panel.record_mode_enabled or panel.is_replaying(): return None + # Derive the action's panel from the UI target so the captured state only + # constrains the panel the action actually operates on. + target_panel_str = { + "signalpanel": "signal", + "imagepanel": "image", + }.get(target) state = WorkspaceState() if save_state: - state.save(panel.mainwindow) + state.save(panel.mainwindow, panel_str=target_panel_str) # Deep-copy kwargs to ensure independent parameter ownership # (same rationale as in add_compute_entry). action = HistoryAction( diff --git a/datalab/history/workspace_state.py b/datalab/history/workspace_state.py index a665d6a8c..527abae2f 100644 --- a/datalab/history/workspace_state.py +++ b/datalab/history/workspace_state.py @@ -160,16 +160,31 @@ def _normalize_panel_keys(cls, d: dict) -> dict: """Return *d* with all top-level keys normalized to stable panel IDs.""" return {cls._normalize_panel_key(k): v for k, v in d.items()} - def save(self, mainwindow: DLMainWindow) -> None: + def save(self, mainwindow: DLMainWindow, panel_str: str | None = None) -> None: """Save the current workspace state Args: mainwindow: DataLab's main window + panel_str: Stable identifier (``"signal"`` or ``"image"``) of the + panel the action operates on. When provided, only that panel's + selection/states/titles are captured -- the other panel's entries + are left empty so that unrelated objects in the other panel cannot + produce false incompatibilities. When ``None`` (default), both + panels are captured (backward-compatible behavior). ``object_metadata`` + is always captured for both panels (used by session-replay + positional fallback and harmless for compatibility checks). """ - self.selection = self.get_current_selection(mainwindow) + full_selection = self.get_current_selection(mainwindow) + if panel_str is None: + self.selection = full_selection + else: + # Restrict the captured selection to the action's own panel; leave + # the other panel's selection empty so compatibility checks ignore + # unrelated objects in that panel. + self.selection = {panel_str: full_selection.get(panel_str, [])} self.object_metadata = {} for panel in (mainwindow.signalpanel, mainwindow.imagepanel): - sel_uuids = self.selection[panel.PANEL_STR_ID] + sel_uuids = self.selection.get(panel.PANEL_STR_ID, []) self.states[panel.PANEL_STR_ID] = [ str(obj.data.shape) for obj in panel.objmodel diff --git a/datalab/tests/features/common/history_test.py b/datalab/tests/features/common/history_test.py index d1a857fa0..51daafdf0 100644 --- a/datalab/tests/features/common/history_test.py +++ b/datalab/tests/features/common/history_test.py @@ -33,13 +33,14 @@ import pytest import sigima.objects import sigima.params +import sigima.proc.image as sipi import sigima.proc.signal as sips from qtpy import QtCore as QC from sigima.objects import create_signal_roi from sigima.objects.base import BaseROI from sigima.objects.signal.creation import NewSignalParam from sigima.tests import helpers -from sigima.tests.data import create_paracetamol_signal +from sigima.tests.data import create_paracetamol_signal, create_sincos_image from datalab.config import _ from datalab.gui.panel.base import AddMetadataParam, BaseDataPanel @@ -483,6 +484,39 @@ def test_history_action_compatibility(): assert item.foreground(0).color().isValid() +def test_history_action_panel_scoped_state(): + """An action's WorkspaceState only captures its own panel's selection.""" + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + spanel, ipanel = win.signalpanel, win.imagepanel + + # Create a signal and keep it selected in the signal panel. + spanel.add_object(create_paracetamol_signal()) + sig_uuid = get_uuid(spanel.objmodel.get_object_from_number(1)) + spanel.objview.select_objects([1]) + + # Create an image and run a 1_to_1 image compute action. + ipanel.add_object(create_sincos_image()) + ima_uuid = get_uuid(ipanel.objmodel.get_object_from_number(1)) + ipanel.objview.select_objects([1]) + ipanel.processor.run_feature(sipi.inverse) + + # The recorded image action must NOT embed the signal-panel selection. + entry = history[len(history)] + assert entry.kind == HistoryAction.KIND_COMPUTE + assert entry.panel_str == ipanel.PANEL_STR_ID + assert entry.state.selection.get("signal", []) == [] + assert entry.state.selection.get("image") == [ima_uuid] + + # Deleting the unrelated signal must keep the image action compatible. + history.toggle_record_mode(False) + spanel.objview.select_objects([1]) + spanel.remove_object(force=True) + assert sig_uuid not in spanel.objmodel.get_object_ids() + assert entry.is_current_state_compatible(win, restore_selection=False) is True + + # --------------------------------------------------------------------------- # 3) Recording: compute + UI actions # --------------------------------------------------------------------------- From dc9aaba6164e51d30aa5ba13c6f6356933c1f9a6 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Tue, 30 Jun 2026 12:30:09 +0200 Subject: [PATCH 031/108] Feat(history): Offer a new session when creating or loading an object (P2) --- datalab/gui/historysession_ops.py | 55 +++++++++++ datalab/gui/main.py | 32 ++++--- datalab/gui/panel/base.py | 94 ++++++++++--------- datalab/gui/panel/history/panel.py | 21 +++++ datalab/tests/features/common/history_test.py | 36 +++++++ 5 files changed, 182 insertions(+), 56 deletions(-) diff --git a/datalab/gui/historysession_ops.py b/datalab/gui/historysession_ops.py index 8e68c857d..49b96622a 100644 --- a/datalab/gui/historysession_ops.py +++ b/datalab/gui/historysession_ops.py @@ -9,6 +9,11 @@ from copy import deepcopy from typing import TYPE_CHECKING, Any, Callable, Generator +from qtpy import QtCore as QC +from qtpy import QtWidgets as QW + +from datalab.config import _ +from datalab.env import execenv from datalab.history import HistoryAction, HistorySession, WorkspaceState from datalab.history.core import _resolve_self_target @@ -33,6 +38,52 @@ def start_new_session_after_workspace_reset(panel: HistoryPanel) -> None: panel.create_new_session() +def maybe_start_session_for_input(panel: HistoryPanel, *, load: bool = False) -> None: + """Offer to start a new history session before a creation/load is recorded. + + When the current session already contains actions, prompt the user to start + a fresh session so the new creation/load becomes the root of a clean, + self-contained pipeline. A new session is opened *before* the action is + recorded when the user accepts. + + Args: + load: True when triggered by a file/workspace load, False for an object + creation. Only affects the prompt wording. + """ + if not panel.record_mode_enabled or panel.is_replaying(): + return + if panel._suppress_session_prompt: + return + # Reuse the current session when there is none yet or it has no actions: + # there is nothing to preserve, so no need to prompt. + if not panel.history_sessions or not panel.history_sessions[-1].actions: + return + # Debounce: a synchronous burst of creations (plugin/macro) must prompt only + # once. The guard is reset on the next event-loop turn. + if panel._session_input_pending: + return + panel._session_input_pending = True + QC.QTimer.singleShot(0, lambda: setattr(panel, "_session_input_pending", False)) + if execenv.unattended: + # Headless runs: honor the accept_dialogs flag (default False -> "No"), + # so tests can drive the behavior without a real modal dialog. + if execenv.accept_dialogs: + panel.create_new_session() + return + if load: + message = _("A new object was loaded. Start a new history session?") + else: + message = _("A new object was created. Start a new history session?") + answer = QW.QMessageBox.question( + panel.mainwindow, + _("New history session"), + message, + QW.QMessageBox.Yes | QW.QMessageBox.No, + ) + if answer == QW.QMessageBox.Yes: + panel.create_new_session() + + def add_compute_entry( panel: HistoryPanel, action_title: str, @@ -257,6 +308,10 @@ def add_ui_entry( """ if not panel.record_mode_enabled or panel.is_replaying(): return None + # When the entry is an object creation, offer to start a fresh history + # session first so the creation becomes the root of a clean pipeline. + if method_name in HistoryAction.UI_CREATION_METHODS: + panel.maybe_start_session_for_input(load=False) # Derive the action's panel from the UI target so the captured state only # constrains the panel the action actually operates on. target_panel_str = { diff --git a/datalab/gui/main.py b/datalab/gui/main.py index fe73dbc1c..ae889e9c7 100644 --- a/datalab/gui/main.py +++ b/datalab/gui/main.py @@ -2276,17 +2276,20 @@ def load_h5_workspace(self, h5files: list[str], reset_all: bool = False) -> None Raises: ValueError: If a file is not a valid native DataLab HDF5 file """ - for idx, filename in enumerate(h5files): - filename = self.__check_h5file(filename, "load") - success = self.h5inputoutput.open_file_headless( - filename, reset_all=(reset_all and idx == 0) - ) - if not success: - raise ValueError( - f"File '{filename}' is not a native DataLab HDF5 file. " - f"Use the GUI menu or a macro with RemoteProxy to import " - f"arbitrary HDF5 files." + # Offer a fresh history session for this load *before* recording anything. + self.historypanel.maybe_start_session_for_input(load=True) + with self.historypanel.session_prompt_suppressed(): + for idx, filename in enumerate(h5files): + filename = self.__check_h5file(filename, "load") + success = self.h5inputoutput.open_file_headless( + filename, reset_all=(reset_all and idx == 0) ) + if not success: + raise ValueError( + f"File '{filename}' is not a native DataLab HDF5 file. " + f"Use the GUI menu or a macro with RemoteProxy to import " + f"arbitrary HDF5 files." + ) # Refresh panel trees after loading self.repopulate_panel_trees() @@ -2317,9 +2320,12 @@ def import_h5_file(self, filename: str, reset_all: bool | None = None) -> None: separated by ":") reset_all: Delete all DataLab signals/images before importing data """ - with qth.qt_try_loadsave_file(self, filename, "load"): - filename = self.__check_h5file(filename, "load") - self.h5inputoutput.import_files([filename], False, reset_all) + # Offer a fresh history session for this load *before* importing anything. + self.historypanel.maybe_start_session_for_input(load=True) + with self.historypanel.session_prompt_suppressed(): + with qth.qt_try_loadsave_file(self, filename, "load"): + filename = self.__check_h5file(filename, "load") + self.h5inputoutput.import_files([filename], False, reset_all) # This method is intentionally *not* remote controlled # (see TODO regarding RemoteClient.add_object method) diff --git a/datalab/gui/panel/base.py b/datalab/gui/panel/base.py index f641e17e2..e021d53b9 100644 --- a/datalab/gui/panel/base.py +++ b/datalab/gui/panel/base.py @@ -2384,42 +2384,47 @@ def load_from_directory(self, directory: str | None = None) -> list[TypeObj]: directory = getexistingdirectory(self, _("Open"), basedir) if not directory: return [] + # Offer a fresh history session for this batch *before* loading anything. + self.mainwindow.historypanel.maybe_start_session_for_input(load=True) folders = [ path for path in glob.glob(osp.join(directory, "**"), recursive=True) if osp.isdir(path) and len(os.listdir(path)) > 0 ] objs = [] - with create_progress_bar( - self, _("Scanning directory"), max_=len(folders) - 1 - ) as progress: - # Iterate over all subfolders in the directory: - for i_path, path in enumerate(folders): - progress.setValue(i_path + 1) - if progress.wasCanceled(): - break - path = osp.normpath(path) - fnames = sorted( - [ - osp.join(path, fname) - for fname in os.listdir(path) - if osp.isfile(osp.join(path, fname)) - ] - ) - new_objs = self.load_from_files( - fnames, - create_group=False, - add_objects=False, - ignore_errors=True, - ) - if new_objs: - objs += new_objs - grp_name = osp.relpath(path, directory) - if grp_name == ".": - grp_name = osp.basename(path) - grp = self.add_group(grp_name) - for obj in new_objs: - self.add_object(obj, group_id=get_uuid(grp), set_current=False) + with self.mainwindow.historypanel.session_prompt_suppressed(): + with create_progress_bar( + self, _("Scanning directory"), max_=len(folders) - 1 + ) as progress: + # Iterate over all subfolders in the directory: + for i_path, path in enumerate(folders): + progress.setValue(i_path + 1) + if progress.wasCanceled(): + break + path = osp.normpath(path) + fnames = sorted( + [ + osp.join(path, fname) + for fname in os.listdir(path) + if osp.isfile(osp.join(path, fname)) + ] + ) + new_objs = self.load_from_files( + fnames, + create_group=False, + add_objects=False, + ignore_errors=True, + ) + if new_objs: + objs += new_objs + grp_name = osp.relpath(path, directory) + if grp_name == ".": + grp_name = osp.basename(path) + grp = self.add_group(grp_name) + for obj in new_objs: + self.add_object( + obj, group_id=get_uuid(grp), set_current=False + ) return objs def load_from_files( @@ -2456,6 +2461,8 @@ def load_from_files( entry_title = _("Load from %d files") % nbf else: entry_title = _('Load "%s"') % osp.basename(filenames[0]) + # Offer a fresh history session for this batch *before* recording any entry. + self.mainwindow.historypanel.maybe_start_session_for_input(load=True) self.mainwindow.historypanel.add_ui_entry( entry_title, target=self.PANEL_STR_ID + "panel", @@ -2467,19 +2474,20 @@ def load_from_files( ignore_errors=ignore_errors, ) objs = [] - for filename in filenames: - with qt_try_loadsave_file(self.parentWidget(), filename, "load"): - Conf.main.base_dir.set(filename) - try: - objs += self.__load_from_file( - filename, create_group=create_group, add_objects=add_objects - ) - except Exception as exc: # pylint: disable=broad-exception-caught - if ignore_errors: - # Ignore unknown file types - pass - else: - raise exc + with self.mainwindow.historypanel.session_prompt_suppressed(): + for filename in filenames: + with qt_try_loadsave_file(self.parentWidget(), filename, "load"): + Conf.main.base_dir.set(filename) + try: + objs += self.__load_from_file( + filename, create_group=create_group, add_objects=add_objects + ) + except Exception as exc: # pylint: disable=broad-exception-caught + if ignore_errors: + # Ignore unknown file types + pass + else: + raise exc return objs def save_to_files(self, filenames: list[str] | str | None = None) -> None: diff --git a/datalab/gui/panel/history/panel.py b/datalab/gui/panel/history/panel.py index bfed85742..7b4008846 100644 --- a/datalab/gui/panel/history/panel.py +++ b/datalab/gui/panel/history/panel.py @@ -63,6 +63,8 @@ def __init__(self, parent: DLMainWindow) -> None: self._output_suppressed = False self._syncing = False self.cascade_in_progress = False + self._session_input_pending = False + self._suppress_session_prompt = False self._delete_action: QW.QAction | None = None self._duplicate_action: QW.QAction | None = None self.step_prev_action: QW.QAction | None = None @@ -791,6 +793,25 @@ def start_new_session_after_workspace_reset(self) -> None: """Start a new history session after a workspace reset.""" return hsess.start_new_session_after_workspace_reset(self) + def maybe_start_session_for_input(self, *, load: bool = False) -> None: + """Offer to start a new history session before a creation/load is recorded. + + Args: + load: True when triggered by a file/workspace load, False for an + object creation. Only affects the prompt wording. + """ + return hsess.maybe_start_session_for_input(self, load=load) + + @contextmanager + def session_prompt_suppressed(self) -> Generator[None, None, None]: + """Context manager suppressing the new-session prompt during a batch load.""" + previous = self._suppress_session_prompt + self._suppress_session_prompt = True + try: + yield + finally: + self._suppress_session_prompt = previous + def add_compute_entry( self, action_title: str, diff --git a/datalab/tests/features/common/history_test.py b/datalab/tests/features/common/history_test.py index 51daafdf0..ad7983983 100644 --- a/datalab/tests/features/common/history_test.py +++ b/datalab/tests/features/common/history_test.py @@ -43,6 +43,7 @@ from sigima.tests.data import create_paracetamol_signal, create_sincos_image from datalab.config import _ +from datalab.env import execenv from datalab.gui.panel.base import AddMetadataParam, BaseDataPanel from datalab.gui.panel.history import ( HISTORY_ACTION_SCHEMA_VERSION, @@ -1627,3 +1628,38 @@ def test_history_chain_reconnect(): reconnected_uuids = action_deriv.state.selection.get("signal", []) assert s002_uuid not in reconnected_uuids assert src_uuid in reconnected_uuids + + +def test_history_new_session_prompt_on_input(monkeypatch): + """Creating an object on a non-empty session offers to start a new session.""" + # --- scenario: user accepts the prompt -> a new session is opened --- + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + + # First creation reuses the (empty) current session: no prompt expected. + win.add_object(create_paracetamol_signal()) + assert len(history.history_sessions) == 1 + assert len(history.history_sessions[-1].actions) == 1 + + # Headless "accept": accept_dialogs drives the prompt to "Yes". + monkeypatch.setattr(execenv, "accept_dialogs", True) + n_sessions = len(history.history_sessions) + win.add_object(create_paracetamol_signal()) + assert len(history.history_sessions) == n_sessions + 1 + new_session = history.history_sessions[-1] + assert new_session.actions + assert new_session.actions[0].method_name == "new_object" + + # --- scenario: user declines the prompt -> no new session is created --- + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + win.add_object(create_paracetamol_signal()) + assert len(history.history_sessions) == 1 + + # Headless "decline": accept_dialogs stays False -> prompt answered "No". + monkeypatch.setattr(execenv, "accept_dialogs", False) + n_sessions = len(history.history_sessions) + win.add_object(create_paracetamol_signal()) + assert len(history.history_sessions) == n_sessions From 852d39251ca003f96fc06e92d018289b424a0882 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Tue, 30 Jun 2026 13:31:48 +0200 Subject: [PATCH 032/108] Feat(history): Disable history auto-record by default --- datalab/config.py | 2 +- datalab/gui/panel/history/panel.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/datalab/config.py b/datalab/config.py index d4f7994ca..b74e7bf54 100644 --- a/datalab/config.py +++ b/datalab/config.py @@ -648,7 +648,7 @@ def initialize(): Conf.proc.keep_results.get(False) Conf.proc.show_result_dialog.get(True) Conf.proc.ignore_warnings.get(False) - Conf.proc.history_auto_record.get(True) + Conf.proc.history_auto_record.get(False) Conf.proc.xarray_compat_behavior.get("ask") Conf.proc.small_mono_font.get((configtools.MONOSPACE, 8, False)) # View section diff --git a/datalab/gui/panel/history/panel.py b/datalab/gui/panel/history/panel.py index 7b4008846..0e3b42637 100644 --- a/datalab/gui/panel/history/panel.py +++ b/datalab/gui/panel/history/panel.py @@ -116,7 +116,7 @@ def __init__(self, parent: DLMainWindow) -> None: self.refresh_obj_ids_snapshot() self.update_actions_state() self.refresh_compatibility_items() - if not execenv.unattended and Conf.proc.history_auto_record.get(True): + if not execenv.unattended and Conf.proc.history_auto_record.get(False): self._record_action.setChecked(True) self.create_new_session() From 28cdf48383b1dd534d3161b0a49ca236f795e1e9 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Tue, 30 Jun 2026 13:48:33 +0200 Subject: [PATCH 033/108] Feat(history): Persist action UUID and register outputs for creation UI actions (A) --- datalab/gui/panel/base.py | 56 ++++++++++--------- datalab/history/action.py | 9 +++ datalab/tests/features/common/history_test.py | 46 +++++++++++++++ 3 files changed, 86 insertions(+), 25 deletions(-) diff --git a/datalab/gui/panel/base.py b/datalab/gui/panel/base.py index e021d53b9..8ff6690cf 100644 --- a/datalab/gui/panel/base.py +++ b/datalab/gui/panel/base.py @@ -1853,22 +1853,23 @@ def duplicate_object(self) -> None: """Duplication signal/image object""" if not self.mainwindow.confirm_memory_state(): return - self.mainwindow.historypanel.add_ui_entry( + action = self.mainwindow.historypanel.add_ui_entry( _("Duplicate object or group"), target=self.PANEL_STR_ID + "panel", method_name="duplicate_object", save_state=False, ) - # Duplicate individual objects (exclusive with respect to groups) - for oid in self.objview.get_sel_object_uuids(): - self.__duplicate_individual_obj(oid, set_current=False) - # Duplicate groups (exclusive with respect to individual objects) - for group in self.objview.get_sel_groups(): - new_group = self.add_group(group.title) - for oid in self.objmodel.get_group_object_ids(get_uuid(group)): - self.__duplicate_individual_obj( - oid, get_uuid(new_group), set_current=False - ) + with self.mainwindow.historypanel.capture_outputs(action): + # Duplicate individual objects (exclusive with respect to groups) + for oid in self.objview.get_sel_object_uuids(): + self.__duplicate_individual_obj(oid, set_current=False) + # Duplicate groups (exclusive with respect to individual objects) + for group in self.objview.get_sel_groups(): + new_group = self.add_group(group.title) + for oid in self.objmodel.get_group_object_ids(get_uuid(group)): + self.__duplicate_individual_obj( + oid, get_uuid(new_group), set_current=False + ) self.selection_changed(update_items=True) def copy_metadata(self) -> None: @@ -2463,7 +2464,7 @@ def load_from_files( entry_title = _('Load "%s"') % osp.basename(filenames[0]) # Offer a fresh history session for this batch *before* recording any entry. self.mainwindow.historypanel.maybe_start_session_for_input(load=True) - self.mainwindow.historypanel.add_ui_entry( + action = self.mainwindow.historypanel.add_ui_entry( entry_title, target=self.PANEL_STR_ID + "panel", method_name="load_from_files", @@ -2475,19 +2476,24 @@ def load_from_files( ) objs = [] with self.mainwindow.historypanel.session_prompt_suppressed(): - for filename in filenames: - with qt_try_loadsave_file(self.parentWidget(), filename, "load"): - Conf.main.base_dir.set(filename) - try: - objs += self.__load_from_file( - filename, create_group=create_group, add_objects=add_objects - ) - except Exception as exc: # pylint: disable=broad-exception-caught - if ignore_errors: - # Ignore unknown file types - pass - else: - raise exc + with self.mainwindow.historypanel.capture_outputs(action): + for filename in filenames: + with qt_try_loadsave_file(self.parentWidget(), filename, "load"): + Conf.main.base_dir.set(filename) + try: + objs += self.__load_from_file( + filename, + create_group=create_group, + add_objects=add_objects, + ) + except ( + Exception + ) as exc: # pylint: disable=broad-exception-caught + if ignore_errors: + # Ignore unknown file types + pass + else: + raise exc return objs def save_to_files(self, filenames: list[str] | str | None = None) -> None: diff --git a/datalab/history/action.py b/datalab/history/action.py index f415367fc..152e9eb20 100644 --- a/datalab/history/action.py +++ b/datalab/history/action.py @@ -663,6 +663,8 @@ def serialize(self, writer: NativeH5Writer) -> None: writer.write(self.kind) with writer.group("title"): writer.write(self.__title) + with writer.group("uuid"): + writer.write(self.uuid) if self.panel_str is not None: with writer.group("panel_str"): writer.write(self.panel_str) @@ -722,6 +724,13 @@ def deserialize(self, reader: NativeH5Reader) -> None: current = reader.h5 for option in reader.option: current = current.require_group(option) + # ``uuid`` is present only in files written after UUID persistence was + # added; keep the freshly generated ``self.uuid`` for older files. + if "uuid" in current.attrs or "uuid" in current: + with reader.group("uuid"): + loaded_uuid = reader.read_any() + if loaded_uuid: + self.uuid = str(loaded_uuid) for attr in ("panel_str", "func_name", "pattern", "target", "method_name"): if attr in current.attrs or attr in current: with reader.group(attr): diff --git a/datalab/tests/features/common/history_test.py b/datalab/tests/features/common/history_test.py index ad7983983..14ab4d7a6 100644 --- a/datalab/tests/features/common/history_test.py +++ b/datalab/tests/features/common/history_test.py @@ -411,6 +411,52 @@ def test_history_schema_and_hdf5_roundtrip(): shutil.rmtree(tmpdir, ignore_errors=True) +def test_history_action_uuid_persisted(): + """Action UUID is stable across a .dlhist save/reload cycle.""" + with datalab_test_app_context() as win: + history = win.historypanel + panel = win.signalpanel + history.toggle_record_mode(True) + panel.add_object(create_paracetamol_signal()) + panel.objview.select_objects([1]) + panel.processor.run_feature( + sips.normalize, sigima.params.NormalizeParam.create(method="maximum") + ) + session = history.history_sessions[-1] + original_uuids = [action.uuid for action in session.actions] + assert original_uuids + with tempfile.TemporaryDirectory() as tmpdir: + path = os.path.join(tmpdir, "uuid_roundtrip.dlhist") + with NativeH5Writer(path) as writer: + writer.write_object_list([session], "history_session") + with NativeH5Reader(path) as reader: + restored_sessions = reader.read_object_list( + "history_session", HistorySession + ) + restored_uuids = [action.uuid for action in restored_sessions[0].actions] + assert restored_uuids == original_uuids + + +def test_history_duplicate_registers_outputs(): + """``duplicate_object`` registers duplicated object UUIDs as action outputs.""" + with datalab_test_app_context() as win: + history = win.historypanel + panel = win.signalpanel + history.toggle_record_mode(True) + panel.add_object(create_paracetamol_signal()) + panel.objview.select_objects([1]) + panel.duplicate_object() + session = history.history_sessions[-1] + dup_action = next( + action + for action in session.actions + if action.method_name == "duplicate_object" + ) + assert dup_action.output_uuids + first_output = dup_action.output_uuids[0] + assert history.output_to_action[first_output] == dup_action.uuid + + # --------------------------------------------------------------------------- # 2) HistoryAction / WorkspaceState compatibility # --------------------------------------------------------------------------- From 877f1974bde9b54ea6878133009931551f89aff1 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Tue, 30 Jun 2026 14:07:02 +0200 Subject: [PATCH 034/108] Feat(history): Add headless deterministic fit evaluator (C1) --- .../features/signal/fitdialog_unit_test.py | 42 +++++++++++ datalab/widgets/fitdialog.py | 75 +++++++++++++++++++ 2 files changed, 117 insertions(+) diff --git a/datalab/tests/features/signal/fitdialog_unit_test.py b/datalab/tests/features/signal/fitdialog_unit_test.py index ca0c65d2f..06d812677 100644 --- a/datalab/tests/features/signal/fitdialog_unit_test.py +++ b/datalab/tests/features/signal/fitdialog_unit_test.py @@ -8,9 +8,11 @@ # pylint: disable=invalid-name # Allows short reference names like x, y, ... # guitest: show +import numpy as np from guidata.qthelpers import qt_app_context from sigima.objects import NormalDistribution1DParam from sigima.tests.data import create_noisy_signal, get_test_signal +from sigima.tools.signal import pulse from sigima.tools.signal.peakdetection import peak_indices from datalab.env import execenv @@ -46,5 +48,45 @@ def test_fit_dialog(): ep(fdlg.piecewiseexponential_fit(s4.x, s4.y, name=tn("12"))) +def test_evaluate_fit_matches_models(): + """Test the GUI-free deterministic fit evaluator (no dialog).""" + x = np.linspace(-5, 5, 50) + + # Polynomial (degree 2) + poly_values = [2.0, -1.0, 3.0] + assert np.allclose( + fdlg.evaluate_fit("polynomial", x, poly_values), + np.polyval(poly_values, x), + ) + + # Gaussian: [amp, sigma, x0, y0] + gauss_values = [5.0, 1.5, 0.3, 0.2] + assert np.allclose( + fdlg.evaluate_fit("gaussian", x, gauss_values), + pulse.GaussianModel.func(x, *gauss_values), + ) + + # Multi-Gaussian: [A1, σ1, A2, σ2, y0] + fixed peak abscissas + multi_values = [1.0, 0.5, 2.0, 0.4, 0.1] + a_x0 = [-1.0, 1.5] + assert np.allclose( + fdlg.evaluate_fit("multigaussian", x, multi_values, extra={"a_x0": a_x0}), + fdlg.multigaussian(x, *multi_values, a_x0=np.array(a_x0)), + ) + + # Canonical mapping helper + assert fdlg.fit_type_from_dlgfunc_name("gaussian_fit") == "gaussian" + assert fdlg.fit_type_from_dlgfunc_name("unknown") is None + + # Unknown fit type raises + try: + fdlg.evaluate_fit("nope", x, []) + except ValueError: + pass + else: + raise AssertionError("evaluate_fit should raise ValueError for unknown type") + + if __name__ == "__main__": test_fit_dialog() + test_evaluate_fit_matches_models() diff --git a/datalab/widgets/fitdialog.py b/datalab/widgets/fitdialog.py index aaac07ace..2aef2fafe 100644 --- a/datalab/widgets/fitdialog.py +++ b/datalab/widgets/fitdialog.py @@ -4,6 +4,8 @@ # pylint: disable=invalid-name # Allows short reference names like x, y, ... +from __future__ import annotations + import numpy as np from guidata.configtools import get_icon from guidata.qthelpers import exec_dialog @@ -786,3 +788,76 @@ def fitfunc(x, params): ) if values: return fitfunc(x, values), params + + +# --- Deterministic fit evaluation (GUI-free) ---------------------------------- + +# Canonical fit-type identifiers, used to record and replay curve fits +# deterministically (without reopening the interactive dialog). +FIT_TYPE_BY_DLGFUNC = { + "polynomial_fit": "polynomial", + "linear_fit": "polynomial", + "gaussian_fit": "gaussian", + "lorentzian_fit": "lorentzian", + "voigt_fit": "voigt", + "multigaussian_fit": "multigaussian", + "multilorentzian_fit": "multilorentzian", +} + + +def fit_type_from_dlgfunc_name(name: str) -> str | None: + """Return the canonical fit-type id for a fit dialog function name. + + Args: + name: ``__name__`` of the fit dialog function (e.g. ``"gaussian_fit"``). + + Returns: + The canonical fit-type id (e.g. ``"gaussian"``), or ``None`` if the + function is not a recognised deterministic fit. + """ + return FIT_TYPE_BY_DLGFUNC.get(name) + + +def evaluate_fit( + fit_type: str, + x: np.ndarray, + values: list[float], + extra: dict | None = None, +) -> np.ndarray: + """Evaluate a recorded curve fit deterministically (no GUI). + + Args: + fit_type: Canonical fit-type id (see :data:`FIT_TYPE_BY_DLGFUNC`). + x: Abscissa values of the source signal. + values: Final fit parameter values, in the same order produced by the + corresponding interactive fit function. + extra: Optional structural data required by some models + (``{"a_x0": [...]}`` for multi-peak fits). + + Returns: + The fitted ordinate array ``y`` evaluated at ``x``. + + Raises: + ValueError: If ``fit_type`` is unknown or required ``extra`` is missing. + """ + x = np.asarray(x, dtype=float) + vals = list(values) + extra = extra or {} + if fit_type == "polynomial": + return np.polyval(vals, x) + if fit_type == "gaussian": + return pulse.GaussianModel.func(x, *vals) + if fit_type == "lorentzian": + return pulse.LorentzianModel.func(x, *vals) + if fit_type == "voigt": + return pulse.VoigtModel.func(x, *vals) + if fit_type in ("multigaussian", "multilorentzian"): + a_x0 = extra.get("a_x0") + if a_x0 is None: + raise ValueError( + f"Missing 'a_x0' in extra for {fit_type!r} fit evaluation" + ) + a_x0 = np.asarray(a_x0, dtype=float) + func = multigaussian if fit_type == "multigaussian" else multilorentzian + return func(x, *vals, a_x0=a_x0) + raise ValueError(f"Unknown fit_type {fit_type!r}") From c26c2fb845e8787ad0661a028aaeef3f990a13d5 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Tue, 30 Jun 2026 14:31:03 +0200 Subject: [PATCH 035/108] Feat(history): Record interactive curve fits as deterministic replay actions (C2/C3) Interactive fit dialogs now record a UI history action targeting the signal processor's new recompute_fit method, which reconstructs the fitted curve headlessly via fitdialog.evaluate_fit at replay time (no dialog reopened). - action.py: resolve signalprocessor/imageprocessor targets; translate the recorded source_uuid through uuid_remap on session replay. - historysession_ops.py: scope captured state and panel_str to processor targets. - processor/signal.py: thread fit_type/fit_x0 through the fit path, record one action per source object, add deterministic recompute_fit. - Covered types: polynomial, linear, gaussian, lorentzian, voigt, multigaussian, multilorentzian. Other interactive fits remain interactive-only (graceful). - Add integration test test_history_interactive_fit_replay. --- datalab/gui/historysession_ops.py | 5 + datalab/gui/processor/signal.py | 92 +++++++++++++++++-- datalab/history/action.py | 19 +++- datalab/tests/features/common/history_test.py | 73 +++++++++++++++ datalab/widgets/fitdialog.py | 4 +- 5 files changed, 180 insertions(+), 13 deletions(-) diff --git a/datalab/gui/historysession_ops.py b/datalab/gui/historysession_ops.py index 49b96622a..8f1f995c5 100644 --- a/datalab/gui/historysession_ops.py +++ b/datalab/gui/historysession_ops.py @@ -317,6 +317,8 @@ def add_ui_entry( target_panel_str = { "signalpanel": "signal", "imagepanel": "image", + "signalprocessor": "signal", + "imageprocessor": "image", }.get(target) state = WorkspaceState() if save_state: @@ -330,6 +332,9 @@ def add_ui_entry( method_name=method_name, kwargs=deepcopy(kwargs), state=state, + panel_str=target_panel_str + if target in ("signalprocessor", "imageprocessor") + else None, ) panel.add_object(action) return action diff --git a/datalab/gui/processor/signal.py b/datalab/gui/processor/signal.py index 1d6e025c4..ad4ae5f9d 100644 --- a/datalab/gui/processor/signal.py +++ b/datalab/gui/processor/signal.py @@ -32,6 +32,7 @@ from datalab.adapters_metadata.table_adapter import TableAdapter from datalab.config import _ from datalab.gui.processor.base import BaseProcessor +from datalab.objectmodel import get_uuid from datalab.utils.qthelpers import qt_try_except from datalab.widgets import ( fitdialog, @@ -705,10 +706,15 @@ def polynomialfit(x, y, parent=None): """Polynomial fit dialog function""" return dlgfunc(x, y, param.degree, parent=parent) - self.compute_fit(txt, polynomialfit) + self.compute_fit(txt, polynomialfit, fit_type="polynomial") def __row_compute_fit( - self, obj: SignalObj, name: str, fitdlgfunc: Callable + self, + obj: SignalObj, + name: str, + fitdlgfunc: Callable, + fit_type: str | None = None, + fit_x0: list[float] | None = None, ) -> None: """Curve fitting computing sub-method""" output = fitdlgfunc(obj.x, obj.y, parent=self.mainwindow) @@ -726,19 +732,79 @@ def __row_compute_fit( # Creating new signal metadata = {fitdlgfunc.__name__: pvalues} signal = create_signal(f"{name}({obj.title})", obj.x, y, metadata=metadata) - # Creating new plot item - self.panel.add_object(signal) + # Record a deterministically-replayable history action when the fit + # type is supported by the headless evaluator. Falls back to no + # recording (interactive-only) for unsupported types. + action = None + if fit_type is not None: + action = self.mainwindow.historypanel.add_ui_entry( + name, + target="signalprocessor", + method_name="recompute_fit", + save_state=True, + fit_type=fit_type, + fit_values=[float(p.value) for p in params], + fit_x0=[float(v) for v in fit_x0] if fit_x0 else None, + fit_name=name, + source_uuid=get_uuid(obj), + ) + # Creating new plot item (capture its UUID as the action output) + with self.mainwindow.historypanel.capture_outputs(action): + self.panel.add_object(signal) @qt_try_except() - def compute_fit(self, title: str, fitdlgfunc: Callable) -> None: + def compute_fit( + self, title: str, fitdlgfunc: Callable, fit_type: str | None = None + ) -> None: """Compute fitting curve using an interactive dialog Args: title: Title of the dialog fitdlgfunc: Fitting dialog function + fit_type: Optional explicit fit type id for deterministic replay. + When None, it is derived from ``fitdlgfunc.__name__``. """ + if fit_type is None: + fit_type = fitdialog.fit_type_from_dlgfunc_name(fitdlgfunc.__name__) for obj in self.panel.objview.get_sel_objects(): - self.__row_compute_fit(obj, title, fitdlgfunc) + self.__row_compute_fit(obj, title, fitdlgfunc, fit_type=fit_type) + + @qt_try_except() + def recompute_fit( + self, + fit_type: str, + fit_values: list[float], + fit_x0: list[float] | None = None, + fit_name: str = "", + source_uuid: str | None = None, + ) -> None: + """Deterministically recompute an interactive fit result curve. + + Used at history-replay time to reconstruct the fitted curve from the + recorded model type and parameter values, without reopening the + interactive dialog. + + Args: + fit_type: Canonical fit type id (see + :func:`datalab.widgets.fitdialog.evaluate_fit`). + fit_values: Ordered fitted parameter values. + fit_x0: Peak abscissas for multi-peak fits (``None`` otherwise). + fit_name: Title prefix used for the produced signal. + source_uuid: UUID of the source signal to fit. When missing or no + longer present, falls back to the first selected signal. + """ + obj = None + if source_uuid is not None and self.panel.objmodel.has_uuid(source_uuid): + obj = self.panel.objmodel[source_uuid] + if obj is None: + selected = self.panel.objview.get_sel_objects(include_groups=True) + obj = selected[0] if selected else None + if obj is None: + return + extra = {"a_x0": fit_x0} if fit_x0 else None + y = fitdialog.evaluate_fit(fit_type, obj.x, fit_values, extra) + signal = create_signal(f"{fit_name}({obj.title})", obj.x, y) + self.panel.add_object(signal) @qt_try_except() def compute_multigaussianfit(self) -> None: @@ -755,7 +821,13 @@ def multigaussianfit(x, y, parent=None): # pylint: disable=cell-var-from-loop return fitdlgfunc(x, y, peaks, parent=parent) - self.__row_compute_fit(obj, _("Multi-Gaussian fit"), multigaussianfit) + self.__row_compute_fit( + obj, + _("Multi-Gaussian fit"), + multigaussianfit, + fit_type="multigaussian", + fit_x0=[float(v) for v in obj.x[peaks]], + ) @qt_try_except() def compute_multilorentzianfit(self) -> None: @@ -773,7 +845,11 @@ def multilorentzianfit(x, y, parent=None): return fitdlgfunc(x, y, peaks, parent=parent) self.__row_compute_fit( - obj, _("Multi-Lorentzian fit"), multilorentzianfit + obj, + _("Multi-Lorentzian fit"), + multilorentzianfit, + fit_type="multilorentzian", + fit_x0=[float(v) for v in obj.x[peaks]], ) @qt_try_except() diff --git a/datalab/history/action.py b/datalab/history/action.py index 152e9eb20..22c40d8dc 100644 --- a/datalab/history/action.py +++ b/datalab/history/action.py @@ -434,6 +434,10 @@ def _resolve_target(self, mainwindow: DLMainWindow) -> Any: attr = self.target or "mainwindow" if attr == "mainwindow": return mainwindow + if attr == "signalprocessor": + return mainwindow.signalpanel.processor + if attr == "imageprocessor": + return mainwindow.imagepanel.processor return getattr(mainwindow, attr) def _resolve_panel(self, mainwindow: DLMainWindow): @@ -527,7 +531,7 @@ def _replay_inner( else: if restore_selection: self.state.restore(mainwindow) - self._replay_ui(mainwindow, edit) + self._replay_ui(mainwindow, edit, uuid_remap) def _translate_state(self, uuid_remap: dict[str, dict[str, str]]) -> WorkspaceState: """Return a copy of ``self.state`` whose captured UUIDs have been @@ -601,7 +605,12 @@ def replay_compute( raise ValueError(f"Unknown compute pattern: {self.pattern!r}") processor.run_feature(feature, **run_kwargs) - def _replay_ui(self, mainwindow: DLMainWindow, edit: bool) -> None: + def _replay_ui( + self, + mainwindow: DLMainWindow, + edit: bool, + uuid_remap: dict[str, dict[str, str]] | None = None, + ) -> None: """Replay a UI-kind action by calling ``target.method_name(**kwargs)``.""" hpanel = mainwindow.historypanel if ( @@ -642,6 +651,12 @@ def _replay_ui(self, mainwindow: DLMainWindow, edit: bool) -> None: return method = getattr(target, self.method_name) call_kwargs = dict(self.kwargs) + # Translate a recorded source object UUID through the session uuid_remap + # so deterministic replay after save/reload still targets the right object. + if uuid_remap and self.panel_str and "source_uuid" in call_kwargs: + panel_map = uuid_remap.get(self.panel_str, {}) + old = call_kwargs["source_uuid"] + call_kwargs["source_uuid"] = panel_map.get(old, old) # Inject edit mode if the method supports it try: sig = inspect.signature(method) diff --git a/datalab/tests/features/common/history_test.py b/datalab/tests/features/common/history_test.py index 14ab4d7a6..00bb45dc5 100644 --- a/datalab/tests/features/common/history_test.py +++ b/datalab/tests/features/common/history_test.py @@ -1709,3 +1709,76 @@ def test_history_new_session_prompt_on_input(monkeypatch): n_sessions = len(history.history_sessions) win.add_object(create_paracetamol_signal()) assert len(history.history_sessions) == n_sessions + + +def test_history_interactive_fit_replay(): + """Interactive curve-fit recording and deterministic replay. + + Records an interactive fit as a UI history action targeting the signal + processor's ``recompute_fit`` method (exactly as ``__row_compute_fit`` + does), persists it to a ``.dlhist`` file, then replays it and verifies the + reconstructed curve matches the deterministic evaluation -- without any + fit dialog. + """ + with datalab_test_app_context() as win: + history = win.historypanel + panel = win.signalpanel + + # --- scenario: record a polynomial interactive fit as a UI action --- + history.toggle_record_mode(True) + panel.add_object(create_paracetamol_signal()) + src = panel.objmodel.get_object_from_number(1) + src_uuid = get_uuid(src) + panel.objview.select_objects([1]) + + degree = 3 + coeffs = np.polyfit(src.x, src.y, degree) # highest-first == polyval order + fit_values = [float(c) for c in coeffs] + expected_y = np.polyval(coeffs, src.x) + name = _("Polynomial fit") + + result = sigima.objects.create_signal(f"{name}({src.title})", src.x, expected_y) + action = history.add_ui_entry( + name, + target="signalprocessor", + method_name="recompute_fit", + save_state=True, + fit_type="polynomial", + fit_values=fit_values, + fit_name=name, + source_uuid=src_uuid, + ) + assert action is not None + with history.capture_outputs(action): + panel.add_object(result) + assert action.output_uuids == [get_uuid(result)] + assert action.target == "signalprocessor" + assert action.panel_str == panel.PANEL_STR_ID + + # --- scenario: .dlhist round-trip preserves uuid + fit kwargs --- + ser_session = HistorySession(number=1) + ser_session.actions.append(action) + with tempfile.TemporaryDirectory() as tmpdir: + path = os.path.join(tmpdir, "fit.dlhist") + with NativeH5Writer(path) as writer: + writer.write_object_list([ser_session], "history_session") + with NativeH5Reader(path) as reader: + restored_sessions = reader.read_object_list( + "history_session", HistorySession + ) + restored = restored_sessions[0].actions[0] + assert restored.uuid == action.uuid + assert restored.kind == HistoryAction.KIND_UI + assert restored.target == "signalprocessor" + assert restored.method_name == "recompute_fit" + assert restored.kwargs.get("fit_type") == "polynomial" + assert restored.kwargs.get("source_uuid") == src_uuid + assert restored.kwargs.get("fit_values") == pytest.approx(fit_values) + + # --- scenario: deterministic replay reconstructs the fit curve --- + n_before = len(panel.objmodel) + restored.replay(win, restore_selection=True, edit=False) + assert len(panel.objmodel) == n_before + 1 + new_obj = panel.objmodel.get_object_from_number(len(panel.objmodel)) + assert np.allclose(new_obj.x, src.x) + assert np.allclose(new_obj.y, expected_y) diff --git a/datalab/widgets/fitdialog.py b/datalab/widgets/fitdialog.py index 2aef2fafe..f9eebf2c9 100644 --- a/datalab/widgets/fitdialog.py +++ b/datalab/widgets/fitdialog.py @@ -854,9 +854,7 @@ def evaluate_fit( if fit_type in ("multigaussian", "multilorentzian"): a_x0 = extra.get("a_x0") if a_x0 is None: - raise ValueError( - f"Missing 'a_x0' in extra for {fit_type!r} fit evaluation" - ) + raise ValueError(f"Missing 'a_x0' in extra for {fit_type!r} fit evaluation") a_x0 = np.asarray(a_x0, dtype=float) func = multigaussian if fit_type == "multigaussian" else multilorentzian return func(x, *vals, a_x0=a_x0) From c2a6cdaff1701b5b20706cdbc226b6f98c771f0d Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Tue, 30 Jun 2026 14:35:20 +0200 Subject: [PATCH 036/108] Style(history): Apply ruff formatting to base.py except clause --- datalab/gui/panel/base.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/datalab/gui/panel/base.py b/datalab/gui/panel/base.py index 8ff6690cf..253bf6860 100644 --- a/datalab/gui/panel/base.py +++ b/datalab/gui/panel/base.py @@ -2486,9 +2486,7 @@ def load_from_files( create_group=create_group, add_objects=add_objects, ) - except ( - Exception - ) as exc: # pylint: disable=broad-exception-caught + except Exception as exc: # pylint: disable=broad-exception-caught if ignore_errors: # Ignore unknown file types pass From 2128106a9191989d6c06de1e5c23fb05fbebf9a0 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Tue, 30 Jun 2026 14:49:09 +0200 Subject: [PATCH 037/108] Test(history): Characterization tests locking cascade-recompute behavior (P3a) Safety net before architecture slimming: assert bounded recompute call count (no replay loop), output identity (UUID + __number) preservation, source immutability, and document current metadata-clearing semantics on cascade. --- datalab/tests/features/common/history_test.py | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/datalab/tests/features/common/history_test.py b/datalab/tests/features/common/history_test.py index 00bb45dc5..9546afad4 100644 --- a/datalab/tests/features/common/history_test.py +++ b/datalab/tests/features/common/history_test.py @@ -1782,3 +1782,90 @@ def test_history_interactive_fit_replay(): new_obj = panel.objmodel.get_object_from_number(len(panel.objmodel)) assert np.allclose(new_obj.x, src.x) assert np.allclose(new_obj.y, expected_y) + + +def test_history_recompute_invariants(): + """Characterization: lock current cascade-recompute behavior (pre-P3 slimming). + + These assertions document the *current* behavior of the History panel + cascade so that the upcoming architecture-slimming refactor (routing + recompute through the pre-existing Apply/processor paths) cannot silently + change observable results. Update deliberately (with justification) if a + refactor intentionally changes a documented behavior. + """ + # --- scenario: cascade recompute call-count is bounded (no infinite loop) --- + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + history.toggle_edit_mode(True) + panel = win.signalpanel + action_a, action_b, action_c, output_b, output_c = _build_cascade_chain( + panel, history + ) + output_a = panel.objmodel.get_object_from_number(2) + src_obj = panel.objmodel.get_object_from_number(1) + src_data_before = src_obj.xydata.copy() + number_b = panel.objmodel.get_number(output_b) + number_c = panel.objmodel.get_number(output_c) + + # Spy on the single shared signal processor recompute entry point. + calls = {"n": 0} + original_recompute = panel.processor.recompute_1_to_1 + + def _counting_recompute(*args, **kwargs): + calls["n"] += 1 + return original_recompute(*args, **kwargs) + + panel.processor.recompute_1_to_1 = _counting_recompute + try: + panel.objview.select_objects([2]) + assert panel.objprop.setup_processing_tab(output_a, reset_params=False) + editor = panel.objprop.processing_param_editor + assert editor is not None + editor.dataset.sigma = 7.0 + report = panel.objprop.apply_processing_parameters( + output_a, interactive=False + ) + assert report.success + finally: + panel.processor.recompute_1_to_1 = original_recompute + + # Editing the root re-runs: the root itself (via apply) + the two + # downstream 1-to-1 actions (via cascade). Exactly one call per + # affected action -- a bound that fails if a replay loop reappears. + assert calls["n"] == 3 # root apply + 2 downstream cascade recomputes + + # Identity invariants: outputs keep their UUID *and* their __number. + assert get_uuid(panel.objmodel[get_uuid(output_b)]) == get_uuid(output_b) + assert panel.objmodel.get_number(panel.objmodel[get_uuid(output_b)]) == number_b + assert panel.objmodel.get_number(panel.objmodel[get_uuid(output_c)]) == number_c + + # Source object is never mutated by a downstream edit. + assert np.array_equal(src_obj.xydata, src_data_before) + + # --- scenario: cascade recompute replaces output metadata (current behavior) --- + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + history.toggle_edit_mode(True) + panel = win.signalpanel + action_a, _action_b, _action_c, _output_b, output_c = _build_cascade_chain( + panel, history + ) + uuid_c = get_uuid(output_c) + # Add a user metadata sentinel on the deepest output. + panel.objmodel[uuid_c].metadata["sentinel_p3a"] = 123 + output_a = panel.objmodel.get_object_from_number(2) + panel.objview.select_objects([2]) + assert panel.objprop.setup_processing_tab(output_a, reset_params=False) + editor = panel.objprop.processing_param_editor + assert editor is not None + editor.dataset.sigma = 9.0 + report = panel.objprop.apply_processing_parameters(output_a, interactive=False) + assert report.success + # CHARACTERIZATION (current): the cascade rebuilds the output via + # ``update_obj_in_place``, which clears metadata (keeping only + # ``__uuid``/``__number``), so the user sentinel is dropped. The + # P3c slimming may intentionally change this to the pre-history + # behavior (metadata preserved) -- update this assertion then. + assert "sentinel_p3a" not in panel.objmodel[uuid_c].metadata From 54dc9627663c16f4d740389bb047353884ae94e2 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Tue, 30 Jun 2026 15:06:05 +0200 Subject: [PATCH 038/108] Refactor(history): Unify 1-to-1 in-place reprocess on single primitive (P3b) Introduce ObjectProp.apply_recomputed_object_in_place as the single source of truth for applying a recomputed object onto an existing one in place. Both the interactive Apply callback (edit mode) and the History cascade (recompute_1_to_1_in_place) now route through it, removing duplicated logic and unifying metadata semantics on the pre-history behavior (preserve the object's metadata instead of clearing it). Update the P3a characterization test to reflect the intentional metadata-preservation change. --- datalab/gui/panel/base.py | 50 +++++++++++++------ datalab/gui/panel/history/recompute.py | 5 +- datalab/tests/features/common/history_test.py | 12 ++--- 3 files changed, 41 insertions(+), 26 deletions(-) diff --git a/datalab/gui/panel/base.py b/datalab/gui/panel/base.py index 253bf6860..237106f68 100644 --- a/datalab/gui/panel/base.py +++ b/datalab/gui/panel/base.py @@ -936,24 +936,18 @@ def apply_processing_parameters( if is_edit_mode: # --- Edit mode: mutate obj in-place, cascade downstream --- - # Update the current object in-place with data from new object - obj.title = new_obj.title - if isinstance(obj, SignalObj): - obj.xydata = new_obj.xydata - else: # ImageObj - obj.data = new_obj.data - # Invalidate ROI mask cache when image dimensions may - # have changed (mask depends on image shape) - obj.invalidate_maskdata_cache() - - # Update metadata with new processing parameters + # Apply the recomputed object in place through the shared + # primitive (single source of truth, also used by the + # History panel cascade): updates title + data and the + # processing parameters, preserves obj's metadata, then + # re-runs auto analysis. updated_proc_params = ProcessingParameters( func_name=proc_params.func_name, pattern=proc_params.pattern, param=param, source_uuid=proc_params.source_uuid, ) - insert_processing_parameters(obj, updated_proc_params) + self.apply_recomputed_object_in_place(obj, new_obj, updated_proc_params) # Propagate the edited param to the History panel: # Mutate the matching existing action (snapshot originals @@ -969,10 +963,6 @@ def apply_processing_parameters( hpanel.refresh_action(action) hpanel.recompute_cascade(action) - # Auto-recompute analysis (data changed, results invalid) - obj_processor = self.__get_processor_associated_to(obj) - obj_processor.auto_recompute_analysis(obj) - # Update the tree view item and refresh plot obj_uuid = get_uuid(obj) self.panel.objview.update_item(obj_uuid) @@ -1049,6 +1039,34 @@ def apply_processing_parameters( return report + def apply_recomputed_object_in_place( + self, + obj: SignalObj | ImageObj, + new_obj: SignalObj | ImageObj, + proc_params: ProcessingParameters, + ) -> None: + """Apply a freshly recomputed object onto ``obj`` in place. + + Single source of truth shared by the interactive Apply callback and + the History panel cascade. Copies title + data from ``new_obj`` while + preserving ``obj``'s own metadata (only the processing parameters are + refreshed), then re-runs auto analysis. This keeps both reprocess + paths behaviorally identical (pre-history semantics). + + Args: + obj: Existing object to update in place (identity preserved). + new_obj: Freshly recomputed object providing title + data. + proc_params: Updated processing parameters to store on ``obj``. + """ + obj.title = new_obj.title + if isinstance(obj, SignalObj): + obj.xydata = new_obj.xydata + else: # ImageObj + obj.data = new_obj.data + obj.invalidate_maskdata_cache() + insert_processing_parameters(obj, proc_params) + self.__get_processor_associated_to(obj).auto_recompute_analysis(obj) + class AbstractPanelMeta(type(QW.QSplitter), abc.ABCMeta): """Mixed metaclass to avoid conflicts""" diff --git a/datalab/gui/panel/history/recompute.py b/datalab/gui/panel/history/recompute.py index 2f0fde07e..d612b0d7e 100644 --- a/datalab/gui/panel/history/recompute.py +++ b/datalab/gui/panel/history/recompute.py @@ -259,9 +259,9 @@ def recompute_1_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> Non ) if new_obj is None: return - update_obj_in_place(output_obj, new_obj) - insert_processing_parameters( + panel_data.objprop.apply_recomputed_object_in_place( output_obj, + new_obj, ProcessingParameters( func_name=pp.func_name, pattern=pp.pattern, @@ -269,7 +269,6 @@ def recompute_1_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> Non source_uuid=pp.source_uuid, ), ) - panel_data.processor.auto_recompute_analysis(output_obj) refresh_target(panel_data, output_uuid) diff --git a/datalab/tests/features/common/history_test.py b/datalab/tests/features/common/history_test.py index 9546afad4..4d3ce587e 100644 --- a/datalab/tests/features/common/history_test.py +++ b/datalab/tests/features/common/history_test.py @@ -1843,7 +1843,7 @@ def _counting_recompute(*args, **kwargs): # Source object is never mutated by a downstream edit. assert np.array_equal(src_obj.xydata, src_data_before) - # --- scenario: cascade recompute replaces output metadata (current behavior) --- + # --- scenario: cascade recompute preserves output metadata --- with datalab_test_app_context() as win: history = win.historypanel history.toggle_record_mode(True) @@ -1863,9 +1863,7 @@ def _counting_recompute(*args, **kwargs): editor.dataset.sigma = 9.0 report = panel.objprop.apply_processing_parameters(output_a, interactive=False) assert report.success - # CHARACTERIZATION (current): the cascade rebuilds the output via - # ``update_obj_in_place``, which clears metadata (keeping only - # ``__uuid``/``__number``), so the user sentinel is dropped. The - # P3c slimming may intentionally change this to the pre-history - # behavior (metadata preserved) -- update this assertion then. - assert "sentinel_p3a" not in panel.objmodel[uuid_c].metadata + # P3b: the cascade now routes through the shared pre-history primitive + # (``apply_recomputed_object_in_place``), which PRESERVES the object's + # metadata instead of clearing it. The user sentinel survives. + assert panel.objmodel[uuid_c].metadata.get("sentinel_p3a") == 123 From 2d753745b90b97636b4ee637b2a05fad30f488dd Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Tue, 30 Jun 2026 15:15:47 +0200 Subject: [PATCH 039/108] Refactor(history): Decouple apply_processing_parameters from the editor (P3c) Add an explicit optional 'param' argument to ObjectProp.apply_processing_parameters. When provided it takes precedence over the Processing-tab editor state, turning the interactive Apply path into a reusable, editor-independent pre-history entry point (structural keystone to reduce future per-method history-compatibility work). Backward compatible: param=None keeps the current editor/stored-params fallback. Add a characterization test proving editor-independence via a decoy editor value. --- datalab/gui/panel/base.py | 18 +++++-- .../common/interactive_processing_test.py | 53 +++++++++++++++++++ 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/datalab/gui/panel/base.py b/datalab/gui/panel/base.py index 237106f68..320a34e05 100644 --- a/datalab/gui/panel/base.py +++ b/datalab/gui/panel/base.py @@ -848,13 +848,21 @@ def __auto_recompute_trigger(self) -> None: editor.set(check=False) def apply_processing_parameters( - self, obj: SignalObj | ImageObj | None = None, interactive: bool = True + self, + obj: SignalObj | ImageObj | None = None, + interactive: bool = True, + param: gds.DataSet | None = None, ) -> ProcessingReport: """Apply processing parameters: re-run processing with updated parameters. Args: obj: Signal or Image object to reprocess. If None, uses the current object. interactive: If True, show progress and error messages in the UI. + param: Explicit processing parameters to apply. When provided, this + takes precedence and makes the call independent of the Processing + tab editor state (used e.g. by programmatic recompute paths). + When None (default), fall back to the editor dataset or the + stored processing parameters. Returns: ProcessingReport with success status, object UUID, and optional message. @@ -905,8 +913,12 @@ def apply_processing_parameters( ) return report - # Get updated parameters from editor - param = editor.dataset if editor is not None else proc_params.param + # Resolve the parameters to apply. An explicit ``param`` argument takes + # precedence and makes this method independent of the editor state; + # otherwise fall back to the editor (interactive Apply) or the stored + # processing parameters. + if param is None: + param = editor.dataset if editor is not None else proc_params.param # For cross-panel computations, we need to use the processor from the panel # that owns the source object (e.g., radial_profile is in ImageProcessor) diff --git a/datalab/tests/features/common/interactive_processing_test.py b/datalab/tests/features/common/interactive_processing_test.py index 705abec1f..cd1e27755 100644 --- a/datalab/tests/features/common/interactive_processing_test.py +++ b/datalab/tests/features/common/interactive_processing_test.py @@ -498,6 +498,59 @@ def test_apply_processing_parameters_image(): assert stored_param.value == v1 +def test_apply_processing_parameters_explicit_param(): + """apply_processing_parameters honors an explicit param, ignoring the editor.""" + with qt_app_context(): + with datalab_test_app_context() as win: + panel = win.signalpanel + processor = panel.processor + objprop = panel.objprop + + param = GaussParam.create(mu=250.0, sigma=20.0, a=100.0, y0=10.0, size=500) + panel.new_object(param=param, edit=False) + signal = panel.objview.get_current_object() + assert signal is not None + signal_uuid = get_uuid(signal) + original_signal_data = signal.y.copy() + + v0 = 5.0 + processor.run_feature("addition_constant", ConstantParam.create(value=v0)) + processed_sig = panel.objview.get_current_object() + assert processed_sig is not None + processed_uuid = get_uuid(processed_sig) + assert np.allclose(processed_sig.y, original_signal_data + v0) + + # Select the processed signal to populate the Processing tab editor. + panel.objview.set_current_object(processed_sig) + assert objprop.processing_param_editor is not None + editor = objprop.processing_param_editor + + # Put a DECOY value in the editor: it must be ignored because an + # explicit param is passed to apply_processing_parameters. + editor.dataset.value = 99.0 + + win.historypanel.toggle_edit_mode(True) + + # Apply with an EXPLICIT param (not the editor's decoy value). + v1 = 15.0 + report = objprop.apply_processing_parameters( + param=ConstantParam.create(value=v1) + ) + assert report.success, f"Reprocessing failed: {report.message}" + assert report.obj_uuid == processed_uuid + assert get_uuid(processed_sig) == processed_uuid + + # Output must reflect the EXPLICIT param (original + 15.0), proving + # the editor decoy (99.0) was ignored -> editor-independent. + assert np.allclose(processed_sig.y, original_signal_data + v1) + + pp_dict = processed_sig.get_metadata_option(PROCESSING_PARAMETERS_OPTION) + assert pp_dict["source_uuid"] == signal_uuid + assert pp_dict["func_name"] == "addition_constant" + stored_param = json_to_dataset(pp_dict["param_json"]) + assert stored_param.value == v1 + + def test_no_duplicate_processing_tabs(): """Test that applying processing parameters multiple times doesn't create duplicate tabs. From 8c001112117da388e7fb528a505fe1e06e680e3d Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Tue, 30 Jun 2026 15:21:21 +0200 Subject: [PATCH 040/108] Refactor(history): Drop selection side-effect in recompute_processing batch (P3c-B2) Pass each object's stored param explicitly to apply_processing_parameters instead of selecting the object to populate the Processing-tab editor. Removes the per-object set_current_object workaround (no more highlighting each object during batch recompute), made possible by the editor decoupling from P3c. --- datalab/gui/panel/base.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/datalab/gui/panel/base.py b/datalab/gui/panel/base.py index 320a34e05..f1431c4be 100644 --- a/datalab/gui/panel/base.py +++ b/datalab/gui/panel/base.py @@ -2914,10 +2914,14 @@ def recompute_processing(self) -> None: if progress.wasCanceled(): break - # Temporarily set this object as current to use existing infrastructure - self.objview.set_current_object(obj) + # Reprocess with the object's stored parameters, passed + # explicitly so we no longer need to select the object just + # to populate the Processing-tab editor. + proc_params = extract_processing_parameters(obj) report = self.objprop.apply_processing_parameters( - obj=obj, interactive=False + obj=obj, + interactive=False, + param=proc_params.param if proc_params is not None else None, ) if not report.success and not execenv.unattended: failtxt = _("Failed to recompute object") From 80b505fc28a611d43aa025f3727ce1f298b48a38 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Tue, 30 Jun 2026 15:49:16 +0200 Subject: [PATCH 041/108] Feat(history): Per-panel active-session recording routing (A1) Recording no longer always appends to the last session. Each action now routes to the active recording session of its panel (signal/image), auto-creating a dedicated session per panel on first use, so signal and image pipelines stay in separate sessions. Selecting a session (or one of its actions) while recording makes it the active session for its panel, letting the user resume recording into any session. The history tree adds each action under the correct session item (add_action_to_tree gains an optional session_index, backward compatible). Add a feature test locking the routing and resume-into-selected behavior. --- datalab/gui/historysession_ops.py | 36 ++++++++-- datalab/gui/panel/history/panel.py | 68 +++++++++++++++++-- datalab/tests/features/common/history_test.py | 53 +++++++++++++++ datalab/widgets/historytree.py | 16 +++-- 4 files changed, 158 insertions(+), 15 deletions(-) diff --git a/datalab/gui/historysession_ops.py b/datalab/gui/historysession_ops.py index 8f1f995c5..94d300de1 100644 --- a/datalab/gui/historysession_ops.py +++ b/datalab/gui/historysession_ops.py @@ -23,13 +23,26 @@ _logger = logging.getLogger(__name__) -def create_new_session(panel: HistoryPanel) -> None: - """Create a new history list""" +def create_new_session( + panel: HistoryPanel, panel_str: str | None = None +) -> HistorySession: + """Create a new history session and make it active for its panel. + + Args: + panel_str: Panel the new session belongs to ("signal"/"image"). + Defaults to the current data panel. + + Returns: + The newly created session. + """ + pstr = panel_str or panel._current_panel_str() panel.session_increment += 1 session = HistorySession(number=panel.session_increment) panel.history_sessions.append(session) + panel.set_active_session(session, pstr) panel.tree.populate_tree(panel.history_sessions) panel.refresh_compatibility_items() + return session def start_new_session_after_workspace_reset(panel: HistoryPanel) -> None: @@ -373,11 +386,20 @@ def add_entry( def add_object(panel: HistoryPanel, obj: HistoryAction) -> None: - """Add object to panel""" - if not panel.history_sessions: - panel.create_new_session() - panel.history_sessions[-1].add_action(obj) - panel.tree.add_action_to_tree(obj) + """Add an action to the active session of its panel. + + Routes the action to the active recording session for the action's panel + ("signal"/"image"), creating a dedicated session on first use, so signal + and image pipelines stay in separate sessions and recording resumes in the + user-selected session. + """ + pstr = obj.panel_str or panel._current_panel_str() + session = panel.get_active_session(pstr) + if session is None: + session = panel.create_new_session(panel_str=pstr) + session.add_action(obj) + session_index = panel.history_sessions.index(session) + panel.tree.add_action_to_tree(obj, session_index) panel.tree.rearrange_tree() panel.refresh_compatibility_items() panel.update_actions_state() diff --git a/datalab/gui/panel/history/panel.py b/datalab/gui/panel/history/panel.py index 0e3b42637..0228e6b91 100644 --- a/datalab/gui/panel/history/panel.py +++ b/datalab/gui/panel/history/panel.py @@ -81,6 +81,7 @@ def __init__(self, parent: DLMainWindow) -> None: self.tree.itemSelectionChanged.connect(self.sync_panel_selection) self.tree.itemSelectionChanged.connect(self.update_actions_state) self.tree.itemSelectionChanged.connect(self.update_state_widget) + self.tree.itemSelectionChanged.connect(self.set_active_session_from_selection) self._state_widget = WorkspaceStateWidget(self) @@ -97,6 +98,7 @@ def __init__(self, parent: DLMainWindow) -> None: self.addWidget(widget) self.history_sessions: list[HistorySession] = [] + self._active_session_by_panel: dict[str, HistorySession] = {} self._session_increment = 0 self.action_output_uuids: dict[str, list[str]] = {} self.output_to_action: dict[str, str] = {} @@ -199,7 +201,7 @@ def create_menu_actions(self) -> list[QW.QAction]: new_session_action = create_action( self, _("New session"), - self.create_new_session, + lambda checked=False: self.create_new_session(), icon=get_icon("libre-gui-add.svg"), tip=_("Start a new history session"), ) @@ -634,6 +636,64 @@ def current_action(self) -> HistoryAction | None: except ValueError: return None + def _current_panel_str(self) -> str: + """Return the current data panel id ('signal'/'image'); default 'signal'.""" + pstr = self.mainwindow.get_current_panel() + return pstr if pstr in ("signal", "image") else "signal" + + def session_panel_str(self, session: HistorySession) -> str | None: + """Return the panel a session belongs to. + + Derived from the panel_str of its first tagged action; falls back to + the active-session tracking for freshly created (empty) sessions. + """ + for action in session.actions: + if action.panel_str: + return action.panel_str + for pstr, sess in self._active_session_by_panel.items(): + if sess is session: + return pstr + return None + + def get_active_session(self, panel_str: str) -> HistorySession | None: + """Return the active recording session for ``panel_str``, if still valid.""" + session = self._active_session_by_panel.get(panel_str) + if session is not None and session in self.history_sessions: + return session + return None + + def set_active_session( + self, session: HistorySession, panel_str: str | None = None + ) -> None: + """Mark ``session`` as the active recording session for its panel.""" + pstr = panel_str or self.session_panel_str(session) + if pstr: + self._active_session_by_panel[pstr] = session + + def set_active_session_from_selection(self) -> None: + """When recording, make the selected session the active one for its panel. + + Lets the user resume recording into any session by selecting it (or one + of its actions) in the tree. + """ + if not self.record_mode_enabled: + return + item = self.tree.currentItem() + if item is None or not item.isSelected(): + return + if item.parent() is None: + index = self.tree.indexOfTopLevelItem(item) + if not 0 <= index < len(self.history_sessions): + return + session = self.history_sessions[index] + else: + action = self.current_action() + if action is None: + return + session = self.find_parent_session(action) + if session is not None: + self.set_active_session(session) + def current_session(self) -> HistorySession | None: """Return the session relevant for step navigation.""" item = self.tree.currentItem() @@ -785,9 +845,9 @@ def __iter__(self) -> Generator[HistoryAction, None, None]: # Session operations delegations # ------------------------------------------------------------------ - def create_new_session(self) -> None: - """Create a new history session.""" - return hsess.create_new_session(self) + def create_new_session(self, panel_str: str | None = None) -> HistorySession: + """Create a new history session (active for the given/current panel).""" + return hsess.create_new_session(self, panel_str=panel_str) def start_new_session_after_workspace_reset(self) -> None: """Start a new history session after a workspace reset.""" diff --git a/datalab/tests/features/common/history_test.py b/datalab/tests/features/common/history_test.py index 4d3ce587e..7772070d3 100644 --- a/datalab/tests/features/common/history_test.py +++ b/datalab/tests/features/common/history_test.py @@ -1867,3 +1867,56 @@ def _counting_recompute(*args, **kwargs): # (``apply_recomputed_object_in_place``), which PRESERVES the object's # metadata instead of clearing it. The user sentinel survives. assert panel.objmodel[uuid_c].metadata.get("sentinel_p3a") == 123 + + +def test_history_active_session_routing(): + """Recording routes per-panel into separate active sessions; selecting a + session resumes recording into it (A1).""" + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + spanel, ipanel = win.signalpanel, win.imagepanel + + # --- signal pipeline: one signal session --- + spanel.add_object(create_paracetamol_signal()) + spanel.objview.select_objects([1]) + spanel.processor.run_feature(sips.derivative) + assert len(history.history_sessions) == 1 + signal_session = history.get_active_session("signal") + assert signal_session is not None + assert len(signal_session.actions) == 1 + + # --- image pipeline: lands in a SEPARATE session --- + ipanel.add_object(create_sincos_image()) + ipanel.objview.select_objects([1]) + ipanel.processor.run_feature(sipi.inverse) + image_session = history.get_active_session("image") + assert image_session is not None + assert image_session is not signal_session + assert len(history.history_sessions) == 2 + assert len(image_session.actions) == 1 + # The image action did not leak into the signal session. + assert len(signal_session.actions) == 1 + + # --- back to signal: continue in the SAME signal session (no new one) --- + spanel.objview.select_objects([2]) + spanel.processor.run_feature(sips.derivative) + assert len(history.history_sessions) == 2 # no new session created + assert len(signal_session.actions) == 2 + assert len(image_session.actions) == 1 + + # --- resume into a SELECTED session --- + # Create a fresh (empty) signal session, then select the ORIGINAL signal + # session: a subsequent signal action must resume into the selected + # session, not the newly created empty one. + empty_session = history.create_new_session(panel_str="signal") + assert len(history.history_sessions) == 3 + n_before = len(signal_session.actions) + _select_tree_session(history, signal_session) + spanel.objview.select_objects([1]) + spanel.processor.run_feature( + sips.normalize, sigima.params.NormalizeParam.create(method="maximum") + ) + assert len(signal_session.actions) == n_before + 1 # resumed here + assert len(empty_session.actions) == 0 # NOT the empty session + assert len(image_session.actions) == 1 # image untouched diff --git a/datalab/widgets/historytree.py b/datalab/widgets/historytree.py index 6591285ea..7013dab98 100644 --- a/datalab/widgets/historytree.py +++ b/datalab/widgets/historytree.py @@ -153,14 +153,22 @@ def rearrange_tree(self) -> None: for col in (0, 1): self.resizeColumnToContents(col) - def add_action_to_tree(self, action: HistoryAction) -> None: - """Add an action to the history tree widget + def add_action_to_tree( + self, action: HistoryAction, session_index: int | None = None + ) -> None: + """Add an action under the session item at ``session_index``. Args: - action: Action to add + action: Action to add. + session_index: Top-level session item index. Defaults to the last + session (backward-compatible). """ item = self.action_to_tree_item(action) - ritem = self.topLevelItem(self.topLevelItemCount() - 1) + if session_index is None: + session_index = self.topLevelItemCount() - 1 + ritem = self.topLevelItem(session_index) + if ritem is None: + return ritem.addChild(item) self.install_description_widget(item, action) From 8e56ec853db797427e13d0389b9deaf22a0ab2bd Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Tue, 30 Jun 2026 15:57:58 +0200 Subject: [PATCH 042/108] Feat(history): Highlight active recording session per panel (A2) Make each panel's active recording session visually obvious in the History tree: its top-level item is shown in bold with a palette-derived tint and a tooltip naming the panel. The highlight is keyed by session number so it survives any tree repopulate (delete/replay/HDF5 reload), and it follows active-session changes (selection, auto-create, panel switch). On a Signal/ Image tab switch, the current panel's active session is scrolled into view and the highlight is refreshed, without forcing tree selection (avoids the selection/sync recursion). Add a feature test locking the highlight behavior. --- datalab/gui/main.py | 6 +++ datalab/gui/panel/history/panel.py | 23 +++++++++ datalab/tests/features/common/history_test.py | 47 +++++++++++++++++++ datalab/widgets/historytree.py | 36 ++++++++++++++ 4 files changed, 112 insertions(+) diff --git a/datalab/gui/main.py b/datalab/gui/main.py index ae889e9c7..a56af23c2 100644 --- a/datalab/gui/main.py +++ b/datalab/gui/main.py @@ -1943,6 +1943,12 @@ def __tab_index_changed(self, index: int) -> None: dock = self.docks[self.tabwidget.widget(index)] dock.raise_() self.__update_actions() + if self.historypanel is not None: + widget = self.tabwidget.widget(index) + if widget is self.signalpanel: + self.historypanel.on_current_panel_changed("signal") + elif widget is self.imagepanel: + self.historypanel.on_current_panel_changed("image") def __update_generic_menu(self, menu: QW.QMenu | None = None) -> None: """Update menu before showing up -- Generic method""" diff --git a/datalab/gui/panel/history/panel.py b/datalab/gui/panel/history/panel.py index 0228e6b91..dcf7b3cc9 100644 --- a/datalab/gui/panel/history/panel.py +++ b/datalab/gui/panel/history/panel.py @@ -641,6 +641,20 @@ def _current_panel_str(self) -> str: pstr = self.mainwindow.get_current_panel() return pstr if pstr in ("signal", "image") else "signal" + def on_current_panel_changed(self, panel_str: str) -> None: + """React to a Signal/Image panel switch: bring this panel's active + recording session into view and refresh the active-session highlight. + """ + if panel_str not in ("signal", "image"): + return + self.refresh_active_session_highlight() + session = self.get_active_session(panel_str) + if session is not None and session in self.history_sessions: + index = self.history_sessions.index(session) + item = self.tree.topLevelItem(index) + if item is not None: + self.tree.scrollToItem(item) + def session_panel_str(self, session: HistorySession) -> str | None: """Return the panel a session belongs to. @@ -669,6 +683,15 @@ def set_active_session( pstr = panel_str or self.session_panel_str(session) if pstr: self._active_session_by_panel[pstr] = session + self.refresh_active_session_highlight() + + def refresh_active_session_highlight(self) -> None: + """Update the tree highlight to mark each panel's active session.""" + active: dict[int, str] = {} + for pstr, session in self._active_session_by_panel.items(): + if session in self.history_sessions: + active[session.number] = pstr + self.tree.set_active_sessions(active) def set_active_session_from_selection(self) -> None: """When recording, make the selected session the active one for its panel. diff --git a/datalab/tests/features/common/history_test.py b/datalab/tests/features/common/history_test.py index 7772070d3..e6047bfaf 100644 --- a/datalab/tests/features/common/history_test.py +++ b/datalab/tests/features/common/history_test.py @@ -1920,3 +1920,50 @@ def test_history_active_session_routing(): assert len(signal_session.actions) == n_before + 1 # resumed here assert len(empty_session.actions) == 0 # NOT the empty session assert len(image_session.actions) == 1 # image untouched + + +def test_history_active_session_highlight(): + """Each panel's active recording session is highlighted (bold) in the tree; + the highlight survives a repopulate and follows active-session changes (A2).""" + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + spanel, ipanel = win.signalpanel, win.imagepanel + + spanel.add_object(create_paracetamol_signal()) + spanel.objview.select_objects([1]) + spanel.processor.run_feature(sips.derivative) + signal_session = history.get_active_session("signal") + assert signal_session is not None + + ipanel.add_object(create_sincos_image()) + ipanel.objview.select_objects([1]) + ipanel.processor.run_feature(sipi.inverse) + image_session = history.get_active_session("image") + assert image_session is not None + + def _is_bold(session): + idx = history.history_sessions.index(session) + item = history.tree.topLevelItem(idx) + return item is not None and item.font(0).bold() + + # Both panels' active sessions are highlighted. + assert _is_bold(signal_session) + assert _is_bold(image_session) + + # Highlight survives a full repopulate. + history.tree.populate_tree(history.history_sessions) + assert _is_bold(signal_session) + assert _is_bold(image_session) + + # Creating a new signal session moves the signal highlight to it. + new_signal = history.create_new_session(panel_str="signal") + assert _is_bold(new_signal) + assert not _is_bold(signal_session) # previous signal session no longer active + assert _is_bold(image_session) # image highlight unchanged + + # Switching panels does not crash and keeps the highlight. + win.set_current_panel("image") + win.set_current_panel("signal") + assert _is_bold(new_signal) + assert _is_bold(image_session) diff --git a/datalab/widgets/historytree.py b/datalab/widgets/historytree.py index 7013dab98..adb09c7cc 100644 --- a/datalab/widgets/historytree.py +++ b/datalab/widgets/historytree.py @@ -24,6 +24,7 @@ class HistoryTree(QW.QTreeWidget): DESCRIPTION_COLUMN = 2 COMPATIBILITY_ROLE = QC.Qt.UserRole + 1 + SESSION_NUMBER_ROLE = QC.Qt.UserRole + 2 def __init__(self, parent: QW.QWidget) -> None: """Create a new history tree widget""" @@ -36,6 +37,10 @@ def __init__(self, parent: QW.QWidget) -> None: header.setSectionResizeMode(self.DESCRIPTION_COLUMN, QW.QHeaderView.Stretch) # Per-action expanded state, preserved across repopulate (delete/replay). self.__expanded_state: dict[str, bool] = {} + # Session numbers currently flagged as active recording sessions, + # mapped to their panel id ('signal'/'image'). Used to highlight the + # active session(s) and survive tree repopulation. + self.__active_session_numbers: dict[int, str] = {} def on_description_toggled(self, uuid: str, expanded: bool) -> None: """Remember the expanded state of a description cell.""" @@ -138,6 +143,7 @@ def populate_tree(self, history_sessions: list[HistorySession]) -> None: for session in history_sessions: ritem = QW.QTreeWidgetItem([session.title, session.dtstr]) ritem.setData(0, self.COMPATIBILITY_ROLE, True) + ritem.setData(0, self.SESSION_NUMBER_ROLE, session.number) self.addTopLevelItem(ritem) for action in session.actions: child = self.action_to_tree_item(action) @@ -146,6 +152,36 @@ def populate_tree(self, history_sessions: list[HistorySession]) -> None: self.expandAll() for col in (0, 1): self.resizeColumnToContents(col) + self.__apply_active_highlight() + + def set_active_sessions(self, active_session_numbers: dict[int, str]) -> None: + """Flag the active recording session(s) by session number and panel. + + Args: + active_session_numbers: Mapping ``{session.number: panel_str}`` of + the active recording session for each panel. + """ + self.__active_session_numbers = dict(active_session_numbers) + self.__apply_active_highlight() + + def __apply_active_highlight(self) -> None: + """Bold + tint the top-level items of the active recording sessions.""" + hl = self.palette().color(QG.QPalette.Highlight) + hl.setAlpha(60) + active_brush = QG.QBrush(hl) + normal_brush = QG.QBrush() + tip = _("Active recording session ({panel}).") + for i in range(self.topLevelItemCount()): + item = self.topLevelItem(i) + number = item.data(0, self.SESSION_NUMBER_ROLE) + panel_str = self.__active_session_numbers.get(number) + is_active = panel_str is not None + font = item.font(0) + font.setBold(is_active) + for col in (0, 1): + item.setFont(col, font) + item.setBackground(col, active_brush if is_active else normal_brush) + item.setToolTip(col, tip.format(panel=panel_str) if is_active else "") def rearrange_tree(self) -> None: """Rearrange the history tree widget""" From cc780201b3c5e23207b2f1a75c01d37b44ce560d Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Tue, 30 Jun 2026 16:03:44 +0200 Subject: [PATCH 043/108] I18n(history): Translate per-panel history session strings (fr) Add the French translation for the new 'Active recording session ({panel}).' string introduced by the per-panel history highlight (A2) and finalize three related history-session strings that were still fuzzy (new-session prompts and 'New history session'). Catalog now 100% translated. --- datalab/locale/fr/LC_MESSAGES/datalab.po | 65 +++++++++++++++--------- 1 file changed, 40 insertions(+), 25 deletions(-) diff --git a/datalab/locale/fr/LC_MESSAGES/datalab.po b/datalab/locale/fr/LC_MESSAGES/datalab.po index 223581775..85c7c7118 100644 --- a/datalab/locale/fr/LC_MESSAGES/datalab.po +++ b/datalab/locale/fr/LC_MESSAGES/datalab.po @@ -962,6 +962,15 @@ msgstr "Troncature de données uint32 en int32." msgid "No supported data available in HDF5 file(s)." msgstr "Aucune donnée prise en charge dans le(s) fichier(s) HDF5." +msgid "A new object was loaded. Start a new history session?" +msgstr "Un nouvel objet a été chargé. Démarrer une nouvelle session d'historique ?" + +msgid "A new object was created. Start a new history session?" +msgstr "Un nouvel objet a été créé. Démarrer une nouvelle session d'historique ?" + +msgid "New history session" +msgstr "Nouvelle session d'historique" + msgid "Generate macro" msgstr "Générer une macro" @@ -1287,6 +1296,10 @@ msgstr "Ouvrir %d fichiers HDF5" msgid "Open HDF5 file" msgstr "Ouvrir un fichier HDF5" +#, fuzzy, python-format +msgid "New %s" +msgstr "Créer un nouvel objet %s" + msgid "not started" msgstr "non démarré" @@ -1413,15 +1426,6 @@ msgstr "Paramètres de création" msgid "Creation" msgstr "Création" -msgid "Signal was modified in-place." -msgstr "Le signal a été modifié sur place." - -msgid "Image was modified in-place." -msgstr "L'image a été modifiée sur place." - -msgid "If computation were performed based on this object, they may need to be redone." -msgstr "Si des calculs ont été effectués sur la base de cet objet, ils devront peut-être être refaits." - #, python-format msgid "" "Failed to recreate object with new parameters:\n" @@ -1430,6 +1434,14 @@ msgstr "" "Échec de la recréation de l'objet avec les nouveaux paramètres :\n" "%s" +#, fuzzy +msgid "Signal was recreated." +msgstr "Le signal a été retraité." + +#, fuzzy +msgid "Image was recreated." +msgstr "L'image a été retraitée." + msgid "Processing Parameters" msgstr "Paramètres de traitement" @@ -1562,12 +1574,12 @@ msgstr "Supprimer les métadonnées" msgid "Some selected objects have regions of interest.<br>Do you want to delete them as well?" msgstr "Certains objets sélectionnés ont des régions d'intérêt.<br>Souhaitez-vous les supprimer également ?" -msgid "Group name:" -msgstr "Nom du groupe :" - msgid "New group" msgstr "Nouveau groupe" +msgid "Group name:" +msgstr "Nom du groupe :" + #, python-format msgid "New group \"%s\"" msgstr "Nouveau groupe \"%s\"" @@ -3568,12 +3580,12 @@ msgstr "Cliquer sur OK pour démarrer la démo.<br><br><u>Note :</u><br>- La dé msgid "Click OK to end demo." msgstr "Cliquer sur OK pour terminer la démo." -msgid "Context" -msgstr "Contexte" - msgid "Error:" msgstr "Erreur:" +msgid "Context" +msgstr "Contexte" + #, python-format msgid "The file %s could not be read:" msgstr "Le fichier %s n'a pas pu être ouvert :" @@ -3790,18 +3802,18 @@ msgstr "Déplier la sélection" msgid "HDF5 Browser" msgstr "Explorateur HDF5" -msgid "Value" -msgstr "Valeur" - -msgid "Name" -msgstr "Nom" - msgid "Size" msgstr "Taille" msgid "Type" msgstr "Type" +msgid "Value" +msgstr "Valeur" + +msgid "Name" +msgstr "Nom" + msgid "Unsupported data" msgstr "Données non prises en charge" @@ -3844,18 +3856,22 @@ msgstr "Afficher les détails" msgid "Hide details" msgstr "Masquer les détails" -msgid "Title" -msgstr "Titre" - msgid "Date and time" msgstr "Date et heure" +msgid "Title" +msgstr "Titre" + msgid "Action is compatible with the current workspace state." msgstr "L'action est compatible avec l'état actuel de l'espace de travail." msgid "Action is not compatible with the current workspace state." msgstr "L'action n'est pas compatible avec l'état actuel de l'espace de travail." +#, python-brace-format +msgid "Active recording session ({panel})." +msgstr "Session d'enregistrement active ({panel})." + msgid "Image background selection" msgstr "Sélection de l'arrière-plan de l'image" @@ -4289,4 +4305,3 @@ msgstr "Aucun contour n'a été trouvé pour la plage de niveaux sélectionnée. msgid "Show contour plot..." msgstr "Afficher le tracé de contours..." - From a6896b312b60a8aad7a3689eab9a0e020749076c Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Tue, 30 Jun 2026 16:39:23 +0200 Subject: [PATCH 044/108] Fix: Stabilize history panel identity and failed-compute capture Signal and Image objects store their UUID in metadata["__uuid"] rather than as an attribute, so get_uuid() was generating a throwaway uuid4 on every call, making object identity unstable across the history panel. On top of this, a compute action that produced no output (failure or complete no-op) was still recorded as a successful action in the history tree. * [FIX] : Materialize object identity deterministically in get_uuid() by reusing set_uuid() on first access, instead of generating a transient uuid4 each time * [FIX] : Replace the faulty direct o.uuid access with get_uuid(o) in the AI assistant builtin tools, since data objects have no .uuid attribute * [FIX] : Drop object-producing compute actions (1_to_1, 1_to_n, n_to_1, 2_to_1) from the history when they yield no output, while keeping UI actions (load, duplicate, interactive fit) and 1_to_0 analysis * [NEW] : Add test_history_capture_outputs_drops_failed_compute covering the dropped failed compute plus retained UI action and 1_to_0 analysis --- datalab/aiassistant/tools/builtin.py | 3 +- datalab/gui/historysession_ops.py | 13 ++++ datalab/objectmodel.py | 14 ++++- datalab/tests/features/common/history_test.py | 63 +++++++++++++++++++ 4 files changed, 90 insertions(+), 3 deletions(-) diff --git a/datalab/aiassistant/tools/builtin.py b/datalab/aiassistant/tools/builtin.py index 89972df12..9a217d724 100644 --- a/datalab/aiassistant/tools/builtin.py +++ b/datalab/aiassistant/tools/builtin.py @@ -30,6 +30,7 @@ from datalab.aiassistant.providers.base import ChatMessage from datalab.aiassistant.tools.registry import Tool, ToolRegistry, ToolResult from datalab.gui.actionhandler import ActionCategory +from datalab.objectmodel import get_uuid if TYPE_CHECKING: from datalab.control.proxy import LocalProxy @@ -412,7 +413,7 @@ def _tool_load_file( return { "filename": filename, "panel": panel_widget.PANEL_STR_ID, - "loaded": [{"uuid": o.uuid, "title": o.title} for o in objs], + "loaded": [{"uuid": get_uuid(o), "title": o.title} for o in objs], } diff --git a/datalab/gui/historysession_ops.py b/datalab/gui/historysession_ops.py index 94d300de1..b1d39401b 100644 --- a/datalab/gui/historysession_ops.py +++ b/datalab/gui/historysession_ops.py @@ -294,6 +294,19 @@ def capture_outputs( if uid not in before_p: new_uuids.append(uid) panel.register_action_outputs(action, new_uuids) + if ( + not new_uuids + and action.kind == HistoryAction.KIND_COMPUTE + and action.pattern in {"1_to_1", "1_to_n", "n_to_1", "2_to_1"} + ): + # The compute produced no output object for any selected input: + # it failed (or was a full no-op). Do not keep a misleading "OK" + # entry in the history — remove the just-recorded action and + # refresh the tree so the panel stays consistent. + panel.remove_single_action(action) + panel.tree.populate_tree(panel.history_sessions) + panel.refresh_compatibility_items() + panel.update_actions_state() def add_ui_entry( diff --git a/datalab/objectmodel.py b/datalab/objectmodel.py index 5976c3ae2..335af0d22 100644 --- a/datalab/objectmodel.py +++ b/datalab/objectmodel.py @@ -62,10 +62,20 @@ def set_number(obj: SignalObj | ImageObj | ObjectGroup, number: int) -> None: def get_uuid(obj: SignalObj | ImageObj | ObjectGroup) -> str: - """Get object UUID""" + """Get object UUID. + + For data objects (signals/images), the UUID is stored in metadata under + the ``__uuid`` option. It is materialized on first access (via + :func:`set_uuid`) so that the returned value is stable across calls and + survives serialization. + """ if isinstance(obj, ObjectGroup): return obj.uuid - return obj.get_metadata_option("uuid", str(uuid4())) + uuid = obj.metadata.get("__uuid") + if not uuid: + set_uuid(obj) + uuid = obj.metadata["__uuid"] + return uuid def set_uuid(obj: SignalObj | ImageObj | ObjectGroup) -> None: diff --git a/datalab/tests/features/common/history_test.py b/datalab/tests/features/common/history_test.py index e6047bfaf..9619e4045 100644 --- a/datalab/tests/features/common/history_test.py +++ b/datalab/tests/features/common/history_test.py @@ -1967,3 +1967,66 @@ def _is_bold(session): win.set_current_panel("signal") assert _is_bold(new_signal) assert _is_bold(image_session) + + +def test_history_capture_outputs_drops_failed_compute(): + """A producing compute that creates no object is removed from the history. + + ``capture_outputs`` is the single funnel for object-producing computes: + when an object-producing *compute* action yields no new UUID it has failed + (or was a full no-op) and must not linger as a misleading "OK" entry. UI + actions and ``1_to_0`` analyses legitimately produce no object and must be + preserved. + """ + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + + panel.add_object(create_paracetamol_signal()) + panel.objview.select_objects([1]) + + # --- scenario: producing compute with no output is dropped --- + action = history.add_compute_entry( + "Failing op", + panel_str="signal", + func_name="gaussian_filter", + pattern="1_to_1", + save_state=True, + ) + assert action is not None + len_before = len(history) + with history.capture_outputs(action): + pass # simulate a failed compute: no object created + assert action not in list(history) + assert len(history) == len_before - 1 + assert action.uuid not in history.action_output_uuids + + # --- control: a UI action producing no object is preserved --- + ui_action = history.add_ui_entry( + "Some UI", + target="signalpanel", + method_name="copy_metadata", + save_state=False, + ) + assert ui_action is not None + ui_len_before = len(history) + with history.capture_outputs(ui_action): + pass + assert ui_action in list(history) + assert len(history) == ui_len_before + + # --- control: a 1_to_0 analysis compute producing no object is kept --- + analysis_action = history.add_compute_entry( + "Analysis op", + panel_str="signal", + func_name="stats", + pattern="1_to_0", + save_state=True, + ) + assert analysis_action is not None + analysis_len_before = len(history) + with history.capture_outputs(analysis_action): + pass + assert analysis_action in list(history) + assert len(history) == analysis_len_before From fa18ddf0849e563fcd73d552751f645514179cc0 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Wed, 1 Jul 2026 12:24:15 +0200 Subject: [PATCH 045/108] Chg(history): Narrow history panel scope for current deliverable Temporarily set aside two features not part of the current scope, without removing their implementation, and allow parameter editing when replaying a whole session in edit mode. * [CHG] : Hide the "Generate macro" action from the toolbar and context menu while keeping its implementation for a later re-enable * [CHG] : Hide the "Restore parameters" action from the toolbar and context menu while keeping the restore logic intact * [CHG] : Clicking a session in edit mode now replays it with parameter dialogs instead of a view-only replay, so session parameters stay editable --- datalab/gui/panel/history/interactive_replay.py | 4 ++-- datalab/gui/panel/history/panel.py | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/datalab/gui/panel/history/interactive_replay.py b/datalab/gui/panel/history/interactive_replay.py index 1fa27dd05..0eb79d01f 100644 --- a/datalab/gui/panel/history/interactive_replay.py +++ b/datalab/gui/panel/history/interactive_replay.py @@ -52,9 +52,9 @@ def replay_restore_actions( if panel.edit_mode and isinstance(session_or_action, HistoryAction): # Defer: edit only the selected actions, no automatic cascade edit_actions.append(session_or_action) - elif panel.edit_mode and isinstance(session_or_action, HistorySession): - view_only_session_replay(panel, session_or_action, restore_selection) else: + # Scope decision: clicking a session in edit mode now replays it + # WITH parameter dialogs (view-only session replay disabled). with panel.replaying(), panel.output_suppressed(): session_or_action.replay( panel.mainwindow, diff --git a/datalab/gui/panel/history/panel.py b/datalab/gui/panel/history/panel.py index dcf7b3cc9..5f4580b2e 100644 --- a/datalab/gui/panel/history/panel.py +++ b/datalab/gui/panel/history/panel.py @@ -255,6 +255,9 @@ def create_menu_actions(self) -> list[QW.QAction]: icon=get_icon("console.svg"), tip=_("Generate a Python macro script from history"), ) + # Temporarily disabled (out of current scope): keep the action and its + # implementation, but hide it from the toolbar and context menu. + generate_macro_action.setVisible(False) remove_incompatible_action = create_action( self, _("Remove incompatible"), @@ -269,6 +272,9 @@ def create_menu_actions(self) -> list[QW.QAction]: icon=get_icon("restore_selection.svg"), tip=_("Restore original parameters (discard edit-mode changes)"), ) + # Temporarily disabled (out of current scope): keep the action and its + # restore logic, but hide it from the toolbar and context menu. + self._restore_selection_action.setVisible(False) return [ record_action, new_session_action, From 6a1d5b24678ba998564e48691d361dbf6a1dd41d Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Wed, 1 Jul 2026 14:00:46 +0200 Subject: [PATCH 046/108] Feat(history): introduce derived processing-chain view in History panel First two lots of the History-panel "workflow" refactor. Sessions remain the persistence unit and top-level tree items; processing chains are a derived, read-only view grouping actions by UUID parenthood. * [NEW] : Add pure, non-mutating read-model (chainmodel.py) with ProcessingChain dataclass, action_input_uuids, build_session_chains and build_processing_chains; deterministic grouping rooted at creation or external-root actions, dropping no action * [CHG] : Render the history tree in 3 levels (Session -> Chain -> Action) with new item-kind roles and _build_session_children; update populate_tree, add_action_to_tree, update_compatibility_states, get_selected_actions and get_selected_actions_or_sessions * [CHG] : Make select_action_in_tree and current_session depth-agnostic by walking to the top-level ancestor for the 3-level tree * [CHG] : Target the last action leaf of the session for post-delete auto-selection * [NEW] : Add test_history_chain_model_grouping and make the _get_tree_item_for helper depth-agnostic No persistence-format change. All history tests pass (21 passed), ruff clean. --- datalab/gui/historytools_ops.py | 15 ++- datalab/gui/panel/history/chainmodel.py | 109 ++++++++++++++++++ datalab/gui/panel/history/panel.py | 32 +++-- datalab/tests/features/common/history_test.py | 78 ++++++++++++- datalab/widgets/historytree.py | 73 +++++++++--- 5 files changed, 262 insertions(+), 45 deletions(-) create mode 100644 datalab/gui/panel/history/chainmodel.py diff --git a/datalab/gui/historytools_ops.py b/datalab/gui/historytools_ops.py index 5342c68b3..8c1ede9cf 100644 --- a/datalab/gui/historytools_ops.py +++ b/datalab/gui/historytools_ops.py @@ -430,10 +430,17 @@ def delete_selected(panel: HistoryPanel) -> None: if session_idx >= 0: top = panel.tree.topLevelItem(session_idx) if top is not None: - if top.childCount() > 0: - target_item = top.child(top.childCount() - 1) - else: - target_item = top + last_action_item = None + iterator = QW.QTreeWidgetItemIterator(top) + while iterator.value(): + node = iterator.value() + if ( + node.data(0, panel.tree.ITEM_KIND_ROLE) + == panel.tree.ITEM_ACTION + ): + last_action_item = node + iterator += 1 + target_item = last_action_item if last_action_item is not None else top if target_item is None and panel.tree.topLevelItemCount() > 0: # Fallback: last top-level item (least likely to switch panels) last_top = panel.tree.topLevelItem(panel.tree.topLevelItemCount() - 1) diff --git a/datalab/gui/panel/history/chainmodel.py b/datalab/gui/panel/history/chainmodel.py new file mode 100644 index 000000000..726b17700 --- /dev/null +++ b/datalab/gui/panel/history/chainmodel.py @@ -0,0 +1,109 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +"""Derived processing-chain read-model for the History panel.""" + +from __future__ import annotations + +from dataclasses import dataclass, field +from typing import TYPE_CHECKING + +from datalab.history import HistoryAction, HistorySession + +if TYPE_CHECKING: + from datalab.gui.panel.history.panel import HistoryPanel + + +@dataclass +class ProcessingChain: + """A processing chain: a creation/external root action and its descendants. + + Attributes: + root: The action that starts the chain (creation action or external + root compute/UI action). + actions: Ordered actions belonging to the chain, ``root`` first, + followed by descendants in session order. + session: The :class:`HistorySession` that contains the chain. + """ + + root: HistoryAction + session: HistorySession + actions: list[HistoryAction] = field(default_factory=list) + + +def action_input_uuids(action: HistoryAction) -> set[str]: + """Return the set of input object UUIDs captured by ``action``. + + Combines the recorded selection for the action's panel with any + ``obj2_uuids`` second-operand references (2-to-1 pattern). + + Args: + action: The history action whose inputs are extracted. + + Returns: + The set of object UUIDs that the action consumed as inputs. + """ + captured: set[str] = set(action.state.selection.get(action.panel_str or "", [])) + obj2 = action.kwargs.get("obj2_uuids") + if obj2: + if isinstance(obj2, str): + captured.add(obj2) + else: + captured.update(obj2) + return captured + + +def build_session_chains( + panel: HistoryPanel, session: HistorySession +) -> list[ProcessingChain]: + """Group the actions of a single session into ordered processing chains. + + Args: + panel: The history panel providing the action→output registry. + session: The session whose actions are grouped. + + Returns: + The session's processing chains, in creation order. Each chain lists + its actions in session order, the root first. + """ + uuid_to_chain: dict[str, ProcessingChain] = {} + chains: list[ProcessingChain] = [] + for action in session.actions: + is_creation = ( + action.kind == HistoryAction.KIND_UI + and action.method_name in HistoryAction.UI_CREATION_METHODS + ) + if is_creation: + chain = ProcessingChain(root=action, session=session) + chains.append(chain) + chain.actions.append(action) + else: + inputs = action_input_uuids(action) + chain = None + for uuid in sorted(inputs): + if uuid in uuid_to_chain: + chain = uuid_to_chain[uuid] + break + if chain is None: + chain = ProcessingChain(root=action, session=session) + chains.append(chain) + chain.actions.append(action) + for out in panel.action_output_uuids.get(action.uuid, []): + uuid_to_chain[out] = chain + return chains + + +def build_processing_chains( + panel: HistoryPanel, +) -> list[tuple[HistorySession, list[ProcessingChain]]]: + """Return, for each session (in order), its ordered list of processing chains. + + Args: + panel: The history panel owning sessions and output registry. + + Returns: + A list of (session, chains) tuples in session order. + """ + return [ + (session, build_session_chains(panel, session)) + for session in panel.history_sessions + ] diff --git a/datalab/gui/panel/history/panel.py b/datalab/gui/panel/history/panel.py index 5f4580b2e..2c55175bf 100644 --- a/datalab/gui/panel/history/panel.py +++ b/datalab/gui/panel/history/panel.py @@ -727,14 +727,12 @@ def current_session(self) -> HistorySession | None: """Return the session relevant for step navigation.""" item = self.tree.currentItem() if item is not None: - if item.parent() is None: - index = self.tree.indexOfTopLevelItem(item) - if 0 <= index < len(self.history_sessions): - return self.history_sessions[index] - else: - action = self.current_action() - if action is not None: - return self.find_parent_session(action) + top = item + while top.parent() is not None: + top = top.parent() + index = self.tree.indexOfTopLevelItem(top) + if 0 <= index < len(self.history_sessions): + return self.history_sessions[index] if self.history_sessions: return self.history_sessions[-1] return None @@ -761,15 +759,15 @@ def can_step_next(self) -> bool: def select_action_in_tree(self, action: HistoryAction) -> None: """Select ``action`` in the tree (triggers ``sync_panel_selection``).""" - for i in range(self.tree.topLevelItemCount()): - sess_item = self.tree.topLevelItem(i) - for j in range(sess_item.childCount()): - child = sess_item.child(j) - if child.data(0, QC.Qt.UserRole) == action.uuid: - self.tree.clearSelection() - self.tree.setCurrentItem(child) - child.setSelected(True) - return + iterator = QW.QTreeWidgetItemIterator(self.tree) + while iterator.value(): + item = iterator.value() + if item.data(0, QC.Qt.UserRole) == action.uuid: + self.tree.clearSelection() + self.tree.setCurrentItem(item) + item.setSelected(True) + return + iterator += 1 def step_prev(self) -> None: """Select the previous action in the current session.""" diff --git a/datalab/tests/features/common/history_test.py b/datalab/tests/features/common/history_test.py index 9619e4045..4554ffbb4 100644 --- a/datalab/tests/features/common/history_test.py +++ b/datalab/tests/features/common/history_test.py @@ -36,6 +36,7 @@ import sigima.proc.image as sipi import sigima.proc.signal as sips from qtpy import QtCore as QC +from qtpy import QtWidgets as QW from sigima.objects import create_signal_roi from sigima.objects.base import BaseROI from sigima.objects.signal.creation import NewSignalParam @@ -53,6 +54,11 @@ HistoryTree, WorkspaceState, ) +from datalab.gui.panel.history.chainmodel import ( + ProcessingChain, + build_processing_chains, + build_session_chains, +) from datalab.gui.processor.base import extract_processing_parameters from datalab.h5.native import NativeH5Reader, NativeH5Writer from datalab.objectmodel import get_uuid @@ -104,12 +110,12 @@ def _session_action_counts(history) -> list[int]: def _get_tree_item_for(history, entry: HistoryAction): """Return the tree item matching ``entry`` in the history tree.""" tree = history.tree - for i in range(tree.topLevelItemCount()): - sess_item = tree.topLevelItem(i) - for j in range(sess_item.childCount()): - child = sess_item.child(j) - if child.data(0, QC.Qt.UserRole) == entry.uuid: - return child + iterator = QW.QTreeWidgetItemIterator(tree) + while iterator.value(): + item = iterator.value() + if item.data(0, QC.Qt.UserRole) == entry.uuid: + return item + iterator += 1 raise AssertionError(f"No tree item found for entry {entry.uuid}") @@ -1676,6 +1682,66 @@ def test_history_chain_reconnect(): assert src_uuid in reconnected_uuids +def test_history_chain_model_grouping(): + """Derived processing-chain read-model groups actions into ordered chains.""" + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + + # Creation via the main-window proxy records a ``new_object`` action and + # registers its output UUID. ``panel.add_object`` deliberately does not + # record, so it is used below to exercise an externally-rooted chain. + win.add_object(create_paracetamol_signal()) + panel.objview.select_objects([1]) + panel.processor.run_feature( + sips.normalize, sigima.params.NormalizeParam.create(method="maximum") + ) + panel.objview.select_objects([2]) + panel.processor.run_feature(sips.derivative) + + # --- invariant: grouping drops no action, per session --- + grouped = build_processing_chains(history) + assert len(grouped) == len(history.history_sessions) + for sess, sess_chains in grouped: + assert isinstance(sess, HistorySession) + assert sum(len(c.actions) for c in sess_chains) == len(sess.actions) + + # --- creation-rooted chain: creation -> normalize -> derivative --- + all_chains = [c for _sess, chains in grouped for c in chains] + creation_chains = [ + c + for c in all_chains + if c.root.kind == HistoryAction.KIND_UI + and c.root.method_name in HistoryAction.UI_CREATION_METHODS + ] + assert len(creation_chains) == 1 + chain = creation_chains[0] + assert isinstance(chain, ProcessingChain) + assert chain.actions[0] is chain.root + assert [a.func_name for a in chain.actions] == [None, "normalize", "derivative"] + assert all(a in chain.session.actions for a in chain.actions) + + # --- externally-rooted chain: panel.add_object records no creation, so a + # compute on such an object roots its own (compute) chain --- + panel.add_object(create_paracetamol_signal()) + panel.objview.select_objects([len(panel.objmodel)]) + panel.processor.run_feature(sips.derivative) + grouped2 = build_processing_chains(history) + for sess, sess_chains in grouped2: + assert sum(len(c.actions) for c in sess_chains) == len(sess.actions) + external_chains = [ + c + for _sess, chains in grouped2 + for c in chains + if c.root.kind == HistoryAction.KIND_COMPUTE + ] + assert external_chains + + # Keep build_session_chains imported — it is public API under test + assert callable(build_session_chains) + + def test_history_new_session_prompt_on_input(monkeypatch): """Creating an object on a non-empty session offers to start a new session.""" # --- scenario: user accepts the prompt -> a new session is opened --- diff --git a/datalab/widgets/historytree.py b/datalab/widgets/historytree.py index adb09c7cc..3a8bffd32 100644 --- a/datalab/widgets/historytree.py +++ b/datalab/widgets/historytree.py @@ -12,11 +12,13 @@ from qtpy import QtWidgets as QW from datalab.config import _ +from datalab.gui.panel.history.chainmodel import build_session_chains from datalab.history import HistoryAction, HistorySession from datalab.widgets.historydescription import CollapsibleDescriptionWidget if TYPE_CHECKING: from datalab.gui.main import DLMainWindow + from datalab.gui.panel.history.panel import HistoryPanel class HistoryTree(QW.QTreeWidget): @@ -25,10 +27,15 @@ class HistoryTree(QW.QTreeWidget): DESCRIPTION_COLUMN = 2 COMPATIBILITY_ROLE = QC.Qt.UserRole + 1 SESSION_NUMBER_ROLE = QC.Qt.UserRole + 2 + ITEM_KIND_ROLE = QC.Qt.UserRole + 3 + ITEM_SESSION = "session" + ITEM_CHAIN = "chain" + ITEM_ACTION = "action" def __init__(self, parent: QW.QWidget) -> None: """Create a new history tree widget""" super().__init__(parent) + self._panel: HistoryPanel = parent self.setHeaderLabels([_("Title"), _("Date and time"), _("Description")]) self.setContextMenuPolicy(QC.Qt.CustomContextMenu) self.setSelectionMode(QW.QAbstractItemView.ContiguousSelection) @@ -86,6 +93,7 @@ def action_to_tree_item(cls, action: HistoryAction) -> QW.QTreeWidgetItem: item = QW.QTreeWidgetItem([action.title, action.dtstr, ""]) item.setData(0, QC.Qt.UserRole, action.uuid) item.setData(0, cls.COMPATIBILITY_ROLE, True) + item.setData(0, cls.ITEM_KIND_ROLE, cls.ITEM_ACTION) return item def update_compatibility_states( @@ -100,24 +108,25 @@ def update_compatibility_states( incompatible_tip = _( "Action is not compatible with the current workspace state." ) - for i in range(self.topLevelItemCount()): - session_item = self.topLevelItem(i) - for j in range(session_item.childCount()): - child = session_item.child(j) - uuid = child.data(0, QC.Qt.UserRole) + iterator = QW.QTreeWidgetItemIterator(self) + while iterator.value(): + item = iterator.value() + if item.data(0, self.ITEM_KIND_ROLE) == self.ITEM_ACTION: + uuid = item.data(0, QC.Qt.UserRole) action = self.get_action_from_uuid(uuid, history_sessions) compatible = action.is_current_state_compatible( mainwindow, restore_selection=True ) - child.setData(0, self.COMPATIBILITY_ROLE, compatible) + item.setData(0, self.COMPATIBILITY_ROLE, compatible) brush = default_brush if compatible else disabled_brush icon = get_icon("apply.svg") if compatible else get_icon("delete.svg") - child.setIcon(0, icon) + item.setIcon(0, icon) for col in range(self.columnCount()): - child.setForeground(col, brush) - child.setToolTip( + item.setForeground(col, brush) + item.setToolTip( col, compatible_tip if compatible else incompatible_tip ) + iterator += 1 def forget_orphan_expanded_states( self, history_sessions: list[HistorySession] @@ -144,16 +153,41 @@ def populate_tree(self, history_sessions: list[HistorySession]) -> None: ritem = QW.QTreeWidgetItem([session.title, session.dtstr]) ritem.setData(0, self.COMPATIBILITY_ROLE, True) ritem.setData(0, self.SESSION_NUMBER_ROLE, session.number) + ritem.setData(0, self.ITEM_KIND_ROLE, self.ITEM_SESSION) self.addTopLevelItem(ritem) - for action in session.actions: - child = self.action_to_tree_item(action) - ritem.addChild(child) - self.install_description_widget(child, action) + self._build_session_children(ritem, session) self.expandAll() for col in (0, 1): self.resizeColumnToContents(col) self.__apply_active_highlight() + def _build_session_children( + self, session_item: QW.QTreeWidgetItem, session: HistorySession + ) -> None: + """(Re)build the chain/action subtree under ``session_item``. + + Args: + session_item: Top-level tree item for ``session``. + session: History session whose actions are grouped into chains. + """ + session_item.takeChildren() + chains = build_session_chains(self._panel, session) + for chain in chains: + chain_item = QW.QTreeWidgetItem([chain.root.title, ""]) + chain_item.setData(0, self.ITEM_KIND_ROLE, self.ITEM_CHAIN) + chain_item.setData(0, self.COMPATIBILITY_ROLE, True) + font = chain_item.font(0) + font.setBold(True) + chain_item.setFont(0, font) + chain_item.setToolTip( + 0, _("Processing chain \u2014 %d step(s)") % len(chain.actions) + ) + session_item.addChild(chain_item) + for action in chain.actions: + child = self.action_to_tree_item(action) + chain_item.addChild(child) + self.install_description_widget(child, action) + def set_active_sessions(self, active_session_numbers: dict[int, str]) -> None: """Flag the active recording session(s) by session number and panel. @@ -199,14 +233,14 @@ def add_action_to_tree( session_index: Top-level session item index. Defaults to the last session (backward-compatible). """ - item = self.action_to_tree_item(action) if session_index is None: session_index = self.topLevelItemCount() - 1 ritem = self.topLevelItem(session_index) if ritem is None: return - ritem.addChild(item) - self.install_description_widget(item, action) + session = self._panel.history_sessions[session_index] + self._build_session_children(ritem, session) + ritem.setExpanded(True) def refresh_action_item(self, action: HistoryAction) -> None: """Refresh the tree item corresponding to ``action``. @@ -269,9 +303,10 @@ def get_selected_actions_or_sessions( if item.parent() is None: index = self.indexOfTopLevelItem(item) selected.append(history_sessions[index]) - else: + elif item.data(0, self.ITEM_KIND_ROLE) == self.ITEM_ACTION: uuid = item.data(0, QC.Qt.UserRole) selected.append(self.get_action_from_uuid(uuid, history_sessions)) + # chain-header items are containers only: ignored here. return selected def get_selected_actions( @@ -287,7 +322,9 @@ def get_selected_actions( """ selected: list[HistoryAction] = [] for item in self.selectedItems(): - if item.parent() is not None: + if item.parent() is not None and ( + item.data(0, self.ITEM_KIND_ROLE) == self.ITEM_ACTION + ): uuid = item.data(0, QC.Qt.UserRole) selected.append(self.get_action_from_uuid(uuid, history_sessions)) return selected From 1c9ac2cd8dfb5c6aaa0e95fcc8f64cdff0511635 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Wed, 1 Jul 2026 15:06:52 +0200 Subject: [PATCH 047/108] Feat(history): Split chains on delete and add step-by-step replay MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This delivers two lots of the History-panel workflow refactor, both scoped to DataLab with no change to the persistence format. Deleting an intermediate history action previously truncated the whole session, discarding every downstream step. It now splices the action out of its processing chain and preserves the work that followed. When the deleted action had downstream steps, its now-orphaned output object is deep-copied into a new "Chain copy" group as a parentless creation root, and every downstream action consuming that output is rewired onto the copy, so the derived chain view renders those steps as a new independent chain. The persistent "Edit mode" toggle was error-prone as a long-lived session state. It is now hidden from the toolbar and context menu (code and API kept) in favor of two explicit launch modes, making replay intent clear at the moment the user triggers it. * [CHG] : Deleting an intermediate action now splits its processing chain instead of truncating the session; downstream steps are preserved on a deep-copied autonomous output and rendered as a new independent chain * [NEW] : Opt-in confirmation (skipped when unattended) to also remove the orphaned output object(s) from the workspace after a chain split * [CHG] : Hide the persistent "Edit mode" toggle from the toolbar and context menu, replaced by explicit "Replay" (silent) and "Step-by-step" launch modes; double-click behavior unchanged * [NEW] : "Step-by-step" replay action driving parameter dialogs and committing edits immediately, with no persistent edit session (replay_step_by_step) * [NEW] : French translations for the 6 new UI strings; resolved 2 fuzzy entries, including a stale "Processing chain — %d step(s)" that broke .mo compilation New tests: test_history_delete_splits_chain, test_history_step_by_step_launch. Full history suite: 23 passed, ruff clean. --- datalab/gui/historytools_ops.py | 192 ++++++++++++++++-- datalab/gui/panel/history/panel.py | 45 +++- datalab/locale/fr/LC_MESSAGES/datalab.po | 26 ++- datalab/tests/features/common/history_test.py | 80 ++++++++ 4 files changed, 321 insertions(+), 22 deletions(-) diff --git a/datalab/gui/historytools_ops.py b/datalab/gui/historytools_ops.py index 8c1ede9cf..52eb46e24 100644 --- a/datalab/gui/historytools_ops.py +++ b/datalab/gui/historytools_ops.py @@ -12,14 +12,18 @@ from datalab.config import _ from datalab.env import execenv +from datalab.gui.panel.history import chain as hchain from datalab.gui.processor.base import ( PROCESSING_PARAMETERS_OPTION, ProcessingParameters, + extract_processing_parameters, + insert_processing_parameters, ) from datalab.history import HistoryAction, HistorySession from datalab.objectmodel import get_uuid if TYPE_CHECKING: + from datalab.gui.panel.base import BaseDataPanel from datalab.gui.panel.history import HistoryPanel @@ -357,13 +361,150 @@ def generate_macro(panel: HistoryPanel) -> None: ) +def _data_panel_for(panel: HistoryPanel, panel_str: str) -> BaseDataPanel | None: + """Return the data panel matching ``panel_str`` (``"signal"``/``"image"``).""" + if panel_str == "signal": + return panel.mainwindow.signalpanel + if panel_str == "image": + return panel.mainwindow.imagepanel + return None + + +def _action_input_uuids(action: HistoryAction) -> set[str]: + """Return the set of object UUIDs consumed as inputs by ``action``.""" + captured: set[str] = set(action.state.selection.get(action.panel_str or "", [])) + obj2 = action.kwargs.get("obj2_uuids") + if obj2: + if isinstance(obj2, str): + captured.add(obj2) + else: + captured.update(obj2) + return captured + + +def _strip_source_links(obj) -> None: + """Turn ``obj`` into a parentless creation root (drop source references).""" + pp = extract_processing_parameters(obj) + if pp is None: + return + insert_processing_parameters( + obj, + ProcessingParameters( + func_name=pp.func_name, + pattern=pp.pattern, + param=pp.param, + source_uuid=None, + source_uuids=None, + ), + ) + + +def _remap_object_source(obj, old_uuid: str, new_uuid: str) -> None: + """Replace ``old_uuid`` with ``new_uuid`` in ``obj``'s source references.""" + pp = extract_processing_parameters(obj) + if pp is None: + return + changed = False + if pp.source_uuid == old_uuid: + pp.source_uuid = new_uuid + changed = True + if pp.source_uuids and old_uuid in pp.source_uuids: + pp.source_uuids = [new_uuid if u == old_uuid else u for u in pp.source_uuids] + changed = True + if changed: + insert_processing_parameters(obj, pp) + + +def _first_alive_output( + panel: HistoryPanel, panel_str: str, output_uuids: list[str] +) -> str | None: + """Return the first ``output_uuids`` entry still present in its data panel.""" + data_panel = _data_panel_for(panel, panel_str) + if data_panel is None: + return None + for out_uuid in output_uuids: + if data_panel.objmodel.has_uuid(out_uuid): + return out_uuid + return None + + +def _split_chain_on_action_delete( + panel: HistoryPanel, action: HistoryAction +) -> str | None: + """Splice ``action`` out of its session and split its processing chain. + + The action is removed from its session (splice, not truncate). If it had + downstream compute steps, the first downstream action becomes the head of a + new, independent chain: the deleted action's now-orphaned output object is + deep-copied into a new ``Chain copy`` group as a parentless creation root, + and the downstream head is rewired to consume that copy. + + Args: + panel: The history panel owning sessions and the output registry. + action: The action to delete. + + Returns: + The UUID of the deleted action's output object if it remains present + (now truly orphaned) in its data panel, otherwise ``None``. + """ + panel_str = action.panel_str or "" + # Compute downstream + captured output UUIDs BEFORE removing the action. + downstream = hchain.get_downstream_actions(panel, action) + output_uuids = list(panel.action_output_uuids.get(action.uuid, [])) + # Splice the action out (does not truncate the rest of the session). + hchain.remove_single_action(panel, action) + if not downstream: + return _first_alive_output(panel, panel_str, output_uuids) + first = downstream[0] + data_panel = _data_panel_for(panel, first.panel_str or "") + if data_panel is None: + return _first_alive_output(panel, panel_str, output_uuids) + # Locate the orphaned output object that ``first`` still consumes. + first_inputs = _action_input_uuids(first) + orphan_uuid = next((u for u in output_uuids if u in first_inputs), None) + if orphan_uuid is None or not data_panel.objmodel.has_uuid(orphan_uuid): + return _first_alive_output(panel, panel_str, output_uuids) + # §8.2 — autonomy via COPY: clone the orphan as a parentless creation root. + orphan_obj = data_panel.objmodel[orphan_uuid] + clone = deepcopy(orphan_obj) + new_uuid = str(uuid4()) + try: + clone.set_metadata_option("uuid", new_uuid) + except AttributeError: + clone.uuid = new_uuid + _strip_source_links(clone) + group_id = get_uuid(data_panel.add_group(_("Chain copy"))) + data_panel.add_object(clone, group_id=group_id) + # Rewire ALL downstream actions that directly consume the orphan onto the copy. + for d in downstream: + if orphan_uuid not in _action_input_uuids(d): + continue + hchain.rewrite_action_source(d, d.panel_str or "", orphan_uuid, new_uuid) + for out_uuid in panel.action_output_uuids.get(d.uuid, []): + if data_panel.objmodel.has_uuid(out_uuid): + _remap_object_source( + data_panel.objmodel[out_uuid], orphan_uuid, new_uuid + ) + # The orphan is now consumed by no surviving action: report it as orphaned. + return orphan_uuid if data_panel.objmodel.has_uuid(orphan_uuid) else None + + +def _remove_data_object(data_panel: BaseDataPanel, obj_uuid: str) -> None: + """Remove a single object from ``data_panel`` without recording history.""" + obj = data_panel.objmodel[obj_uuid] + data_panel.plothandler.remove_item(obj_uuid) + data_panel.objview.remove_item(obj_uuid, refresh=False) + data_panel.objmodel.remove_object(obj) + + def delete_selected(panel: HistoryPanel) -> None: """Delete the selected actions or sessions (with confirmation). When a top-level session is selected, the entire session is deleted. - When individual actions are selected, they and all subsequent actions - in their parent session are removed. After deletion, the first - available item in the tree is selected automatically. + When individual actions are selected, each action is spliced out of its + session and its processing chain is split: downstream steps become an + independent chain rooted at a copy of the deleted action's output. After + deletion, the last action leaf in the affected session is selected. """ selected = panel.tree.get_selected_actions_or_sessions(panel.history_sessions) if not selected: @@ -372,8 +513,8 @@ def delete_selected(panel: HistoryPanel) -> None: if has_individual_actions: msg = _( "Do you really want to delete the selected items?\n\n" - "Note: deleting an action also removes all subsequent " - "actions in the same session." + "Note: deleting an intermediate action splits its processing " + "chain; downstream steps become an independent chain." ) else: msg = _("Do you really want to delete the selected items?") @@ -402,20 +543,45 @@ def delete_selected(panel: HistoryPanel) -> None: break sessions_to_remove: set[int] = set() + orphan_refs: list[tuple[str, str]] = [] for item in selected: if isinstance(item, HistorySession): sessions_to_remove.add(id(item)) - else: - # Individual action: remove from its parent session - for session in panel.history_sessions: - if item in session.actions: - session.remove_action(item) - if not session.actions: - sessions_to_remove.add(id(session)) - break + elif isinstance(item, HistoryAction): + # Individual action: splice it out and split its chain (with copy). + orphan_uuid = _split_chain_on_action_delete(panel, item) + if orphan_uuid is not None: + orphan_refs.append((item.panel_str or "", orphan_uuid)) panel.history_sessions = [ s for s in panel.history_sessions if id(s) not in sessions_to_remove ] + # §8.3 — opt-in: offer to also remove the now-orphaned output object(s). + alive_orphans: list[tuple[BaseDataPanel, str]] = [] + for panel_str, orphan_uuid in orphan_refs: + data_panel = _data_panel_for(panel, panel_str) + if data_panel is not None and data_panel.objmodel.has_uuid(orphan_uuid): + alive_orphans.append((data_panel, orphan_uuid)) + if alive_orphans and not execenv.unattended: + answer = QW.QMessageBox.question( + panel.mainwindow, + _("Delete"), + _( + "The deleted action(s) produced object(s) still present in the " + "workspace. Do you want to remove the associated object(s) as well?" + ), + QW.QMessageBox.Yes | QW.QMessageBox.No, + QW.QMessageBox.No, + ) + if answer == QW.QMessageBox.Yes: + touched: dict[int, BaseDataPanel] = {} + for data_panel, orphan_uuid in alive_orphans: + if data_panel.objmodel.has_uuid(orphan_uuid): + _remove_data_object(data_panel, orphan_uuid) + touched[id(data_panel)] = data_panel + for data_panel in touched.values(): + data_panel.objview.update_tree() + data_panel.selection_changed(update_items=True) + panel.refresh_obj_ids_snapshot() panel.tree.populate_tree(panel.history_sessions) panel.refresh_compatibility_items() panel.update_actions_state() diff --git a/datalab/gui/panel/history/panel.py b/datalab/gui/panel/history/panel.py index 2c55175bf..651a5c83d 100644 --- a/datalab/gui/panel/history/panel.py +++ b/datalab/gui/panel/history/panel.py @@ -190,6 +190,10 @@ def create_menu_actions(self) -> list[QW.QAction]: ) edit_action.setChecked(self.edit_mode) self._edit_action = edit_action + # Temporarily disabled (superseded by the Replay / Step-by-step launch + # modes): keep the action and its edit-mode logic, but hide it from the + # toolbar and context menu. + edit_action.setVisible(False) record_action = create_action( self, _("Record mode"), @@ -275,6 +279,20 @@ def create_menu_actions(self) -> list[QW.QAction]: # Temporarily disabled (out of current scope): keep the action and its # restore logic, but hide it from the toolbar and context menu. self._restore_selection_action.setVisible(False) + replay_action = create_action( + self, + _("Replay"), + lambda: self.replay_restore_actions(restore_selection=False), + icon=get_icon("replay.svg"), + tip=_("Replay the selection silently (no parameter dialogs)"), + ) + step_by_step_action = create_action( + self, + _("Step-by-step"), + triggered=lambda checked=False: self.replay_step_by_step(), + icon=get_icon("edit_mode.svg"), + tip=_("Replay the selection step by step, editing parameters at each step"), + ) return [ record_action, new_session_action, @@ -285,12 +303,8 @@ def create_menu_actions(self) -> list[QW.QAction]: self.step_prev_action, self.step_next_action, None, - create_action( - self, - _("Replay"), - lambda: self.replay_restore_actions(restore_selection=False), - icon=get_icon("replay.svg"), - ), + replay_action, + step_by_step_action, self._restore_selection_action, edit_action, None, @@ -400,6 +414,25 @@ def replay_restore_actions( """Replay and/or restore selection for the selected actions.""" return hreplay.replay_restore_actions(self, replay, restore_selection) + def replay_step_by_step(self) -> None: + """Replay the current selection step by step, prompting for parameters. + + Dialog-driven launch mode: each replayed action opens its parameter + dialog (reusing the edit-mode machinery), then recomputes. Edits are + committed immediately -- there is no persistent edit session. + """ + previous = self.edit_mode + self.edit_mode = True + try: + self.replay_restore_actions(replay=True, restore_selection=False) + finally: + self.edit_mode = previous + # Commit step-by-step edits immediately (no persistent edit session). + for session in self.history_sessions: + for action in session.actions: + action.discard_snapshot() + self.update_actions_state() + def prompt_edit_action_params(self, action: HistoryAction) -> bool | None: """Open the parameter dialog for *action* according to its pattern.""" return hreplay.prompt_edit_action_params(self, action) diff --git a/datalab/locale/fr/LC_MESSAGES/datalab.po b/datalab/locale/fr/LC_MESSAGES/datalab.po index 85c7c7118..08e0eb386 100644 --- a/datalab/locale/fr/LC_MESSAGES/datalab.po +++ b/datalab/locale/fr/LC_MESSAGES/datalab.po @@ -981,18 +981,24 @@ msgstr "Pas d'actions de calcul à exporter." msgid "Macro script copied to clipboard (%d actions)." msgstr "Script de macro copié dans le presse-papier (%d actions)." +msgid "Chain copy" +msgstr "Copie de chaîne" + msgid "" "Do you really want to delete the selected items?\n" "\n" -"Note: deleting an action also removes all subsequent actions in the same session." +"Note: deleting an intermediate action splits its processing chain; downstream steps become an independent chain." msgstr "" -"Êtes-vous sûr de vouloir supprimer le(s) groupe(s) sélectionné(s) ?\n" +"Êtes-vous sûr de vouloir supprimer les éléments sélectionnés ?\n" "\n" -"Remarque : la suppression d'une action entraîne également la suppression de toutes les actions suivantes dans la même session." +"Remarque : la suppression d'une action intermédiaire divise sa chaîne de traitement ; les étapes en aval deviennent une chaîne indépendante." msgid "Do you really want to delete the selected items?" msgstr "Êtes-vous sûr de vouloir supprimer le(s) groupe(s) sélectionné(s) ?" +msgid "The deleted action(s) produced object(s) still present in the workspace. Do you want to remove the associated object(s) as well?" +msgstr "La ou les actions supprimées ont produit des objets encore présents dans l'espace de travail. Voulez-vous également supprimer le ou les objets associés ?" + msgid "Remove incompatible" msgstr "Supprimer les actions incompatibles" @@ -1791,6 +1797,15 @@ msgstr "Restaurer les paramètres d'origine (annuler les modifications du mode d msgid "Replay" msgstr "Rejouer" +msgid "Replay the selection silently (no parameter dialogs)" +msgstr "Rejouer la sélection silencieusement (sans boîtes de dialogue de paramètres)" + +msgid "Step-by-step" +msgstr "Pas à pas" + +msgid "Replay the selection step by step, editing parameters at each step" +msgstr "Rejouer la sélection pas à pas, en modifiant les paramètres à chaque étape" + msgid "Commit edit mode changes?" msgstr "Valider les modifications du mode d'édition ?" @@ -3868,6 +3883,10 @@ msgstr "L'action est compatible avec l'état actuel de l'espace de travail." msgid "Action is not compatible with the current workspace state." msgstr "L'action n'est pas compatible avec l'état actuel de l'espace de travail." +#, python-format +msgid "Processing chain — %d step(s)" +msgstr "Chaîne de traitement — %d étape(s)" + #, python-brace-format msgid "Active recording session ({panel})." msgstr "Session d'enregistrement active ({panel})." @@ -4305,3 +4324,4 @@ msgstr "Aucun contour n'a été trouvé pour la plage de niveaux sélectionnée. msgid "Show contour plot..." msgstr "Afficher le tracé de contours..." + diff --git a/datalab/tests/features/common/history_test.py b/datalab/tests/features/common/history_test.py index 4554ffbb4..0d53511b7 100644 --- a/datalab/tests/features/common/history_test.py +++ b/datalab/tests/features/common/history_test.py @@ -1439,6 +1439,27 @@ def test_history_edit_in_tree(): assert panel.objview.get_sel_object_uuids() == [src_uuid] +def test_history_step_by_step_launch(): + """Step-by-step launch replays with dialogs then commits edits immediately.""" + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) + panel.objview.select_objects([1]) + panel.processor.run_feature( + sips.normalize, sigima.params.NormalizeParam.create(method="maximum") + ) + norm_entry = history[len(history)] + assert norm_entry.func_name == "normalize" + previous_edit_mode = history.edit_mode + _select_tree_item_for(history, norm_entry) + # Step-by-step launch: parameter dialogs auto-accept in unattended mode. + history.replay_step_by_step() + assert history.edit_mode is previous_edit_mode + assert history.has_any_pending_edits() is False + + # --------------------------------------------------------------------------- # 9) Cascade recompute # --------------------------------------------------------------------------- @@ -1742,6 +1763,65 @@ def test_history_chain_model_grouping(): assert callable(build_session_chains) +def test_history_delete_splits_chain(): + """Deleting an intermediate action splits its chain via a data copy.""" + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + + # Creation via the main window records a ``new_object`` creation action; + # ``panel.add_object`` deliberately does not, so ``win.add_object`` is + # required to obtain a creation-rooted chain. + win.add_object(create_paracetamol_signal()) + panel.objview.select_objects([1]) + panel.processor.run_feature( + sips.normalize, sigima.params.NormalizeParam.create(method="maximum") + ) + panel.objview.select_objects([2]) + panel.processor.run_feature(sips.derivative) + + session = history.history_sessions[-1] + assert [a.func_name for a in session.actions] == [ + None, + "normalize", + "derivative", + ] + normalize_action = session.actions[1] + derivative_action = session.actions[2] + n_objects_before = len(panel.objmodel) + + # Delete the MIDDLE action (normalize). Unattended mode auto-confirms and + # skips the associated-object removal prompt. + _select_tree_item_for(history, normalize_action) + history.delete_selected() + + # ``normalize`` is spliced out; creation and ``derivative`` remain. + assert normalize_action not in session.actions + assert session.actions[0].method_name in HistoryAction.UI_CREATION_METHODS + assert derivative_action in session.actions + + # A copy of ``normalize``'s output was added as a new parentless root. + assert len(panel.objmodel) == n_objects_before + 1 + + # The session now splits into two chains and drops no action. + chains = build_session_chains(history, session) + assert len(chains) == 2 + assert sum(len(c.actions) for c in chains) == len(session.actions) + + # ``derivative`` roots a NEW chain (fed by the copy), not the creation one. + creation_chain = next( + c + for c in chains + if c.root.kind == HistoryAction.KIND_UI + and c.root.method_name in HistoryAction.UI_CREATION_METHODS + ) + assert derivative_action not in creation_chain.actions + deriv_chain = next(c for c in chains if derivative_action in c.actions) + assert deriv_chain is not creation_chain + assert deriv_chain.root is derivative_action + + def test_history_new_session_prompt_on_input(monkeypatch): """Creating an object on a non-empty session offers to start a new session.""" # --- scenario: user accepts the prompt -> a new session is opened --- From 7b5c816d93504221cd4f101d2723489b74406c96 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Wed, 1 Jul 2026 16:18:13 +0200 Subject: [PATCH 048/108] Feat(history): Editable analysis parameters tab for in-place re-run (L5) The object-properties "Analysis parameters" section was read-only, so a user who wanted to re-run a 1-to-0 analysis (2D peak detection, FWHM, segments) with different settings had to restart the whole operation from scratch. This lot adds an editable "Analysis" tab that mirrors the existing editable Processing tab, letting the user adjust the stored parameters and re-run the analysis in place without polluting the history chain. * [NEW] : Add editable "Analysis" scroll tab to ObjectProp via setup_analysis_tab() and apply_analysis_parameters(); parameters are read from the object's ANALYSIS_PARAMETERS_OPTION metadata through extract_analysis_parameters (guards against None, non-1-to-0 and list params) * [NEW] : Re-run through processor.recompute_1_to_0() under the history replaying() guard so no synthetic history entry is created and the chain is left untouched * [NEW] : Add find_analysis_action() in history/chain.py (delegated from history/panel.py) to locate the matching 1-to-0 compute action by input UUID and function name, scanning most-recent-first for consistency with find_action_for_output * [CHG] : Extend update_properties_from with dynamic teardown/rebuild of the analysis tab; force_tab == "analysis" now prefers the editable tab and falls back to the unchanged read-only HTML view * [CHG] : On re-run, keep the located action consistent by refreshing snapshot_kwargs() and kwargs["param"] and updating the tree (no cascade, analysis is a leaf) * [CHG] : Force create_rois to False before recompute to avoid re-creating non-deletable ROIs when editing parameters Validation: new test_analysis_parameters_edit_image (peak-image threshold edit, recompute effect + ROI guard) plus analysis-recompute, result-deletion and full history suites all pass; ruff clean on all changed files; fr translations 100% translated and compiling. --- datalab/gui/panel/base.py | 187 ++++++++++++++++++ datalab/gui/panel/history/chain.py | 29 +++ datalab/gui/panel/history/panel.py | 6 + datalab/locale/fr/LC_MESSAGES/datalab.po | 17 ++ .../analysis_parameters_edit_unit_test.py | 83 ++++++++ 5 files changed, 322 insertions(+) create mode 100644 datalab/tests/features/common/analysis_parameters_edit_unit_test.py diff --git a/datalab/gui/panel/base.py b/datalab/gui/panel/base.py index f1431c4be..08e20bef7 100644 --- a/datalab/gui/panel/base.py +++ b/datalab/gui/panel/base.py @@ -82,6 +82,7 @@ PROCESSING_PARAMETERS_OPTION, ProcessingParameters, clear_analysis_parameters, + extract_analysis_parameters, extract_processing_parameters, insert_processing_parameters, ) @@ -209,6 +210,10 @@ def __init__(self, panel: BaseDataPanel, objclass: SignalObj | ImageObj) -> None self.processing_param_editor: gdq.DataSetEditGroupBox | None = None self.current_processing_obj: SignalObj | ImageObj | None = None self.processing_scroll: QW.QScrollArea | None = None + # Object analysis tab (editable 1-to-0 analysis parameters) + self.analysis_param_editor: gdq.DataSetEditGroupBox | None = None + self.current_analysis_obj: SignalObj | ImageObj | None = None + self.analysis_scroll: QW.QScrollArea | None = None # Auto-recompute toggle (session-only state, not persisted to Conf). self.__auto_recompute_enabled: bool = False self.__auto_recompute_timer = QC.QTimer(self) @@ -429,6 +434,10 @@ def update_properties_from( index = self.tabwidget.indexOf(self.processing_scroll) if index >= 0: self.tabwidget.removeTab(index) + if self.analysis_scroll is not None: + index = self.tabwidget.indexOf(self.analysis_scroll) + if index >= 0: + self.tabwidget.removeTab(index) # Reset references for dynamic tabs self.creation_param_editor = None @@ -437,13 +446,18 @@ def update_properties_from( self.processing_param_editor = None self.current_processing_obj = None self.processing_scroll = None + self.analysis_param_editor = None + self.current_analysis_obj = None + self.analysis_scroll = None # Setup Creation and Processing tabs (if applicable) has_creation_tab = False has_processing_tab = False + has_analysis_tab = False if obj is not None: has_creation_tab = self.setup_creation_tab(obj) has_processing_tab = self.setup_processing_tab(obj) # Processing tab setup + has_analysis_tab = self.setup_analysis_tab(obj) # Analysis tab setup # Trigger visibility update for History and Analysis parameters tabs # (will be called via textChanged signals, but we call explicitly @@ -459,6 +473,8 @@ def update_properties_from( self.tabwidget.setCurrentWidget(self.creation_scroll) elif force_tab == "processing" and has_processing_tab: self.tabwidget.setCurrentWidget(self.processing_scroll) + elif force_tab == "analysis" and has_analysis_tab: + self.tabwidget.setCurrentWidget(self.analysis_scroll) elif force_tab == "analysis" and has_analysis_parameters: self.tabwidget.setCurrentWidget(self.analysis_parameters) else: @@ -813,6 +829,177 @@ def _wrapped_change_cb() -> None: return True + def setup_analysis_tab( + self, obj: SignalObj | ImageObj, set_current: bool = False + ) -> bool: + """Setup the Analysis tab with parameter editor for re-running analysis. + + This tab lets the user edit the parameters of a 1-to-0 analysis + operation (peak detection, FWHM, segments, etc.) and re-run it in place + with the modified parameters. + + Args: + obj: Signal or Image object + set_current: If True, set the Analysis tab as current after creation + + Returns: + True if Analysis tab was set up, False otherwise + """ + # Extract analysis parameters (1-to-0 pattern only) + proc_params = extract_analysis_parameters(obj) + if proc_params is None or proc_params.pattern != "1-to-0": + return False + + param = proc_params.param + if param is None or isinstance(param, list): + return False + + # Store reference to be able to retrieve it later + self.current_analysis_obj = obj + + # Create parameter editor widget + editor = gdq.DataSetEditGroupBox( + _("Analysis Parameters"), param.__class__, wordwrap=True + ) + update_dataset(editor.dataset, param) + editor.get() + + # Connect Apply button to re-analysis handler + editor.SIG_APPLY_BUTTON_CLICKED.connect(self.apply_analysis_parameters) + editor.set_apply_button_state(False) + + # Store reference to be able to retrieve it later + self.analysis_param_editor = editor + + # Remove existing Analysis tab if it exists + if self.analysis_scroll is not None: + index = self.tabwidget.indexOf(self.analysis_scroll) + if index >= 0: + self.tabwidget.removeTab(index) + + # Analysis tab comes after Creation and Processing tabs (if they exist) + insert_index = 0 + if ( + self.creation_scroll is not None + and self.tabwidget.indexOf(self.creation_scroll) >= 0 + ): + insert_index += 1 + if ( + self.processing_scroll is not None + and self.tabwidget.indexOf(self.processing_scroll) >= 0 + ): + insert_index += 1 + + # Create new analysis scroll area and tab + self.analysis_scroll = QW.QScrollArea() + self.analysis_scroll.setWidgetResizable(True) + self.analysis_scroll.setHorizontalScrollBarPolicy(QC.Qt.ScrollBarAlwaysOff) + self.analysis_scroll.setSizePolicy( + QW.QSizePolicy.Expanding, QW.QSizePolicy.Preferred + ) + self.analysis_scroll.setWidget(editor) + self.tabwidget.insertTab( + insert_index, + self.analysis_scroll, + get_icon("analysis.svg"), + _("Analysis"), + ) + + # Set as current tab if requested + if set_current: + self.tabwidget.setCurrentWidget(self.analysis_scroll) + + return True + + def apply_analysis_parameters( + self, + obj: SignalObj | ImageObj | None = None, + interactive: bool = True, + param: gds.DataSet | None = None, + ) -> None: + """Apply analysis parameters: re-run the 1-to-0 analysis in place. + + Args: + obj: Signal or Image object to re-analyze. If None, uses the current + analysis object. + interactive: If True, show error messages in the UI. + param: Explicit analysis parameters to apply. When None (default), + fall back to the editor dataset or the stored analysis parameters. + """ + if execenv.unattended: + interactive = False + + editor = self.analysis_param_editor + obj = obj or self.current_analysis_obj + if obj is None: + return + + # Extract analysis parameters + proc_params = extract_analysis_parameters(obj) + if proc_params is None: + if interactive: + QW.QMessageBox.warning( + self, _("Error"), _("Analysis metadata is incomplete.") + ) + return + + func_name = proc_params.func_name + + # Resolve the parameters to apply. An explicit ``param`` argument takes + # precedence; otherwise fall back to the editor (interactive Apply) or + # the stored analysis parameters. + if param is None: + param = editor.dataset if editor is not None else proc_params.param + + # Disable ROI creation during re-analysis: detection functions store + # create_rois=True in their parameters, but re-running should only + # update analysis results, not recreate ROIs (which would make them + # impossible to delete or modify). + if hasattr(param, "create_rois"): + param.create_rois = False + + # Re-run the analysis in place (no history entry: runs under replaying) + processor = self.__get_processor_associated_to(obj) + try: + processor.recompute_1_to_0(func_name, obj, param) + except Exception as exc: # pylint: disable=broad-exception-caught + if execenv.unattended: + raise exc + QW.QMessageBox.warning( + self, + _("Error"), + _("Failed to recompute analysis:\n%s") % str(exc), + ) + return + + # Propagate the edited param to the History panel: mutate the matching + # analysis action (snapshot originals first) and refresh its tree + # display. Analysis is a leaf operation (1-to-0), so no cascade is + # needed. + hpanel = getattr(self.panel.mainwindow, "historypanel", None) + if hpanel is not None: + action = hpanel.find_analysis_action(get_uuid(obj), func_name) + if action is not None: + action.snapshot_kwargs() + action.kwargs["param"] = copy.deepcopy(param) + hpanel.refresh_action(action) + + # Refresh the object display after re-analysis + obj_uuid = get_uuid(obj) + self.display_analysis_parameters(obj) + self.panel.objview.update_item(obj_uuid) + # Analysis results are plot shapes, so force a plot refresh + self.panel.refresh_plot(obj_uuid, update_items=True, force=True) + self.panel.SIG_STATUS_MESSAGE.emit("✅ " + _("Analysis was recomputed."), 5000) + + # Refresh the Analysis tab with the new parameters (defer, keep visible) + QC.QTimer.singleShot( + 0, + lambda: self.setup_analysis_tab( + self.current_analysis_obj, set_current=True + ), + ) + def __get_processor_associated_to( self, obj: SignalObj | ImageObj ) -> SignalProcessor | ImageProcessor: diff --git a/datalab/gui/panel/history/chain.py b/datalab/gui/panel/history/chain.py index 954db42b5..e268e055a 100644 --- a/datalab/gui/panel/history/chain.py +++ b/datalab/gui/panel/history/chain.py @@ -12,6 +12,7 @@ from datalab.config import _ from datalab.env import execenv from datalab.gui.panel.history import recompute as hrec +from datalab.gui.panel.history.chainmodel import action_input_uuids from datalab.gui.processor.base import ( ProcessingParameters, extract_processing_parameters, @@ -169,6 +170,34 @@ def find_creation_action_for_output( return None +def find_analysis_action( + panel: HistoryPanel, obj_uuid: str, func_name: str +) -> HistoryAction | None: + """Find the 1-to-0 analysis action for ``obj_uuid`` with ``func_name``. + + Analysis operations (1-to-0) do not produce a new output object: they + write their result to the input object's metadata. The matching action is + therefore identified by its input UUID and function name. + + Args: + panel: The history panel providing the sessions. + obj_uuid: UUID of the analyzed object. + func_name: Sigima analysis feature name. + + Returns: + The matching :class:`HistoryAction`, or ``None`` if not found. + """ + for session in reversed(panel.history_sessions): + for action in reversed(session.actions): + if action.kind != HistoryAction.KIND_COMPUTE: + continue + if action.func_name != func_name: + continue + if obj_uuid in action_input_uuids(action): + return action + return None + + def get_session_of(panel: HistoryPanel, action: HistoryAction) -> HistorySession | None: """Return the session that contains ``action``, or None.""" for session in panel.history_sessions: diff --git a/datalab/gui/panel/history/panel.py b/datalab/gui/panel/history/panel.py index 651a5c83d..ac15516b3 100644 --- a/datalab/gui/panel/history/panel.py +++ b/datalab/gui/panel/history/panel.py @@ -483,6 +483,12 @@ def find_creation_action_for_output(self, output_uuid: str) -> HistoryAction | N """Find the creation action that produced ``output_uuid``.""" return hchain.find_creation_action_for_output(self, output_uuid) + def find_analysis_action( + self, obj_uuid: str, func_name: str + ) -> HistoryAction | None: + """Find the 1-to-0 analysis action for ``obj_uuid`` with ``func_name``.""" + return hchain.find_analysis_action(self, obj_uuid, func_name) + def get_session_of(self, action: HistoryAction) -> HistorySession | None: """Return the session that contains ``action``, or None.""" return hchain.get_session_of(self, action) diff --git a/datalab/locale/fr/LC_MESSAGES/datalab.po b/datalab/locale/fr/LC_MESSAGES/datalab.po index 08e0eb386..6bfe76151 100644 --- a/datalab/locale/fr/LC_MESSAGES/datalab.po +++ b/datalab/locale/fr/LC_MESSAGES/datalab.po @@ -1457,6 +1457,23 @@ msgstr "Recalcul automatique lors de l'édition" msgid "Automatically re-run processing when parameters are modified" msgstr "Relancer automatiquement le traitement à chaque modification de paramètre" +msgid "Analysis Parameters" +msgstr "Paramètres d'analyse" + +msgid "Analysis metadata is incomplete." +msgstr "Les métadonnées d'analyse sont incomplètes." + +#, python-format +msgid "" +"Failed to recompute analysis:\n" +"%s" +msgstr "" +"Échec du recalcul de l'analyse :\n" +"%s" + +msgid "Analysis was recomputed." +msgstr "L'analyse a été recalculée." + msgid "No processing object available." msgstr "Aucun objet de traitement disponible." diff --git a/datalab/tests/features/common/analysis_parameters_edit_unit_test.py b/datalab/tests/features/common/analysis_parameters_edit_unit_test.py new file mode 100644 index 000000000..caad812f5 --- /dev/null +++ b/datalab/tests/features/common/analysis_parameters_edit_unit_test.py @@ -0,0 +1,83 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +""" +Analysis parameters edit unit test +---------------------------------- + +Test the editable "Analysis" tab of the Object Properties widget. + +This verifies that a 1-to-0 analysis operation (e.g. 2D peak detection) can be +re-run in place with modified parameters through +:meth:`ObjectProp.setup_analysis_tab` / :meth:`ObjectProp.apply_analysis_parameters`. +""" + +# pylint: disable=invalid-name # Allows short reference names like x, y, ... +# guitest: show + +from __future__ import annotations + +import sigima.params as sigima_param +from sigima.tests.data import create_peak_image + +from datalab.config import Conf +from datalab.env import execenv +from datalab.gui.processor.base import extract_analysis_parameters +from datalab.tests import datalab_test_app_context + + +def test_analysis_parameters_edit_image(): + """Test editing and re-running a 1-to-0 analysis via the Analysis tab.""" + with datalab_test_app_context(console=False) as win: + execenv.print("Analysis parameters edit test (image peak detection):") + panel = win.imagepanel + + # Create a multi-peak image guaranteed to yield detections + img = create_peak_image() + panel.add_object(img) + + # Run 2D peak detection: a 1-to-0 analysis with an editable parameter + det_param = sigima_param.Peak2DDetectionParam.create( + create_rois=False, threshold=0.5 + ) + with Conf.proc.show_result_dialog.temp(False): + panel.processor.run_feature("peak_detection", det_param) + + # The analysis parameters must be stored as a single 1-to-0 dataset + proc_params = extract_analysis_parameters(img) + assert proc_params is not None, "Analysis parameters should be stored" + assert proc_params.pattern == "1-to-0" + assert proc_params.param is not None + assert not isinstance(proc_params.param, list) + assert proc_params.param.threshold == 0.5 + execenv.print(" ✓ Analysis parameters stored (threshold=0.5)") + + # Set up the editable Analysis tab + objprop = panel.objprop + assert objprop.setup_analysis_tab(img) is True + assert objprop.analysis_param_editor is not None + execenv.print(" ✓ Analysis tab set up") + + # Modify the threshold and (deliberately) enable ROI creation to verify + # the create_rois guard forces it back to False on apply + objprop.analysis_param_editor.dataset.threshold = 0.8 + objprop.analysis_param_editor.dataset.create_rois = True + + # Apply: re-run the analysis in place with the modified parameters + objprop.apply_analysis_parameters(img) + + # The stored analysis parameters must reflect the new threshold + proc_params2 = extract_analysis_parameters(img) + assert proc_params2 is not None + assert proc_params2.param.threshold == 0.8, "Threshold change must be applied" + execenv.print(" ✓ Analysis re-ran with new threshold (0.8)") + + # ROI guard: create_rois must have been forced to False (no ROI created) + assert proc_params2.param.create_rois is False, ( + "create_rois must be forced to False on re-analysis" + ) + assert not img.roi, "No ROI should be created on re-analysis" + execenv.print(" ✓ ROI creation guard held (create_rois=False)") + + +if __name__ == "__main__": + test_analysis_parameters_edit_image() From 230820a2a460c08a68e53127dd5d0a640cd3f467 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Wed, 8 Jul 2026 11:17:28 +0200 Subject: [PATCH 049/108] Fix(history): Tolerate stale tree items in compatibility refresh update_compatibility_states iterated every action item and resolved its uuid via get_action_from_uuid, which raises when the action is no longer in the model. During reconnect_chain_after_removal the recompute cascade emits SIG_OBJECT_MODIFIED (firing refresh_compatibility_items) before the final repopulate, so the tree transiently references a just-removed action and the Qt slot crashed with 'Action not found'. Build a uuid->action map once and skip unresolved items instead of raising; harden get_selected_actions[_or_ sessions] the same way. Add a regression test. --- datalab/tests/features/common/history_test.py | 27 +++++++++++++++++++ datalab/widgets/historytree.py | 24 ++++++++++++++--- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/datalab/tests/features/common/history_test.py b/datalab/tests/features/common/history_test.py index 0d53511b7..9f37516da 100644 --- a/datalab/tests/features/common/history_test.py +++ b/datalab/tests/features/common/history_test.py @@ -2176,3 +2176,30 @@ def test_history_capture_outputs_drops_failed_compute(): pass assert analysis_action in list(history) assert len(history) == analysis_len_before + + +def test_history_compatibility_refresh_tolerates_stale_tree(): + """update_compatibility_states must not crash when the tree transiently + references an action already removed from the model (regression).""" + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + spanel = win.signalpanel + spanel.add_object(create_paracetamol_signal()) + spanel.objview.select_objects([1]) + spanel.processor.run_feature(sips.derivative) + spanel.objview.select_objects([2]) + spanel.processor.run_feature(sips.derivative) + # Tree is populated and in sync here. + session = history.history_sessions[-1] + assert session.actions + # Simulate a transient desync: drop the last action from the model + # WITHOUT repopulating the tree (as happens mid-cascade). + removed = session.actions.pop() + # The tree still has an item for ``removed``; a compatibility refresh + # must skip it gracefully instead of raising ValueError. + history.tree.update_compatibility_states( + history.history_sessions, history.mainwindow + ) + # Restore invariant for a clean teardown. + session.actions.append(removed) diff --git a/datalab/widgets/historytree.py b/datalab/widgets/historytree.py index 3a8bffd32..fdfad20ca 100644 --- a/datalab/widgets/historytree.py +++ b/datalab/widgets/historytree.py @@ -108,12 +108,24 @@ def update_compatibility_states( incompatible_tip = _( "Action is not compatible with the current workspace state." ) + actions_by_uuid = { + action.uuid: action + for session in history_sessions + for action in session.actions + } iterator = QW.QTreeWidgetItemIterator(self) while iterator.value(): item = iterator.value() if item.data(0, self.ITEM_KIND_ROLE) == self.ITEM_ACTION: uuid = item.data(0, QC.Qt.UserRole) - action = self.get_action_from_uuid(uuid, history_sessions) + action = actions_by_uuid.get(uuid) + # The tree can transiently reference an action that was just + # removed from the model (e.g. mid-cascade during + # reconnect_chain_after_removal, before the final repopulate). + # Skip such stale items instead of crashing. + if action is None: + iterator += 1 + continue compatible = action.is_current_state_compatible( mainwindow, restore_selection=True ) @@ -305,7 +317,10 @@ def get_selected_actions_or_sessions( selected.append(history_sessions[index]) elif item.data(0, self.ITEM_KIND_ROLE) == self.ITEM_ACTION: uuid = item.data(0, QC.Qt.UserRole) - selected.append(self.get_action_from_uuid(uuid, history_sessions)) + try: + selected.append(self.get_action_from_uuid(uuid, history_sessions)) + except ValueError: + continue # chain-header items are containers only: ignored here. return selected @@ -326,5 +341,8 @@ def get_selected_actions( item.data(0, self.ITEM_KIND_ROLE) == self.ITEM_ACTION ): uuid = item.data(0, QC.Qt.UserRole) - selected.append(self.get_action_from_uuid(uuid, history_sessions)) + try: + selected.append(self.get_action_from_uuid(uuid, history_sessions)) + except ValueError: + continue return selected From c4971ed4a54071468d6731c77d3b36bd6bd3f8f3 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Wed, 8 Jul 2026 12:02:23 +0200 Subject: [PATCH 050/108] Feat: Rework history duplication as chain-oriented cloning History duplication used to clone whole sessions and remap them at the session level, which left duplicated entries still pointing at the original objects' UUIDs. The feature is reworked around processing chains: selecting a session duplicates all its chains, selecting an action duplicates the single chain that contains it. Every cloned object receives a fresh UUID and all action references are remapped to the clones, so the result is an independent, editable and replayable session. Operation-rooted chains consume an object created outside the chain, so they cannot be replayed on their own. A synthetic "Initial state" creation head is prepended per distinct source object to materialize a clone snapshot, making such chains self-contained. * [CHG] : Resolve selection to processing chains via build_session_chains instead of normalising actions to their parent session * [FIX] : Assign a fresh UUID to every cloned object and remap all action references, fixing duplicated entries still referencing original UUIDs * [NEW] : Handle Cas A (creation-rooted chain) by duplicating the root new_object action as-is so it stays replayable * [NEW] : Handle Cas B (operation-rooted chain) by prepending a synthetic KIND_UI new_object head (empty kwargs/state, output_uuids=[clone]) recognised as a chain root by build_session_chains * [TEST] : Update test_history_duplication (scenarios 1-3) and add test_history_duplication_cas_a_creation_root and test_history_duplication_cas_b_synthetic_head (26 passed) * [NEW] : Add French translation "Initial state" -> "Etat initial" --- datalab/gui/historytools_ops.py | 203 ++++++++++++++---- datalab/locale/fr/LC_MESSAGES/datalab.po | 4 +- datalab/tests/features/common/history_test.py | 98 ++++++++- 3 files changed, 263 insertions(+), 42 deletions(-) diff --git a/datalab/gui/historytools_ops.py b/datalab/gui/historytools_ops.py index 52eb46e24..037dcece5 100644 --- a/datalab/gui/historytools_ops.py +++ b/datalab/gui/historytools_ops.py @@ -13,6 +13,10 @@ from datalab.config import _ from datalab.env import execenv from datalab.gui.panel.history import chain as hchain +from datalab.gui.panel.history.chainmodel import ( + ProcessingChain, + build_session_chains, +) from datalab.gui.processor.base import ( PROCESSING_PARAMETERS_OPTION, ProcessingParameters, @@ -20,6 +24,7 @@ insert_processing_parameters, ) from datalab.history import HistoryAction, HistorySession +from datalab.history.workspace_state import WorkspaceState from datalab.objectmodel import get_uuid if TYPE_CHECKING: @@ -27,30 +32,104 @@ from datalab.gui.panel.history import HistoryPanel +def _make_initial_state_head(pstr: str, clone_uuid: str, title: str) -> HistoryAction: + """Return a synthetic creation-root action for an operation-rooted chain. + + A *Cas B* chain starts from an operation whose input object was created + outside the chain (e.g. imported or added programmatically). To make the + duplicated chain self-contained and replayable, a synthetic ``new_object`` + UI action is prepended, standing in for that missing object creation. Its + empty workspace state mirrors a real ``new_object`` recorded with + ``save_state=False`` (hence always compatible), and its ``new_object`` + method name places it in :attr:`HistoryAction.UI_CREATION_METHODS` so + :func:`build_session_chains` treats it as a genuine chain root. + + Args: + pstr: Panel string of the created object (``"signal"``/``"image"``). + clone_uuid: UUID of the cloned source object produced as head output. + title: Title shown for the synthetic action in the tree. + + Returns: + A new :class:`HistoryAction` describing the synthetic creation root. + """ + target = "signalpanel" if pstr == "signal" else "imagepanel" + head = HistoryAction( + title=title, + kind=HistoryAction.KIND_UI, + target=target, + method_name="new_object", + kwargs={}, + state=WorkspaceState(), + panel_str=None, + ) + head.output_uuids = [clone_uuid] + return head + + def duplicate_selected_entries(panel: HistoryPanel) -> None: - """Duplicate selected sessions (with their data) into new independent sessions. + """Duplicate selected processing chains into new independent sessions. + + Selection is resolved to *processing chains* (see + :func:`build_session_chains`): selecting a session duplicates all its + chains, while selecting an action duplicates the single chain that + contains it. For each source session, exactly one new session is produced + containing the duplicates of its selected chains, with all referenced data + objects deep-copied into a new group and every UUID reference rewritten to + the clones. + + Two chain shapes are handled: + + * **Cas A** -- creation-rooted chain (root is a ``new_object`` UI action): + the chain is copied as-is (root included), no synthetic head is added. + * **Cas B** -- operation-rooted chain (root consumes an external object): + one synthetic ``new_object`` head is prepended per distinct remapped + source object so the duplicated chain remains self-contained and + replayable. - For each selected session (or the parent session of a selected action), - all referenced data objects are deep-copied into a new group and the - session is duplicated with all UUID references rewritten to the clones. The result is an independent, editable and replayable session. """ selected = panel.tree.get_selected_actions_or_sessions(panel.history_sessions) if not selected: return - # Normalise: resolve individual actions to their parent session, deduplicate. - sessions_to_dup: list[HistorySession] = [] - seen: set[int] = set() + + # 1. Resolve selection to a per-session set of chains. + session_by_id: dict[int, HistorySession] = {} + full_session_ids: set[int] = set() + actions_by_session: dict[int, list[HistoryAction]] = {} for item in selected: if isinstance(item, HistorySession): - session = item + session_by_id[id(item)] = item + full_session_ids.add(id(item)) else: session = panel.find_parent_session(item) if session is None: continue - if id(session) not in seen: - seen.add(id(session)) - sessions_to_dup.append(session) + session_by_id[id(session)] = session + actions_by_session.setdefault(id(session), []).append(item) + + # Preserve source-session order (iterate panel.history_sessions). + ordered: list[tuple[HistorySession, list[ProcessingChain]]] = [] + for session in panel.history_sessions: + sid = id(session) + if sid not in session_by_id: + continue + all_chains = build_session_chains(panel, session) + if sid in full_session_ids: + chains = all_chains + else: + chains = [] + seen_chains: set[int] = set() + for action in actions_by_session.get(sid, []): + for chain in all_chains: + if any(a is action or a.uuid == action.uuid for a in chain.actions): + if id(chain) not in seen_chains: + seen_chains.add(id(chain)) + chains.append(chain) + break + if chains: + ordered.append((session, chains)) + if not ordered: + return copy_suffix = _("Copy") new_sessions: list[HistorySession] = [] @@ -59,28 +138,29 @@ def duplicate_selected_entries(panel: HistoryPanel) -> None: "image": panel.mainwindow.imagepanel, } - for session in sessions_to_dup: - # 1. Collect all UUIDs referenced by this session + for session, chains in ordered: + # 2. Collect all UUIDs referenced by the SELECTED chains only. uuids_by_panel: dict[str, set[str]] = {} - for action in session.actions: - for pstr, uuids in action.state.selection.items(): - uuids_by_panel.setdefault(pstr, set()).update(uuids) - for pstr, metadata in action.state.object_metadata.items(): - uuids_by_panel.setdefault(pstr, set()).update(metadata.keys()) - obj2 = action.kwargs.get("obj2_uuids") - if obj2: - pstr = action.panel_str or "" - if isinstance(obj2, str): - obj2 = [obj2] - uuids_by_panel.setdefault(pstr, set()).update(obj2) - # Output UUIDs produced by this action (e.g. result of a - # compute step). Without this, the last action's outputs - # would be missing because no subsequent state captures them. - if action.output_uuids: - pstr = action.panel_str or "" - uuids_by_panel.setdefault(pstr, set()).update(action.output_uuids) - - # 2. Clone objects and build uuid_remap + for chain in chains: + for action in chain.actions: + for pstr, uuids in action.state.selection.items(): + uuids_by_panel.setdefault(pstr, set()).update(uuids) + for pstr, metadata in action.state.object_metadata.items(): + uuids_by_panel.setdefault(pstr, set()).update(metadata.keys()) + obj2 = action.kwargs.get("obj2_uuids") + if obj2: + pstr = action.panel_str or "signal" + if isinstance(obj2, str): + obj2 = [obj2] + uuids_by_panel.setdefault(pstr, set()).update(obj2) + # Output UUIDs produced by this action (e.g. result of a + # compute step). Without this, the last action's outputs + # would be missing because no subsequent state captures them. + if action.output_uuids: + pstr = action.panel_str or "signal" + uuids_by_panel.setdefault(pstr, set()).update(action.output_uuids) + + # 3. Clone objects and build uuid_remap. uuid_remap: dict[str, dict[str, str]] = {} clones_by_pstr: dict[str, list] = {} group_title = f"{copy_suffix} - {session.title}" @@ -150,11 +230,61 @@ def duplicate_selected_entries(panel: HistoryPanel) -> None: except (AttributeError, ValueError): pass - # 3. Build the new session with remapped UUIDs + # 4. Build the new session's actions per chain (Cas A / Cas B). + new_actions: list[HistoryAction] = [] + for chain in chains: + is_creation_root = ( + chain.root.kind == HistoryAction.KIND_UI + and chain.root.method_name in HistoryAction.UI_CREATION_METHODS + ) + if is_creation_root: + # Cas A: creation-rooted chain, copy as-is (root included). + new_actions.extend( + action.copy_with_uuid_remap(uuid_remap) for action in chain.actions + ) + continue + # Cas B: operation-rooted chain, synthesize one creation head per + # distinct remapped source object of the chain root. + root_inputs: list[tuple[str, str]] = [] + for pstr, uuids in chain.root.state.selection.items(): + for old_uuid in uuids: + root_inputs.append((pstr, old_uuid)) + obj2 = chain.root.kwargs.get("obj2_uuids") + if obj2: + pstr = chain.root.panel_str or "signal" + if isinstance(obj2, str): + obj2 = [obj2] + for old_uuid in obj2: + root_inputs.append((pstr, old_uuid)) + heads: list[HistoryAction] = [] + seen_clones: set[str] = set() + for pstr, old_uuid in root_inputs: + clone_uuid = uuid_remap.get(pstr, {}).get(old_uuid) + if clone_uuid is None or clone_uuid in seen_clones: + # Source object deleted / not clonable, or already headed. + continue + seen_clones.add(clone_uuid) + head_title = _("Initial state") + data_panel = panel_map.get(pstr) + if data_panel is not None: + try: + head_title = data_panel.objmodel[clone_uuid].title + except (KeyError, AttributeError): + head_title = _("Initial state") + head = _make_initial_state_head(pstr, clone_uuid, head_title) + heads.append(head) + panel.action_output_uuids[head.uuid] = [clone_uuid] + panel.output_to_action[clone_uuid] = head.uuid + new_actions.extend(heads) + new_actions.extend( + action.copy_with_uuid_remap(uuid_remap) for action in chain.actions + ) + + # 5. Assemble the new session and register output mappings. panel.session_increment += 1 title = f"{session.title} {copy_suffix}" - new_session = session.copy_with_uuid_remap(title=title, uuid_remap=uuid_remap) - new_session.number = panel.session_increment + new_session = HistorySession(title=title, number=panel.session_increment) + new_session.actions = new_actions new_sessions.append(new_session) # Register output mappings for cloned actions so that @@ -168,7 +298,8 @@ def duplicate_selected_entries(panel: HistoryPanel) -> None: # Insert each duplicated session immediately after its original. offset = 0 - for original_session, new_session in zip(sessions_to_dup, new_sessions): + source_sessions = [session for session, _chains in ordered] + for original_session, new_session in zip(source_sessions, new_sessions): idx = panel.history_sessions.index(original_session) panel.history_sessions.insert(idx + 1 + offset, new_session) offset += 1 diff --git a/datalab/locale/fr/LC_MESSAGES/datalab.po b/datalab/locale/fr/LC_MESSAGES/datalab.po index 6bfe76151..32c91dee3 100644 --- a/datalab/locale/fr/LC_MESSAGES/datalab.po +++ b/datalab/locale/fr/LC_MESSAGES/datalab.po @@ -971,6 +971,9 @@ msgstr "Un nouvel objet a été créé. Démarrer une nouvelle session d'histori msgid "New history session" msgstr "Nouvelle session d'historique" +msgid "Initial state" +msgstr "État initial" + msgid "Generate macro" msgstr "Générer une macro" @@ -4341,4 +4344,3 @@ msgstr "Aucun contour n'a été trouvé pour la plage de niveaux sélectionnée. msgid "Show contour plot..." msgstr "Afficher le tracé de contours..." - diff --git a/datalab/tests/features/common/history_test.py b/datalab/tests/features/common/history_test.py index 9f37516da..84b6aa3ab 100644 --- a/datalab/tests/features/common/history_test.py +++ b/datalab/tests/features/common/history_test.py @@ -1155,7 +1155,12 @@ def test_history_duplication(): history.duplicate_selected_entries() sessions = history.history_sessions duplicate_session = sessions[-1] - duplicate = duplicate_session.actions[0] + # Operation-rooted chain (Cas B): a synthetic creation head is + # prepended, so the compute duplicate is no longer at index 0. + assert duplicate_session.actions[0].method_name == "new_object" + duplicate = next( + a for a in duplicate_session.actions if a.kind == HistoryAction.KIND_COMPUTE + ) assert duplicate_session.title.endswith(_("Copy")) assert duplicate is not original assert duplicate.uuid != original.uuid @@ -1181,7 +1186,8 @@ def test_history_duplication(): sessions = history.history_sessions duplicate_session = sessions[-1] assert duplicate_session is not original_session - assert len(duplicate_session.actions) == len(original_session.actions) + # One synthetic creation head is prepended (Cas B). + assert len(duplicate_session.actions) == len(original_session.actions) + 1 assert duplicate_session.title.endswith(_("Copy")) orig_a = original_session.actions[-1] dup_a = duplicate_session.actions[-1] @@ -1207,9 +1213,12 @@ def test_history_duplication(): assert dup_session is not original_session assert dup_session.title.endswith(_("Copy")) assert len(panel.objmodel) > n_obj_before - for orig_action, dup_action in zip( - original_session.actions, dup_session.actions - ): + # The duplicate has an extra leading synthetic head (Cas B); compare + # only the compute actions against the originals. + dup_compute = [ + a for a in dup_session.actions if a.kind == HistoryAction.KIND_COMPUTE + ] + for orig_action, dup_action in zip(original_session.actions, dup_compute): for pstr in orig_action.state.selection: orig_uuids = set(orig_action.state.selection.get(pstr, [])) dup_uuids = set(dup_action.state.selection.get(pstr, [])) @@ -1259,6 +1268,85 @@ def _suffix(title: str) -> str: assert clonable == dup_suffixes +def test_history_duplication_cas_a_creation_root(): + """Duplicating a creation-rooted chain copies the creation (no synthetic head).""" + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + win.add_object(create_paracetamol_signal()) # records new_object creation + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.derivative) + original_session = history.history_sessions[-1] + assert original_session.actions[0].method_name == "new_object" + _select_tree_session(history, original_session) + n_obj_before = len(panel.objmodel) + history.duplicate_selected_entries() + dup_session = history.history_sessions[-1] + assert dup_session is not original_session + # Cas A: same number of actions (creation duplicated, NO synthetic head). + assert len(dup_session.actions) == len(original_session.actions) + dup_root = dup_session.actions[0] + orig_root = original_session.actions[0] + assert dup_root.method_name == "new_object" + assert dup_root is not orig_root + assert dup_root.uuid != orig_root.uuid + # Objects were cloned. + assert len(panel.objmodel) > n_obj_before + # UUID remap: duplicated actions share no object uuid with originals. + for orig_a, dup_a in zip(original_session.actions, dup_session.actions): + for pstr in orig_a.state.selection: + o = set(orig_a.state.selection.get(pstr, [])) + d = set(dup_a.state.selection.get(pstr, [])) + if o and d: + assert o.isdisjoint(d) + + +def test_history_duplication_cas_b_synthetic_head(): + """Duplicating an operation-rooted chain synthesizes an initial-state head.""" + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) # NO creation recorded + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.derivative) + original_session = history.history_sessions[-1] + # Operation-rooted: no creation action at the head. + assert original_session.actions[0].method_name != "new_object" + _select_tree_session(history, original_session) + history.duplicate_selected_entries() + dup_session = history.history_sessions[-1] + assert dup_session is not original_session + # Cas B: exactly one synthetic head prepended. + assert len(dup_session.actions) == len(original_session.actions) + 1 + head = dup_session.actions[0] + assert head.kind == HistoryAction.KIND_UI + assert head.method_name == "new_object" + assert head.kwargs == {} + assert head.state.selection == {} # empty state (always compatible) + assert len(head.output_uuids) == 1 + clone_uuid = head.output_uuids[0] + # Head output registered in the panel mappings. + assert history.action_output_uuids.get(head.uuid) == [clone_uuid] + assert history.output_to_action.get(clone_uuid) == head.uuid + # Clone materialized in the panel. + assert clone_uuid in panel.objmodel.get_object_ids() + # Head + ops re-link into a SINGLE chain on the duplicate. + dup_chains = build_session_chains(history, dup_session) + assert len(dup_chains) == 1 + assert dup_chains[0].root is head + assert sum(len(c.actions) for c in dup_chains) == len(dup_session.actions) + # Replay of the duplicate adds no new object (creations skipped under + # suppression). + _select_tree_session(history, dup_session) + n_obj = len(panel.objmodel) + n_hist = len(history) + history.replay_restore_actions(replay=True, restore_selection=False) + assert len(panel.objmodel) == n_obj + assert len(history) == n_hist + + # --------------------------------------------------------------------------- # 7) Stepping + selection sync # --------------------------------------------------------------------------- From a1e20f5a3987f9682e6ce5763c0bf5ab9cda64ff Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Wed, 8 Jul 2026 12:48:57 +0200 Subject: [PATCH 051/108] Refactor: Model history sessions as single linear processing chains A history session now represents exactly one linear processing chain. The previous read-model split a session into several chains at each creation action, which detached downstream processing when duplicating a session. Session boundaries are already decided at recording time (the "start a new history session?" prompt shown on object creation), so no per-creation splitting is performed at display time anymore. * [CHG] : build_session_chains() now returns a single ProcessingChain per session (root = first action, all actions kept in order) * [FIX] : copy_with_uuid_remap() resolves an effective panel string from the action target so new_object output UUIDs are remapped on duplication * [CHG] : Remove dead HistoryAction.regenerate_uuid no-op --- datalab/gui/historytools_ops.py | 25 +++++++++----- datalab/gui/panel/history/chainmodel.py | 46 +++++++++---------------- datalab/history/action.py | 18 +++++++--- 3 files changed, 45 insertions(+), 44 deletions(-) diff --git a/datalab/gui/historytools_ops.py b/datalab/gui/historytools_ops.py index 037dcece5..8d3e95c11 100644 --- a/datalab/gui/historytools_ops.py +++ b/datalab/gui/historytools_ops.py @@ -32,6 +32,13 @@ from datalab.gui.panel.history import HistoryPanel +def _action_panel_str(action: HistoryAction) -> str: + """Return the panel an action operates on, using target as fallback.""" + if action.panel_str: + return action.panel_str + return {"imagepanel": "image", "signalpanel": "signal"}.get(action.target, "signal") + + def _make_initial_state_head(pstr: str, clone_uuid: str, title: str) -> HistoryAction: """Return a synthetic creation-root action for an operation-rooted chain. @@ -70,12 +77,12 @@ def duplicate_selected_entries(panel: HistoryPanel) -> None: """Duplicate selected processing chains into new independent sessions. Selection is resolved to *processing chains* (see - :func:`build_session_chains`): selecting a session duplicates all its - chains, while selecting an action duplicates the single chain that - contains it. For each source session, exactly one new session is produced - containing the duplicates of its selected chains, with all referenced data - objects deep-copied into a new group and every UUID reference rewritten to - the clones. + :func:`build_session_chains`): a session **is** a single linear processing + chain, so selecting a session duplicates its chain, and selecting an action + duplicates the chain of its session. For each source session, exactly one + new session is produced containing the duplicate of its chain, with all + referenced data objects deep-copied into a new group and every UUID + reference rewritten to the clones. Two chain shapes are handled: @@ -149,7 +156,7 @@ def duplicate_selected_entries(panel: HistoryPanel) -> None: uuids_by_panel.setdefault(pstr, set()).update(metadata.keys()) obj2 = action.kwargs.get("obj2_uuids") if obj2: - pstr = action.panel_str or "signal" + pstr = _action_panel_str(action) if isinstance(obj2, str): obj2 = [obj2] uuids_by_panel.setdefault(pstr, set()).update(obj2) @@ -157,7 +164,7 @@ def duplicate_selected_entries(panel: HistoryPanel) -> None: # compute step). Without this, the last action's outputs # would be missing because no subsequent state captures them. if action.output_uuids: - pstr = action.panel_str or "signal" + pstr = _action_panel_str(action) uuids_by_panel.setdefault(pstr, set()).update(action.output_uuids) # 3. Clone objects and build uuid_remap. @@ -251,7 +258,7 @@ def duplicate_selected_entries(panel: HistoryPanel) -> None: root_inputs.append((pstr, old_uuid)) obj2 = chain.root.kwargs.get("obj2_uuids") if obj2: - pstr = chain.root.panel_str or "signal" + pstr = _action_panel_str(chain.root) if isinstance(obj2, str): obj2 = [obj2] for old_uuid in obj2: diff --git a/datalab/gui/panel/history/chainmodel.py b/datalab/gui/panel/history/chainmodel.py index 726b17700..1f62f9cf7 100644 --- a/datalab/gui/panel/history/chainmodel.py +++ b/datalab/gui/panel/history/chainmodel.py @@ -55,41 +55,27 @@ def action_input_uuids(action: HistoryAction) -> set[str]: def build_session_chains( panel: HistoryPanel, session: HistorySession ) -> list[ProcessingChain]: - """Group the actions of a single session into ordered processing chains. + """Return the session's single processing chain. + + In DataLab's history model a session **is** a single linear processing + chain: every action of the session belongs to one chain, the first action + being its root. Session boundaries are decided at recording time (the + "start a new history session?" prompt shown on object creation), so no + per-creation splitting is performed here. Args: - panel: The history panel providing the action→output registry. - session: The session whose actions are grouped. + panel: The history panel (kept for signature stability; unused). + session: The session whose actions form the chain. Returns: - The session's processing chains, in creation order. Each chain lists - its actions in session order, the root first. + A single-element list with the session's chain, or an empty list when + the session has no actions. """ - uuid_to_chain: dict[str, ProcessingChain] = {} - chains: list[ProcessingChain] = [] - for action in session.actions: - is_creation = ( - action.kind == HistoryAction.KIND_UI - and action.method_name in HistoryAction.UI_CREATION_METHODS - ) - if is_creation: - chain = ProcessingChain(root=action, session=session) - chains.append(chain) - chain.actions.append(action) - else: - inputs = action_input_uuids(action) - chain = None - for uuid in sorted(inputs): - if uuid in uuid_to_chain: - chain = uuid_to_chain[uuid] - break - if chain is None: - chain = ProcessingChain(root=action, session=session) - chains.append(chain) - chain.actions.append(action) - for out in panel.action_output_uuids.get(action.uuid, []): - uuid_to_chain[out] = chain - return chains + if not session.actions: + return [] + chain = ProcessingChain(root=session.actions[0], session=session) + chain.actions = list(session.actions) + return [chain] def build_processing_chains( diff --git a/datalab/history/action.py b/datalab/history/action.py index 22c40d8dc..5c648eb53 100644 --- a/datalab/history/action.py +++ b/datalab/history/action.py @@ -148,9 +148,6 @@ def has_pending_edits(self) -> bool: """Return True if this action has unsaved edit-mode changes.""" return self._saved_kwargs is not None - def regenerate_uuid(self): - """Regenerate UUID after loading from a file (no-op: per-action UUID).""" - def copy(self, title_suffix: str | None = None) -> HistoryAction: """Return an independent copy of this history action.""" state = self.state.copy() @@ -175,6 +172,17 @@ def copy(self, title_suffix: str | None = None) -> HistoryAction: # Copying an action acts as an implicit commit (no pending edits). return new_action + def _effective_panel_str(self) -> str: + """Return the panel this action operates on ("signal"/"image"). + + Falls back to the UI ``target`` when ``panel_str`` is unset (the case for + creation actions such as ``new_object``, whose ``panel_str`` is ``None`` + but whose ``target`` identifies the panel). + """ + if self.panel_str: + return self.panel_str + return {"imagepanel": "image", "signalpanel": "signal"}.get(self.target, "") + def copy_with_uuid_remap( self, uuid_remap: dict[str, dict[str, str]] ) -> HistoryAction: @@ -204,7 +212,7 @@ def copy_with_uuid_remap( if obj2: if isinstance(obj2, str): obj2 = [obj2] - pstr = new_action.panel_str or "" + pstr = new_action._effective_panel_str() pmap = uuid_remap.get(pstr, {}) rewritten = [pmap.get(u, u) for u in obj2] new_action.kwargs["obj2_uuids"] = ( @@ -212,7 +220,7 @@ def copy_with_uuid_remap( ) # Rewrite output_uuids — they reference the target panel. if new_action.output_uuids: - pstr = new_action.panel_str or "" + pstr = new_action._effective_panel_str() pmap = uuid_remap.get(pstr, {}) new_action.output_uuids = [pmap.get(u, u) for u in new_action.output_uuids] return new_action From cb4b0fe4034e5578c9164f85de8d5a4a8996ec10 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Wed, 8 Jul 2026 12:49:22 +0200 Subject: [PATCH 052/108] Refactor: Remove dead code from the history subsystem Clean-up pass on the history panel: remove symbols that had no caller left in production nor in the test suite. This reduces the maintenance surface without changing any behaviour. * [CHG] : Remove unused add_to_history decorator and its _resolve_self_target helper (never applied anywhere), drop the add_to_history re-export * [CHG] : Remove unused add_entry entry-point and its panel delegation * [CHG] : Remove dead chain helper collect_downstream_uuids * [CHG] : Remove unused HistoryTree.get_selected_actions * [CHG] : Remove dead replay helpers edit_mode_replay (singular), view_only_session_replay and show_readonly_param_dialog * [CHG] : Remove ~14 dead HistoryPanel delegation methods that duplicated live module-level functions with no caller --- datalab/gui/historysession_ops.py | 35 +------ datalab/gui/panel/history/chain.py | 24 ----- .../gui/panel/history/interactive_replay.py | 60 ------------ datalab/gui/panel/history/panel.py | 96 +------------------ datalab/history/__init__.py | 2 - datalab/history/core.py | 60 +----------- datalab/widgets/historytree.py | 22 ----- 7 files changed, 4 insertions(+), 295 deletions(-) diff --git a/datalab/gui/historysession_ops.py b/datalab/gui/historysession_ops.py index b1d39401b..bd4e7dab2 100644 --- a/datalab/gui/historysession_ops.py +++ b/datalab/gui/historysession_ops.py @@ -7,7 +7,7 @@ import logging from contextlib import contextmanager from copy import deepcopy -from typing import TYPE_CHECKING, Any, Callable, Generator +from typing import TYPE_CHECKING, Any, Generator from qtpy import QtCore as QC from qtpy import QtWidgets as QW @@ -15,7 +15,6 @@ from datalab.config import _ from datalab.env import execenv from datalab.history import HistoryAction, HistorySession, WorkspaceState -from datalab.history.core import _resolve_self_target if TYPE_CHECKING: from datalab.gui.panel.history import HistoryPanel @@ -366,38 +365,6 @@ def add_ui_entry( return action -def add_entry( - panel: HistoryPanel, - action_title: str, - save_state: bool, - func: Callable, - **kwargs, -) -> None: - """Legacy entry-point kept as a compatibility shim. - - Most call sites have been migrated to :meth:`add_compute_entry` or - :meth:`add_ui_entry`. The remaining paths -- and the - :func:`add_to_history` decorator -- still call ``add_entry`` with a - bound method; we infer the ``(target, method_name)`` from the bound - ``func.__self__`` and route to :meth:`add_ui_entry`. - """ - if not panel.record_mode_enabled or panel.is_replaying(): - return - target = None - if hasattr(func, "__self__"): - target = _resolve_self_target(func.__self__) - if target is None: - # Cannot route safely -- skip rather than pickle a Callable. - return - panel.add_ui_entry( - action_title, - target=target, - method_name=func.__name__, - save_state=save_state, - **kwargs, - ) - - def add_object(panel: HistoryPanel, obj: HistoryAction) -> None: """Add an action to the active session of its panel. diff --git a/datalab/gui/panel/history/chain.py b/datalab/gui/panel/history/chain.py index e268e055a..2dd62d78d 100644 --- a/datalab/gui/panel/history/chain.py +++ b/datalab/gui/panel/history/chain.py @@ -229,30 +229,6 @@ def action_consumes_any(action: HistoryAction, uuids: set[str]) -> bool: return bool(captured & uuids) -def collect_downstream_uuids(panel: HistoryPanel, action: HistoryAction) -> set[str]: - """Return the transitive closure of output UUIDs descending from ``action``.""" - if not panel.history_sessions: - return set() - current = get_session_of(panel, action) - if current is None: - return set() - root_out = action_output_uuid(panel, action) - if root_out is None: - return set() - closure: set[str] = {root_out} - idx = current.actions.index(action) - for downstream in current.actions[idx + 1 :]: - if downstream.kind != HistoryAction.KIND_COMPUTE: - continue - if not action_consumes_any(downstream, closure): - continue - out_uuid = action_output_uuid(panel, downstream) - if out_uuid is not None: - closure.add(out_uuid) - closure.discard(root_out) - return closure - - def get_downstream_actions( panel: HistoryPanel, action: HistoryAction ) -> list[HistoryAction]: diff --git a/datalab/gui/panel/history/interactive_replay.py b/datalab/gui/panel/history/interactive_replay.py index 0eb79d01f..6298b07aa 100644 --- a/datalab/gui/panel/history/interactive_replay.py +++ b/datalab/gui/panel/history/interactive_replay.py @@ -9,7 +9,6 @@ from typing import TYPE_CHECKING import guidata.dataset as gds -from guidata.dataset.qtwidgets import DataSetEditDialog, DataSetGroupEditDialog from qtpy import QtWidgets as QW from datalab.config import _ @@ -111,15 +110,6 @@ def prompt_edit_action_params( return True -def edit_mode_replay(panel: HistoryPanel, action: HistoryAction) -> None: - """Replay a single action in edit mode: open param dialog, update kwargs. - - Only the given action is edited and recomputed in place: no automatic - cascade towards unselected downstream actions. - """ - edit_mode_replay_actions(panel, [action]) - - def edit_mode_replay_actions(panel: HistoryPanel, actions: list[HistoryAction]) -> None: """Edit and recompute only the selected actions, in session order. @@ -192,56 +182,6 @@ def _order_selected_actions( return unique -def show_readonly_param_dialog( - panel: HistoryPanel, dataset: gds.DataSet | gds.DataSetGroup -) -> None: - """Show a parameter dialog identical to the edit dialog but read-only.""" - if isinstance(dataset, gds.DataSetGroup): - dialog = DataSetGroupEditDialog(dataset, parent=panel.mainwindow) - else: - dialog = DataSetEditDialog(dataset, parent=panel.mainwindow) - for edl in dialog.edit_layout: - for widget in edl.widgets: - if widget.group is not None: - widget.group.setEnabled(False) - if widget.label is not None: - widget.label.setEnabled(False) - dialog.exec() - - -def view_only_session_replay( - panel: HistoryPanel, - session: HistorySession, - restore_selection: bool, -) -> None: - """Replay a session in edit mode with read-only parameter dialogs.""" - for action in session.actions: - if action.kind != HistoryAction.KIND_COMPUTE: - continue - pattern = action.pattern - panel.select_action_in_tree(action) - QW.QApplication.processEvents() - if pattern in {"1_to_1", "1_to_0", "n_to_1", "2_to_1"}: - param = action.kwargs.get("param") - if param is not None: - show_readonly_param_dialog(panel, copy.deepcopy(param)) - elif pattern == "1_to_n": - params = action.kwargs.get("params") or [] - if params: - group = gds.DataSetGroup( - [copy.deepcopy(p) for p in params], - title=_("Parameters"), - ) - show_readonly_param_dialog(panel, group) - - with panel.replaying(), panel.output_suppressed(): - session.replay( - panel.mainwindow, - restore_selection=restore_selection, - edit=False, - ) - - def restore_action_params( panel: HistoryPanel, item: HistoryAction | HistorySession ) -> None: diff --git a/datalab/gui/panel/history/panel.py b/datalab/gui/panel/history/panel.py index ac15516b3..6171e03ad 100644 --- a/datalab/gui/panel/history/panel.py +++ b/datalab/gui/panel/history/panel.py @@ -9,7 +9,7 @@ import functools import logging from contextlib import contextmanager -from typing import TYPE_CHECKING, Any, Callable, Generator +from typing import TYPE_CHECKING, Any, Generator from guidata.configtools import get_icon from guidata.qthelpers import add_actions, create_action @@ -437,20 +437,6 @@ def prompt_edit_action_params(self, action: HistoryAction) -> bool | None: """Open the parameter dialog for *action* according to its pattern.""" return hreplay.prompt_edit_action_params(self, action) - def edit_mode_replay(self, action: HistoryAction) -> None: - """Replay a single action in edit mode.""" - return hreplay.edit_mode_replay(self, action) - - def show_readonly_param_dialog(self, dataset: Any) -> None: - """Show a parameter dialog identical to the edit dialog but read-only.""" - return hreplay.show_readonly_param_dialog(self, dataset) - - def view_only_session_replay( - self, session: HistorySession, restore_selection: bool - ) -> None: - """Replay a session in edit mode with read-only parameter dialogs.""" - return hreplay.view_only_session_replay(self, session, restore_selection) - def restore_action_params(self, item: HistoryAction | HistorySession) -> None: """Restore original kwargs from snapshot and recompute in-place.""" return hreplay.restore_action_params(self, item) @@ -497,14 +483,6 @@ def action_output_uuid(self, action: HistoryAction) -> str | None: """Return the UUID of the object produced by ``action``, or ``None``.""" return hchain.action_output_uuid(self, action) - def action_consumes_any(self, action: HistoryAction, uuids: set[str]) -> bool: - """Return True if ``action``'s input UUIDs intersect ``uuids``.""" - return hchain.action_consumes_any(action, uuids) - - def collect_downstream_uuids(self, action: HistoryAction) -> set[str]: - """Return the transitive closure of output UUIDs descending from ``action``.""" - return hchain.collect_downstream_uuids(self, action) - def get_downstream_actions(self, action: HistoryAction) -> list[HistoryAction]: """Return the actions of the current session that depend on ``action``.""" return hchain.get_downstream_actions(self, action) @@ -525,32 +503,10 @@ def prune_output_mapping(self) -> None: """Drop entries of :attr:`output_to_action` whose object no longer exists.""" return hchain.prune_output_mapping(self) - def rewrite_action_source( - self, - action: HistoryAction, - pstr: str, - old_uuid: str, - new_uuid: str, - ) -> None: - """Replace ``old_uuid`` with ``new_uuid`` in an action's recorded inputs.""" - return hchain.rewrite_action_source(action, pstr, old_uuid, new_uuid) - def remove_single_action(self, action: HistoryAction) -> None: """Remove a single action from its session (splice, not truncate).""" return hchain.remove_single_action(self, action) - def reconnect_single_removed( - self, - panel: BaseDataPanel, - x_uuid: str, - warnings: list[str], - roots_to_recompute: list[HistoryAction], - ) -> None: - """Reconnect consumers of a single deleted object ``x_uuid``.""" - return hchain.reconnect_single_removed( - self, panel, x_uuid, warnings, roots_to_recompute - ) - def reconnect_chain_after_removal(self, panel: BaseDataPanel) -> None: """Reconnect the processing chain after object(s) were deleted.""" return hchain.reconnect_chain_after_removal(self, panel) @@ -563,46 +519,6 @@ def refresh_action(self, action: HistoryAction) -> None: """Refresh the tree display for ``action`` after its kwargs were mutated.""" return hrec.refresh_action(self, action) - def update_obj_in_place(self, target_obj: Any, new_obj: Any) -> None: - """Copy data + title + metadata from ``new_obj`` onto ``target_obj``.""" - return hrec.update_obj_in_place(target_obj, new_obj) - - def refresh_target(self, panel: BaseDataPanel, output_uuid: str) -> None: - """Refresh tree item + plot for ``output_uuid`` in ``panel``.""" - return hrec.refresh_target(panel, output_uuid) - - def record_missing_outputs(self, action: HistoryAction, missing: list[str]) -> None: - """Log + queue a user-facing warning for deleted output objects.""" - return hrec.record_missing_outputs(self, action, missing) - - def recompute_action_in_place(self, action: HistoryAction) -> None: - """Re-run ``action`` on the existing output object(s) (same UUIDs).""" - return hrec.recompute_action_in_place(self, action) - - def handle_missing_feature(self, action: HistoryAction, exc: Any) -> None: - """Flag ``action`` as broken (missing plugin) and queue a user warning.""" - return hrec.handle_missing_feature(self, action, exc) - - def recompute_1_to_1_in_place(self, action: HistoryAction) -> None: - """Recompute a single 1-to-1 action in place.""" - return hrec.recompute_1_to_1_in_place(self, action) - - def recompute_1_to_n_in_place(self, action: HistoryAction) -> None: - """Recompute a 1-to-n action in place.""" - return hrec.recompute_1_to_n_in_place(self, action) - - def recompute_n_to_1_in_place(self, action: HistoryAction) -> None: - """Recompute an n-to-1 action in place.""" - return hrec.recompute_n_to_1_in_place(self, action) - - def recompute_2_to_1_in_place(self, action: HistoryAction) -> None: - """Recompute a 2-to-1 action in place.""" - return hrec.recompute_2_to_1_in_place(self, action) - - def recompute_1_to_0_in_place(self, action: HistoryAction) -> None: - """Recompute a 1-to-0 analysis on each source object in place.""" - return hrec.recompute_1_to_0_in_place(self, action) - def recompute_cascade( self, root_action: HistoryAction, @@ -1009,16 +925,6 @@ def add_ui_entry( self, action_title, target, method_name, save_state, **kwargs ) - def add_entry( - self, - action_title: str, - save_state: bool, - func: Callable, - **kwargs: Any, - ) -> None: - """Add a generic entry to the history.""" - return hsess.add_entry(self, action_title, save_state, func, **kwargs) - # ------ AbstractPanel interface --------------------------------------------------- def create_object(self) -> HistoryAction: """Create and return object.""" diff --git a/datalab/history/__init__.py b/datalab/history/__init__.py index 2ecb73c20..35dc65ae7 100644 --- a/datalab/history/__init__.py +++ b/datalab/history/__init__.py @@ -6,7 +6,6 @@ from datalab.history.core import ( HISTORY_ACTION_SCHEMA_VERSION, HISTORY_SCHEMA_VERSION, - add_to_history, get_datetime_str, ) from datalab.history.session import HistorySession @@ -18,6 +17,5 @@ "HistoryAction", "HistorySession", "WorkspaceState", - "add_to_history", "get_datetime_str", ] diff --git a/datalab/history/core.py b/datalab/history/core.py index 07ec11a4d..68263a0ef 100644 --- a/datalab/history/core.py +++ b/datalab/history/core.py @@ -1,18 +1,17 @@ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. """ -History core utilities: schema constants, JSON codec, ``@add_to_history`` decorator. +History core utilities: schema constants, JSON codec. """ from __future__ import annotations -import functools import importlib import json import logging import warnings from copy import deepcopy -from typing import TYPE_CHECKING, Any +from typing import Any import numpy as np from guidata.dataset.conv import dataset_to_json, json_to_dataset @@ -22,11 +21,6 @@ from datalab.config import _ -if TYPE_CHECKING: - from datalab.gui.panel.base import BaseDataPanel - from datalab.gui.panel.history import HistoryPanel - from datalab.gui.processor.base import BaseProcessor - _logger = logging.getLogger(__name__) _TRUSTED_ROI_MODULE_PREFIX = "sigima." @@ -185,53 +179,3 @@ def _copy_history_value(value: Any) -> Any: if isinstance(value, tuple): return tuple(_copy_history_value(item) for item in value) return deepcopy(value) - - -def add_to_history(kwargs_names: list[str] | None = None, title: str | None = None): - """Method decorator to add the method call to the history panel as a UI entry. - - Args: - kwargs_names: List of keyword arguments to add to the history action. - Defaults to None. - title: Title of the history action. Defaults to None. - """ - if kwargs_names is None: - kwargs_names = [] - - def add_to_history_decorator(func): - """Decorator function""" - - @functools.wraps(func) - def method_wrapper(*args, **kwargs): - """Decorator wrapper function""" - self: BaseDataPanel | BaseProcessor = args[0] - history: HistoryPanel = self.mainwindow.historypanel - histkwargs = {k: kwargs[k] for k in kwargs_names if k in kwargs} - target = _resolve_self_target(self) - if target is not None: - history.add_ui_entry( - kwargs.get("title", title) or func.__name__, - target=target, - method_name=func.__name__, - save_state=kwargs.get("save_state", True), - **histkwargs, - ) - return func(*args, **kwargs) - - return method_wrapper - - return add_to_history_decorator - - -def _resolve_self_target(self_obj: Any) -> str | None: - """Resolve a 'self' instance to a string target understood by replay. - - Used by the legacy ``@add_to_history`` decorator. Returns None when no - safe routing is possible (in which case the entry is skipped). - """ - panel_str = getattr(self_obj, "PANEL_STR_ID", None) - if panel_str == "signal": - return "signalpanel" - if panel_str == "image": - return "imagepanel" - return None diff --git a/datalab/widgets/historytree.py b/datalab/widgets/historytree.py index fdfad20ca..caa0c44f8 100644 --- a/datalab/widgets/historytree.py +++ b/datalab/widgets/historytree.py @@ -324,25 +324,3 @@ def get_selected_actions_or_sessions( # chain-header items are containers only: ignored here. return selected - def get_selected_actions( - self, history_sessions: list[HistorySession] - ) -> list[HistoryAction]: - """Get the selected actions - - Args: - history_sessions: List of history sessions - - Returns: - list[HistoryAction]: List of selected actions - """ - selected: list[HistoryAction] = [] - for item in self.selectedItems(): - if item.parent() is not None and ( - item.data(0, self.ITEM_KIND_ROLE) == self.ITEM_ACTION - ): - uuid = item.data(0, QC.Qt.UserRole) - try: - selected.append(self.get_action_from_uuid(uuid, history_sessions)) - except ValueError: - continue - return selected From e153f6c25462f34055ef5473d6b8a446d621145c Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Wed, 8 Jul 2026 12:54:45 +0200 Subject: [PATCH 053/108] Refactor: Remove the disabled "Generate macro" history feature The "Generate macro" action of the history panel was permanently hidden (setVisible(False), "out of current scope"). Remove it entirely together with its unreachable implementation to reduce the maintenance surface. * [CHG] : Remove the generate_macro_action and its HistoryPanel.generate_macro delegation from the history panel * [CHG] : Remove the historytools_ops.generate_macro implementation * [CHG] : Remove HistoryAction.to_macro_code (only consumed by generate_macro) --- datalab/gui/historytools_ops.py | 183 ----------------------------- datalab/gui/panel/history/panel.py | 15 --- datalab/history/action.py | 84 ------------- 3 files changed, 282 deletions(-) diff --git a/datalab/gui/historytools_ops.py b/datalab/gui/historytools_ops.py index 8d3e95c11..a8d980fbe 100644 --- a/datalab/gui/historytools_ops.py +++ b/datalab/gui/historytools_ops.py @@ -316,189 +316,6 @@ def duplicate_selected_entries(panel: HistoryPanel) -> None: panel.update_actions_state() -def generate_macro(panel: HistoryPanel) -> None: - """Generate a standalone Python script from selected history entries. - - The generated script uses sigima functions directly with proper variable - chaining. Object references (UUIDs) are resolved to variable names so - that 2-to-1 operations reference the correct intermediate result. - The script is copied to the clipboard and the user is notified. - """ - selected = panel.tree.get_selected_actions_or_sessions(panel.history_sessions) - actions: list[HistoryAction] = [] - if not selected: - for session in panel.history_sessions: - actions.extend(session.actions) - else: - for item in selected: - if isinstance(item, HistorySession): - actions.extend(item.actions) - else: - actions.append(item) - if not actions: - return - - # Filter to compute-only actions for the pipeline - compute_actions = [a for a in actions if a.kind == HistoryAction.KIND_COMPUTE] - if not compute_actions: - if not execenv.unattended: - QW.QMessageBox.information( - panel.mainwindow, - _("Generate macro"), - _("No compute actions to export."), - ) - return - - # Determine input type from first action - first_panel = compute_actions[0].panel_str - if first_panel == "signal": - obj_type = "SignalObj" - obj_import = "from sigima.objects import SignalObj" - else: - obj_type = "ImageObj" - obj_import = "from sigima.objects import ImageObj" - - imports: set[str] = set() - imports.add(obj_import) - body_lines: list[str] = [] - - # UUID → variable mapping for resolving object references. - # Populated with input UUIDs ("src", "src_2", ...) and enriched - # with each step's output UUID after code generation. - uuid_to_var: dict[str, str] = {} - - # Extra input parameters discovered during generation (second - # operands that are not produced by any previous step). - extra_inputs: list[str] = [] - - # Seed the mapping with the first action's input selection. - first_sel = compute_actions[0].state.selection.get(compute_actions[0].panel_str, []) - for i, uuid in enumerate(first_sel): - var = "src" if i == 0 else f"src_{i + 1}" - uuid_to_var[uuid] = var - - step = 0 - current_var = "src" - - for action in compute_actions: - step += 1 - - # Resolve input variable from the action's selection UUIDs. - sel_uuids = action.state.selection.get(action.panel_str or "", []) - if sel_uuids and sel_uuids[0] in uuid_to_var: - input_var = uuid_to_var[sel_uuids[0]] - else: - input_var = current_var - - # Resolve second operand for 2-to-1 patterns. - obj2_var: str | None = None - if action.pattern == "2_to_1": - obj2_uuids = action.kwargs.get("obj2_uuids", []) - if isinstance(obj2_uuids, str): - obj2_uuids = [obj2_uuids] - if obj2_uuids: - obj2_uuid = obj2_uuids[0] - if obj2_uuid in uuid_to_var: - obj2_var = uuid_to_var[obj2_uuid] - else: - # External input — add as function parameter. - obj2_var = f"obj2_{step}" - uuid_to_var[obj2_uuid] = obj2_var - extra_inputs.append(obj2_var) - - code_lines, output_var = action.to_macro_code( - step, input_var, imports, obj2_var=obj2_var - ) - body_lines.extend(code_lines) - body_lines.append("") - - if output_var is not None: - current_var = output_var - # Map the output UUID so subsequent steps can reference it. - output_uuid = panel.action_output_uuid(action) - if output_uuid: - uuid_to_var[output_uuid] = output_var - # Also register any new UUIDs from the action's selection - # that we haven't seen yet (secondary selections). - for uuid in sel_uuids[1:]: - if uuid not in uuid_to_var: - uuid_to_var[uuid] = input_var - - # Build the function signature with extra inputs. - params_str = f"src: {obj_type}" - for extra in extra_inputs: - params_str += f", {extra}: {obj_type}" - - # Assemble the full script - sorted_imports = sorted(imports) - script_lines: list[str] = [ - '"""', - "DataLab — standalone processing pipeline", - f"Generated from history ({len(compute_actions)} steps)", - '"""', - "", - ] - script_lines.extend(sorted_imports) - script_lines.append("") - script_lines.append("") - script_lines.append(f"def process({params_str}) -> {obj_type}:") - script_lines.append(' """Apply the recorded processing pipeline."""') - for line in body_lines: - script_lines.append(f" {line}" if line else "") - script_lines.append(f" return {current_var}") - script_lines.append("") - script_lines.append("") - script_lines.append('if __name__ == "__main__":') - script_lines.append(" # Standalone execution: run from DataLab's Macro panel.") - script_lines.append(" # Operates on the current object of the target panel.") - script_lines.append(" from datalab.control.proxy import RemoteProxy") - script_lines.append("") - script_lines.append(" proxy = RemoteProxy()") - panel_str = compute_actions[0].panel_str or ( - "signal" if obj_type == "SignalObj" else "image" - ) - script_lines.append(f' proxy.set_current_panel("{panel_str}")') - if extra_inputs: - n_extra = len(extra_inputs) - script_lines.append(" _uuids = proxy.get_sel_object_uuids()") - script_lines.append(f" if len(_uuids) < {n_extra + 1}:") - script_lines.append(" raise RuntimeError(") - script_lines.append( - f' "Pipeline needs {n_extra + 1} selected' - f' object(s): 1 source + {n_extra} extra"' - ) - script_lines.append(" )") - script_lines.append(f' src = proxy.get_object(_uuids[0], "{panel_str}")') - script_lines.append(" if src is None:") - script_lines.append( - f' raise RuntimeError("No current object in panel: {panel_str}")' - ) - for idx, extra in enumerate(extra_inputs): - script_lines.append( - f' {extra} = proxy.get_object(_uuids[{idx + 1}], "{panel_str}")' - ) - else: - script_lines.append(" src = proxy.get_object()") - script_lines.append(" if src is None:") - script_lines.append( - f' raise RuntimeError("No current object in panel: {panel_str}")' - ) - extra_args = "".join(f", {e}" for e in extra_inputs) - script_lines.append(f" result = process(src{extra_args})") - script_lines.append(" proxy.add_object(result)") - script_lines.append(' print(f"Pipeline applied: {result.title}")') - script_lines.append("") - - script = "\n".join(script_lines) - QW.QApplication.clipboard().setText(script) - if not execenv.unattended: - QW.QMessageBox.information( - panel.mainwindow, - _("Generate macro"), - _("Macro script copied to clipboard (%d actions).") % len(compute_actions), - ) - - def _data_panel_for(panel: HistoryPanel, panel_str: str) -> BaseDataPanel | None: """Return the data panel matching ``panel_str`` (``"signal"``/``"image"``).""" if panel_str == "signal": diff --git a/datalab/gui/panel/history/panel.py b/datalab/gui/panel/history/panel.py index 6171e03ad..2ad5e5c2f 100644 --- a/datalab/gui/panel/history/panel.py +++ b/datalab/gui/panel/history/panel.py @@ -252,16 +252,6 @@ def create_menu_actions(self) -> list[QW.QAction]: tip=_("Select the next action in the current session"), shortcut=QG.QKeySequence("Ctrl+Right"), ) - generate_macro_action = create_action( - self, - _("Generate macro"), - self.generate_macro, - icon=get_icon("console.svg"), - tip=_("Generate a Python macro script from history"), - ) - # Temporarily disabled (out of current scope): keep the action and its - # implementation, but hide it from the toolbar and context menu. - generate_macro_action.setVisible(False) remove_incompatible_action = create_action( self, _("Remove incompatible"), @@ -309,7 +299,6 @@ def create_menu_actions(self) -> list[QW.QAction]: edit_action, None, self._duplicate_action, - generate_macro_action, None, remove_incompatible_action, self._delete_action, @@ -755,10 +744,6 @@ def duplicate_selected_entries(self) -> None: """Duplicate selected entries.""" return htools.duplicate_selected_entries(self) - def generate_macro(self) -> None: - """Generate a Python macro script from history.""" - return htools.generate_macro(self) - def select_sessions(self, sessions: list[HistorySession]) -> None: """Select top-level tree items matching ``sessions``.""" self.tree.clearSelection() diff --git a/datalab/history/action.py b/datalab/history/action.py index 5c648eb53..7f28ef953 100644 --- a/datalab/history/action.py +++ b/datalab/history/action.py @@ -335,90 +335,6 @@ def description_html(self) -> str: return html.escape(text).replace("\n", "<br>") return "" - def to_macro_code( - self, - step_index: int, - input_var: str, - imports: set[str], - obj2_var: str | None = None, - ) -> tuple[list[str], str | None]: - """Return Python source lines for this action as a standalone sigima call. - - Args: - step_index: Step number for variable naming. - input_var: Name of the input variable from the previous step. - imports: Mutable set of import statements accumulated by the caller. - obj2_var: Resolved variable name for the second operand (2-to-1 - pattern). When ``None``, the second operand is left as a - placeholder. - - Returns: - Tuple of (code_lines, output_var_name). ``output_var_name`` is - ``None`` for UI-kind actions (no data output). - """ - if self.kind != self.KIND_COMPUTE: - return [f"# (UI) {self.title} [skipped]"], None - - lines: list[str] = [] - output_var = f"result_{step_index}" - - # Determine the sigima module alias - if self.panel_str == "signal": - mod_alias = "sips" - imports.add("import sigima.proc.signal as sips") - elif self.panel_str == "image": - mod_alias = "sipi" - imports.add("import sigima.proc.image as sipi") - else: - lines.append(f"# {self.title} [unknown panel: {self.panel_str}]") - return lines, None - - lines.append(f"# Step {step_index}: {self.title}") - - param = self.kwargs.get("param") - param_var: str | None = None - - if param is not None and isinstance(param, DataSet): - param_var = f"param_{step_index}" - param_class = type(param).__qualname__ - param_module = type(param).__module__ - imports.add(f"from {param_module} import {param_class}") - lines.append(f"{param_var} = {param_class}()") - # Reconstruct each attribute - for item in param.get_items(): - attr_name = item.get_name() - value = getattr(param, attr_name, None) - if value is not None: - lines.append(f"{param_var}.{attr_name} = {value!r}") - - # Build the function call - func_call = f"{mod_alias}.{self.func_name}" - if self.pattern in ("1_to_1", "1_to_0"): - if param_var: - lines.append(f"{output_var} = {func_call}({input_var}, {param_var})") - else: - lines.append(f"{output_var} = {func_call}({input_var})") - elif self.pattern == "n_to_1": - if param_var: - lines.append(f"{output_var} = {func_call}([{input_var}], {param_var})") - else: - lines.append(f"{output_var} = {func_call}([{input_var}])") - elif self.pattern == "2_to_1": - second = obj2_var or "... # TODO: provide second operand" - if param_var: - lines.append( - f"{output_var} = {func_call}({input_var}, {second}, {param_var})" - ) - else: - lines.append(f"{output_var} = {func_call}({input_var}, {second})") - elif self.pattern == "1_to_n": - lines.append(f"{output_var} = {func_call}({input_var})") - else: - lines.append(f"# Unknown pattern {self.pattern!r}") - return lines, None - - return lines, output_var - # ------------------------------------------------------------------ # Workspace-state delegation # ------------------------------------------------------------------ From b1b248ffb39accaf196ff0345ae51845dec9433c Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Wed, 8 Jul 2026 12:59:31 +0200 Subject: [PATCH 054/108] Refactor: Remove the disabled "Restore parameters" history action The "Restore parameters" toolbar/context action was permanently hidden (setVisible(False), "out of current scope"). Remove the dead UI entry point and its unused panel delegation. The underlying replay_restore_actions() branch is kept as it is still exercised elsewhere. * [CHG] : Remove the _restore_selection_action and all its references in create_menu_actions and update_actions_state * [CHG] : Remove the dead HistoryPanel.restore_action_params delegation --- datalab/gui/panel/history/panel.py | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/datalab/gui/panel/history/panel.py b/datalab/gui/panel/history/panel.py index 2ad5e5c2f..a8034a780 100644 --- a/datalab/gui/panel/history/panel.py +++ b/datalab/gui/panel/history/panel.py @@ -69,7 +69,6 @@ def __init__(self, parent: DLMainWindow) -> None: self._duplicate_action: QW.QAction | None = None self.step_prev_action: QW.QAction | None = None self.step_next_action: QW.QAction | None = None - self._restore_selection_action: QW.QAction | None = None self._edit_action: QW.QAction | None = None self._record_action: QW.QAction | None = None self._menu_actions: list[QW.QAction] = self.create_menu_actions() @@ -143,10 +142,6 @@ def update_actions_state(self) -> None: self.step_prev_action.setEnabled(self.can_step_prev()) if self.step_next_action is not None: self.step_next_action.setEnabled(self.can_step_next()) - if self._restore_selection_action is not None: - self._restore_selection_action.setEnabled( - self.edit_mode or self.has_any_pending_edits() - ) @property def session_increment(self) -> int: @@ -259,16 +254,6 @@ def create_menu_actions(self) -> list[QW.QAction]: icon=get_icon("edit/delete_all.svg"), tip=_("Remove actions incompatible with the current workspace"), ) - self._restore_selection_action = create_action( - self, - _("Restore parameters"), - lambda: self.replay_restore_actions(restore_selection=True, replay=False), - icon=get_icon("restore_selection.svg"), - tip=_("Restore original parameters (discard edit-mode changes)"), - ) - # Temporarily disabled (out of current scope): keep the action and its - # restore logic, but hide it from the toolbar and context menu. - self._restore_selection_action.setVisible(False) replay_action = create_action( self, _("Replay"), @@ -295,7 +280,6 @@ def create_menu_actions(self) -> list[QW.QAction]: None, replay_action, step_by_step_action, - self._restore_selection_action, edit_action, None, self._duplicate_action, @@ -426,10 +410,6 @@ def prompt_edit_action_params(self, action: HistoryAction) -> bool | None: """Open the parameter dialog for *action* according to its pattern.""" return hreplay.prompt_edit_action_params(self, action) - def restore_action_params(self, item: HistoryAction | HistorySession) -> None: - """Restore original kwargs from snapshot and recompute in-place.""" - return hreplay.restore_action_params(self, item) - # ------------------------------------------------------------------ # Chain delegations # ------------------------------------------------------------------ From 76d6ba26f05a8c437f93a9896e9aab28279ff9a4 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Wed, 8 Jul 2026 13:18:32 +0200 Subject: [PATCH 055/108] Refactor: Remove the disabled "Edit mode" toolbar button The "Edit mode" toggle action was permanently hidden (setVisible(False), superseded by the Replay / Step-by-step launch modes). Remove the dead UI entry point and its _edit_action attribute. The edit-mode mechanism itself is kept intact as it is still used by the recompute pipeline (is_edit_mode), the step-by-step replay and the test suite. * [CHG] : Remove the edit_action button, its _edit_action attribute and the now-useless action re-sync branch in toggle_edit_mode --- datalab/gui/panel/history/panel.py | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/datalab/gui/panel/history/panel.py b/datalab/gui/panel/history/panel.py index a8034a780..820084daf 100644 --- a/datalab/gui/panel/history/panel.py +++ b/datalab/gui/panel/history/panel.py @@ -69,7 +69,6 @@ def __init__(self, parent: DLMainWindow) -> None: self._duplicate_action: QW.QAction | None = None self.step_prev_action: QW.QAction | None = None self.step_next_action: QW.QAction | None = None - self._edit_action: QW.QAction | None = None self._record_action: QW.QAction | None = None self._menu_actions: list[QW.QAction] = self.create_menu_actions() @@ -177,18 +176,6 @@ def update_state_widget(self) -> None: def create_menu_actions(self) -> list[QW.QAction]: """Create menu actions for the history panel.""" - edit_action = create_action( - self, - _("Edit mode"), - toggled=self.toggle_edit_mode, - icon=get_icon("edit_mode.svg"), - ) - edit_action.setChecked(self.edit_mode) - self._edit_action = edit_action - # Temporarily disabled (superseded by the Replay / Step-by-step launch - # modes): keep the action and its edit-mode logic, but hide it from the - # toolbar and context menu. - edit_action.setVisible(False) record_action = create_action( self, _("Record mode"), @@ -280,7 +267,6 @@ def create_menu_actions(self) -> list[QW.QAction]: None, replay_action, step_by_step_action, - edit_action, None, self._duplicate_action, None, @@ -314,10 +300,6 @@ def toggle_edit_mode(self, checked: bool) -> None: ) ) if reply != QW.QMessageBox.Yes: - if self._edit_action is not None: - self._edit_action.blockSignals(True) - self._edit_action.setChecked(True) - self._edit_action.blockSignals(False) return self.edit_mode = checked if not checked: From 5e819502f349c242b09c7edf1379e949616f1dda Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Wed, 8 Jul 2026 13:19:15 +0200 Subject: [PATCH 056/108] Chore: Remove leftover blank line in history tree widget --- datalab/widgets/historytree.py | 1 - 1 file changed, 1 deletion(-) diff --git a/datalab/widgets/historytree.py b/datalab/widgets/historytree.py index caa0c44f8..1ded02370 100644 --- a/datalab/widgets/historytree.py +++ b/datalab/widgets/historytree.py @@ -323,4 +323,3 @@ def get_selected_actions_or_sessions( continue # chain-header items are containers only: ignored here. return selected - From 06a43ccf43b7f2d60c67f76b7f978eda6a776c51 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Wed, 8 Jul 2026 13:28:28 +0200 Subject: [PATCH 057/108] Doc: Sync history panel documentation and translations with the cleanup Reflect the removal of the disabled "Generate macro", "Restore parameters" and "Edit mode" toolbar actions, and document the "New session" and "Step-by-step" actions that were missing. * [CHG] : Update historypanel.rst toolbar list to match the actual actions * [CHG] : Drop obsolete UI translation entries (Generate macro, Restore parameters, Edit mode and related strings) * [CHG] : Update the French documentation catalog for the history panel --- datalab/locale/fr/LC_MESSAGES/datalab.po | 23 +----- doc/features/common/historypanel.rst | 40 ++++------ .../features/common/historypanel.po | 75 +++++++++++-------- 3 files changed, 58 insertions(+), 80 deletions(-) diff --git a/datalab/locale/fr/LC_MESSAGES/datalab.po b/datalab/locale/fr/LC_MESSAGES/datalab.po index 32c91dee3..1a178c820 100644 --- a/datalab/locale/fr/LC_MESSAGES/datalab.po +++ b/datalab/locale/fr/LC_MESSAGES/datalab.po @@ -974,16 +974,6 @@ msgstr "Nouvelle session d'historique" msgid "Initial state" msgstr "État initial" -msgid "Generate macro" -msgstr "Générer une macro" - -msgid "No compute actions to export." -msgstr "Pas d'actions de calcul à exporter." - -#, python-format -msgid "Macro script copied to clipboard (%d actions)." -msgstr "Script de macro copié dans le presse-papier (%d actions)." - msgid "Chain copy" msgstr "Copie de chaîne" @@ -1763,9 +1753,6 @@ msgstr "Panneau d'historique" msgid "History files" msgstr "Fichiers d'historique" -msgid "Edit mode" -msgstr "Mode d'édition" - msgid "Record mode" msgstr "Mode d'enregistrement" @@ -1802,18 +1789,9 @@ msgstr "Étape suivante" msgid "Select the next action in the current session" msgstr "Sélectionner l'action suivante dans la session courante" -msgid "Generate a Python macro script from history" -msgstr "Générer un script macro Python à partir de l'historique" - msgid "Remove actions incompatible with the current workspace" msgstr "Supprimer les actions incompatibles avec l'espace de travail courant" -msgid "Restore parameters" -msgstr "Restaurer les paramètres" - -msgid "Restore original parameters (discard edit-mode changes)" -msgstr "Restaurer les paramètres d'origine (annuler les modifications du mode d'édition)" - msgid "Replay" msgstr "Rejouer" @@ -4344,3 +4322,4 @@ msgstr "Aucun contour n'a été trouvé pour la plage de niveaux sélectionnée. msgid "Show contour plot..." msgstr "Afficher le tracé de contours..." + diff --git a/doc/features/common/historypanel.rst b/doc/features/common/historypanel.rst index 7f1ecf594..5d369b438 100644 --- a/doc/features/common/historypanel.rst +++ b/doc/features/common/historypanel.rst @@ -25,8 +25,6 @@ A recorded session can be: the workspace; - **Duplicated and applied**, to create an explicit comparison branch with new outputs in the signal/image panels; -- **Restored to a given selection state** without re-executing anything, to - quickly jump back to a previous working context; - **Saved to a standalone history file** (``.dlhist``) or **embedded in the workspace** when saving to HDF5, so that the full processing chain travels with the data. @@ -50,27 +48,27 @@ The toolbar at the top of the panel exposes the following actions: :height: 24px :class: dark-light no-scaled-link -.. |open_history| image:: ../../../datalab/data/icons/io/fileopen_h5.svg +.. |new_session| image:: ../../../datalab/data/icons/libre-gui-add.svg :width: 24px :height: 24px :class: dark-light no-scaled-link -.. |save_history| image:: ../../../datalab/data/icons/io/filesave_h5.svg +.. |open_history| image:: ../../../datalab/data/icons/io/fileopen_h5.svg :width: 24px :height: 24px :class: dark-light no-scaled-link -.. |replay| image:: ../../../datalab/data/icons/replay.svg +.. |save_history| image:: ../../../datalab/data/icons/io/filesave_h5.svg :width: 24px :height: 24px :class: dark-light no-scaled-link -.. |restore_selection| image:: ../../../datalab/data/icons/restore_selection.svg +.. |replay| image:: ../../../datalab/data/icons/replay.svg :width: 24px :height: 24px :class: dark-light no-scaled-link -.. |edit_mode| image:: ../../../datalab/data/icons/edit_mode.svg +.. |step_by_step| image:: ../../../datalab/data/icons/edit_mode.svg :width: 24px :height: 24px :class: dark-light no-scaled-link @@ -95,11 +93,6 @@ The toolbar at the top of the panel exposes the following actions: :height: 24px :class: dark-light no-scaled-link -.. |generate_macro| image:: ../../../datalab/data/icons/console.svg - :width: 24px - :height: 24px - :class: dark-light no-scaled-link - .. |remove_incompatible| image:: ../../../datalab/data/icons/edit/delete_all.svg :width: 24px :height: 24px @@ -107,37 +100,30 @@ The toolbar at the top of the panel exposes the following actions: - |record| **Record mode**: toggle the recording of new actions. When off, no new entry is added to the history (existing sessions are preserved). +- |new_session| **New session**: start a new history session. - |open_history| **Open history file**: load recorded sessions from a standalone ``.dlhist`` file. - |save_history| **Save history file**: save the current recorded sessions to a standalone ``.dlhist`` file. +- |step_prev| **Previous step**: select the preceding action in the current + session (keyboard shortcut: :kbd:`Ctrl+Left`). +- |step_next| **Next step**: select the following action in the current + session (keyboard shortcut: :kbd:`Ctrl+Right`). - |replay| **Replay**: validate/replay the selected action (or the whole session if a session row is selected) without changing the current workspace selection beforehand and without adding new outputs to the signal/image panels. -- |restore_selection| **Restore selection**: only re-select the objects that - were selected when the action was originally executed; no computation is - re-run. -- |edit_mode| **Edit mode**: when on, replaying a computation opens the - parameters dialog so the user can tweak the parameters before re-running. - When replaying a *whole session*, the parameter dialogs open in a - **read-only** mode — all fields are shown with their recorded values but - cannot be edited. +- |step_by_step| **Step-by-step**: replay the selection one step at a time, + opening the parameters dialog at each step so the user can tweak the + parameters before re-running. - |duplicate| **Duplicate**: copy the selected action or session into a new history session. The copied parameters are independent from the original record. -- |generate_macro| **Generate macro**: generate a Python macro script from the - selected actions (or all actions if nothing is selected). The generated script - is copied to the clipboard. - |remove_incompatible| **Remove incompatible**: remove all actions whose workspace state is no longer compatible with the current workspace. A confirmation dialog shows how many actions will be removed. - |delete| **Delete**: remove the selected actions or sessions from the history. -- |step_prev| **Previous step**: select the preceding action in the current - session (keyboard shortcut: :kbd:`Ctrl+Left`). -- |step_next| **Next step**: select the following action in the current - session (keyboard shortcut: :kbd:`Ctrl+Right`). .. note:: diff --git a/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po b/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po index daf1be0d6..98b241dd5 100644 --- a/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po +++ b/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po @@ -41,9 +41,6 @@ msgstr "**rejouée** en mode validation, sans ajouter de nouvelles sorties signa msgid "**Duplicated and applied**, to create an explicit comparison branch with new outputs in the signal/image panels;" msgstr "**dupliquée et appliquée**, afin de créer une branche de comparaison explicite avec de nouvelles sorties dans les panneaux signal/image ;" -msgid "**Restored to a given selection state** without re-executing anything, to quickly jump back to a previous working context;" -msgstr "**restaurée dans un état de sélection donné** sans rien réexécuter, afin de revenir rapidement à un contexte de travail antérieur ;" - msgid "**Saved to a standalone history file** (``.dlhist``) or **embedded in the workspace** when saving to HDF5, so that the full processing chain travels with the data." msgstr "**sauvegardée dans un fichier d'historique autonome** (``.dlhist``) ou **intégrée à l'espace de travail** lors de l'enregistrement au format HDF5, de sorte que toute la chaîne de traitement accompagne les données." @@ -62,6 +59,12 @@ msgstr "|record| **Mode enregistrement** : active ou désactive l'enregistrement msgid "record" msgstr "record" +msgid "|new_session| **New session**: start a new history session." +msgstr "|new_session| **Nouvelle session** : démarre une nouvelle session d'historique." + +msgid "new_session" +msgstr "new_session" + msgid "|open_history| **Open history file**: load recorded sessions from a standalone ``.dlhist`` file." msgstr "|open_history| **Ouvrir un fichier d'historique** : charge des sessions enregistrées depuis un fichier ``.dlhist`` autonome." @@ -74,23 +77,29 @@ msgstr "|save_history| **Enregistrer le fichier d'historique** : enregistre les msgid "save_history" msgstr "save_history" +msgid "|step_prev| **Previous step**: select the preceding action in the current session (keyboard shortcut: :kbd:`Ctrl+Left`)." +msgstr "|step_prev| **Étape précédente** : sélectionne l'action précédente dans la session courante (raccourci clavier : :kbd:`Ctrl+Gauche`)." + +msgid "step_prev" +msgstr "step_prev" + +msgid "|step_next| **Next step**: select the following action in the current session (keyboard shortcut: :kbd:`Ctrl+Right`)." +msgstr "|step_next| **Étape suivante** : sélectionne l'action suivante dans la session courante (raccourci clavier : :kbd:`Ctrl+Droite`)." + +msgid "step_next" +msgstr "step_next" + msgid "|replay| **Replay**: validate/replay the selected action (or the whole session if a session row is selected) without changing the current workspace selection beforehand and without adding new outputs to the signal/image panels." msgstr "|replay| **Rejouer** : valide/rejoue l'action sélectionnée (ou la session entière si une ligne de session est sélectionnée) sans modifier au préalable la sélection courante de l'espace de travail et sans ajouter de nouvelles sorties aux panneaux signal/image." msgid "replay" msgstr "replay" -msgid "|restore_selection| **Restore selection**: only re-select the objects that were selected when the action was originally executed; no computation is re-run." -msgstr "|restore_selection| **Restaurer la sélection** : ré-sélectionne uniquement les objets qui étaient sélectionnés lors de l'exécution initiale de l'action ; aucun calcul n'est ré-exécuté." +msgid "|step_by_step| **Step-by-step**: replay the selection one step at a time, opening the parameters dialog at each step so the user can tweak the parameters before re-running." +msgstr "|step_by_step| **Pas à pas** : rejoue la sélection étape par étape, en ouvrant la boîte de dialogue des paramètres à chaque étape afin que l'utilisateur puisse ajuster les paramètres avant de relancer." -msgid "restore_selection" -msgstr "restore_selection" - -msgid "|edit_mode| **Edit mode**: when on, replaying a computation opens the parameters dialog so the user can tweak the parameters before re-running. When replaying a *whole session*, the parameter dialogs open in a **read-only** mode — all fields are shown with their recorded values but cannot be edited." -msgstr "|edit_mode| **Mode édition** : lorsqu'il est activé, le rejeu d'un calcul ouvre la boîte de dialogue des paramètres afin que l'utilisateur puisse ajuster les paramètres avant de relancer. Lors du rejeu d'une *session entière*, les boîtes de dialogue des paramètres s'ouvrent en mode **lecture seule** — tous les champs affichent les valeurs enregistrées mais ne peuvent pas être édités." - -msgid "edit_mode" -msgstr "edit_mode" +msgid "step_by_step" +msgstr "step_by_step" msgid "|duplicate| **Duplicate**: copy the selected action or session into a new history session. The copied parameters are independent from the original record." msgstr "|duplicate| **Dupliquer** : copie l'action ou la session sélectionnée dans une nouvelle session d'historique. Les paramètres copiés sont indépendants de l'enregistrement d'origine." @@ -98,12 +107,6 @@ msgstr "|duplicate| **Dupliquer** : copie l'action ou la session sélectionnée msgid "duplicate" msgstr "duplicate" -msgid "|generate_macro| **Generate macro**: generate a Python macro script from the selected actions (or all actions if nothing is selected). The generated script is copied to the clipboard." -msgstr "|generate_macro| **Générer une macro** : génère un script macro Python à partir des actions sélectionnées (ou de toutes les actions si rien n'est sélectionné). Le script généré est copié dans le presse-papiers." - -msgid "generate_macro" -msgstr "generate_macro" - msgid "|remove_incompatible| **Remove incompatible**: remove all actions whose workspace state is no longer compatible with the current workspace. A confirmation dialog shows how many actions will be removed." msgstr "|remove_incompatible| **Supprimer les incompatibles** : supprime toutes les actions dont l'état de l'espace de travail n'est plus compatible avec l'espace de travail actuel. Une boîte de dialogue de confirmation indique combien d'actions seront supprimées." @@ -116,18 +119,6 @@ msgstr "|delete| **Supprimer** : retire de l'historique les actions ou sessions msgid "delete" msgstr "delete" -msgid "|step_prev| **Previous step**: select the preceding action in the current session (keyboard shortcut: :kbd:`Ctrl+Left`)." -msgstr "|step_prev| **Étape précédente** : sélectionne l'action précédente dans la session courante (raccourci clavier : :kbd:`Ctrl+Gauche`)." - -msgid "step_prev" -msgstr "step_prev" - -msgid "|step_next| **Next step**: select the following action in the current session (keyboard shortcut: :kbd:`Ctrl+Right`)." -msgstr "|step_next| **Étape suivante** : sélectionne l'action suivante dans la session courante (raccourci clavier : :kbd:`Ctrl+Droite`)." - -msgid "step_next" -msgstr "step_next" - msgid "Double-clicking on an action row in the tree is equivalent to **Replay**." msgstr "Un double-clic sur la ligne d'une action dans l'arborescence équivaut à **Rejouer**." @@ -229,3 +220,25 @@ msgstr "Recalcul automatique" msgid "When a result object is selected in the signal/image panel and it has processing parameters (i.e. was produced by a 1-to-1 computation), a **Processing** tab appears in the Properties panel. Checking **Auto-recompute on edit** in that tab will re-run the computation automatically 300 ms after any parameter modification." msgstr "Lorsqu'un objet résultat est sélectionné dans le panneau signal/image et qu'il possède des paramètres de traitement (c'est-à-dire qu'il a été produit par un calcul 1-à-1), un onglet **Traitement** apparaît dans le panneau Propriétés. Cocher **Recalcul automatique lors de l'édition** dans cet onglet relancera automatiquement le calcul 300 ms après toute modification d'un paramètre." + +#~ msgid "**Restored to a given selection state** without re-executing anything, to quickly jump back to a previous working context;" +#~ msgstr "**restaurée dans un état de sélection donné** sans rien réexécuter, afin de revenir rapidement à un contexte de travail antérieur ;" + +#~ msgid "|restore_selection| **Restore selection**: only re-select the objects that were selected when the action was originally executed; no computation is re-run." +#~ msgstr "|restore_selection| **Restaurer la sélection** : ré-sélectionne uniquement les objets qui étaient sélectionnés lors de l'exécution initiale de l'action ; aucun calcul n'est ré-exécuté." + +#~ msgid "restore_selection" +#~ msgstr "restore_selection" + +#~ msgid "|edit_mode| **Edit mode**: when on, replaying a computation opens the parameters dialog so the user can tweak the parameters before re-running. When replaying a *whole session*, the parameter dialogs open in a **read-only** mode — all fields are shown with their recorded values but cannot be edited." +#~ msgstr "|edit_mode| **Mode édition** : lorsqu'il est activé, le rejeu d'un calcul ouvre la boîte de dialogue des paramètres afin que l'utilisateur puisse ajuster les paramètres avant de relancer. Lors du rejeu d'une *session entière*, les boîtes de dialogue des paramètres s'ouvrent en mode **lecture seule** — tous les champs affichent les valeurs enregistrées mais ne peuvent pas être édités." + +#~ msgid "edit_mode" +#~ msgstr "edit_mode" + +#~ msgid "|generate_macro| **Generate macro**: generate a Python macro script from the selected actions (or all actions if nothing is selected). The generated script is copied to the clipboard." +#~ msgstr "|generate_macro| **Générer une macro** : génère un script macro Python à partir des actions sélectionnées (ou de toutes les actions si rien n'est sélectionné). Le script généré est copié dans le presse-papiers." + +#~ msgid "generate_macro" +#~ msgstr "generate_macro" + From 76895ffc64e7276c2da17cae9db9027bb6b3f276 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Wed, 8 Jul 2026 14:01:01 +0200 Subject: [PATCH 058/108] Refactor: Drop the private-underscore formalism in the history subsystem Rename module-level functions, methods and the cross-module panel attributes so they no longer use the single leading-underscore "private" formalism, in line with the project coding conventions. This clears the protected-access (W0212) warnings raised on cross-module usage without introducing any lint suppression. Property backing fields and purely-internal attributes stay private. * [CHG] : Rename private history helper functions to public names * [CHG] : Rename private HistoryAction, WorkspaceState, HistoryPanel and HistoryTree methods to public names * [CHG] : Expose the cross-module panel flags (edit_replay_in_progress, suppress_session_prompt, session_input_pending) as public attributes --- datalab/gui/historysession_ops.py | 12 +- datalab/gui/historytools_ops.py | 50 +- .../gui/panel/history/interactive_replay.py | 10 +- datalab/gui/panel/history/panel.py | 13 +- datalab/history/action.py | 54 +- datalab/history/core.py | 32 +- datalab/history/workspace_state.py | 20 +- datalab/tests/features/common/history_test.py | 849 +++++++----------- datalab/widgets/historytree.py | 6 +- .../features/common/historypanel.po | 1 - 10 files changed, 438 insertions(+), 609 deletions(-) diff --git a/datalab/gui/historysession_ops.py b/datalab/gui/historysession_ops.py index bd4e7dab2..76628a440 100644 --- a/datalab/gui/historysession_ops.py +++ b/datalab/gui/historysession_ops.py @@ -34,7 +34,7 @@ def create_new_session( Returns: The newly created session. """ - pstr = panel_str or panel._current_panel_str() + pstr = panel_str or panel.current_panel_str() panel.session_increment += 1 session = HistorySession(number=panel.session_increment) panel.history_sessions.append(session) @@ -64,7 +64,7 @@ def maybe_start_session_for_input(panel: HistoryPanel, *, load: bool = False) -> """ if not panel.record_mode_enabled or panel.is_replaying(): return - if panel._suppress_session_prompt: + if panel.suppress_session_prompt: return # Reuse the current session when there is none yet or it has no actions: # there is nothing to preserve, so no need to prompt. @@ -72,10 +72,10 @@ def maybe_start_session_for_input(panel: HistoryPanel, *, load: bool = False) -> return # Debounce: a synchronous burst of creations (plugin/macro) must prompt only # once. The guard is reset on the next event-loop turn. - if panel._session_input_pending: + if panel.session_input_pending: return - panel._session_input_pending = True - QC.QTimer.singleShot(0, lambda: setattr(panel, "_session_input_pending", False)) + panel.session_input_pending = True + QC.QTimer.singleShot(0, lambda: setattr(panel, "session_input_pending", False)) if execenv.unattended: # Headless runs: honor the accept_dialogs flag (default False -> "No"), # so tests can drive the behavior without a real modal dialog. @@ -373,7 +373,7 @@ def add_object(panel: HistoryPanel, obj: HistoryAction) -> None: and image pipelines stay in separate sessions and recording resumes in the user-selected session. """ - pstr = obj.panel_str or panel._current_panel_str() + pstr = obj.panel_str or panel.current_panel_str() session = panel.get_active_session(pstr) if session is None: session = panel.create_new_session(panel_str=pstr) diff --git a/datalab/gui/historytools_ops.py b/datalab/gui/historytools_ops.py index a8d980fbe..fbe8f8738 100644 --- a/datalab/gui/historytools_ops.py +++ b/datalab/gui/historytools_ops.py @@ -32,14 +32,14 @@ from datalab.gui.panel.history import HistoryPanel -def _action_panel_str(action: HistoryAction) -> str: +def action_panel_str(action: HistoryAction) -> str: """Return the panel an action operates on, using target as fallback.""" if action.panel_str: return action.panel_str return {"imagepanel": "image", "signalpanel": "signal"}.get(action.target, "signal") -def _make_initial_state_head(pstr: str, clone_uuid: str, title: str) -> HistoryAction: +def make_initial_state_head(pstr: str, clone_uuid: str, title: str) -> HistoryAction: """Return a synthetic creation-root action for an operation-rooted chain. A *Cas B* chain starts from an operation whose input object was created @@ -156,7 +156,7 @@ def duplicate_selected_entries(panel: HistoryPanel) -> None: uuids_by_panel.setdefault(pstr, set()).update(metadata.keys()) obj2 = action.kwargs.get("obj2_uuids") if obj2: - pstr = _action_panel_str(action) + pstr = action_panel_str(action) if isinstance(obj2, str): obj2 = [obj2] uuids_by_panel.setdefault(pstr, set()).update(obj2) @@ -164,7 +164,7 @@ def duplicate_selected_entries(panel: HistoryPanel) -> None: # compute step). Without this, the last action's outputs # would be missing because no subsequent state captures them. if action.output_uuids: - pstr = _action_panel_str(action) + pstr = action_panel_str(action) uuids_by_panel.setdefault(pstr, set()).update(action.output_uuids) # 3. Clone objects and build uuid_remap. @@ -258,7 +258,7 @@ def duplicate_selected_entries(panel: HistoryPanel) -> None: root_inputs.append((pstr, old_uuid)) obj2 = chain.root.kwargs.get("obj2_uuids") if obj2: - pstr = _action_panel_str(chain.root) + pstr = action_panel_str(chain.root) if isinstance(obj2, str): obj2 = [obj2] for old_uuid in obj2: @@ -278,7 +278,7 @@ def duplicate_selected_entries(panel: HistoryPanel) -> None: head_title = data_panel.objmodel[clone_uuid].title except (KeyError, AttributeError): head_title = _("Initial state") - head = _make_initial_state_head(pstr, clone_uuid, head_title) + head = make_initial_state_head(pstr, clone_uuid, head_title) heads.append(head) panel.action_output_uuids[head.uuid] = [clone_uuid] panel.output_to_action[clone_uuid] = head.uuid @@ -316,7 +316,7 @@ def duplicate_selected_entries(panel: HistoryPanel) -> None: panel.update_actions_state() -def _data_panel_for(panel: HistoryPanel, panel_str: str) -> BaseDataPanel | None: +def data_panel_for(panel: HistoryPanel, panel_str: str) -> BaseDataPanel | None: """Return the data panel matching ``panel_str`` (``"signal"``/``"image"``).""" if panel_str == "signal": return panel.mainwindow.signalpanel @@ -325,7 +325,7 @@ def _data_panel_for(panel: HistoryPanel, panel_str: str) -> BaseDataPanel | None return None -def _action_input_uuids(action: HistoryAction) -> set[str]: +def action_input_uuids(action: HistoryAction) -> set[str]: """Return the set of object UUIDs consumed as inputs by ``action``.""" captured: set[str] = set(action.state.selection.get(action.panel_str or "", [])) obj2 = action.kwargs.get("obj2_uuids") @@ -337,7 +337,7 @@ def _action_input_uuids(action: HistoryAction) -> set[str]: return captured -def _strip_source_links(obj) -> None: +def strip_source_links(obj) -> None: """Turn ``obj`` into a parentless creation root (drop source references).""" pp = extract_processing_parameters(obj) if pp is None: @@ -354,7 +354,7 @@ def _strip_source_links(obj) -> None: ) -def _remap_object_source(obj, old_uuid: str, new_uuid: str) -> None: +def remap_object_source(obj, old_uuid: str, new_uuid: str) -> None: """Replace ``old_uuid`` with ``new_uuid`` in ``obj``'s source references.""" pp = extract_processing_parameters(obj) if pp is None: @@ -370,11 +370,11 @@ def _remap_object_source(obj, old_uuid: str, new_uuid: str) -> None: insert_processing_parameters(obj, pp) -def _first_alive_output( +def first_alive_output( panel: HistoryPanel, panel_str: str, output_uuids: list[str] ) -> str | None: """Return the first ``output_uuids`` entry still present in its data panel.""" - data_panel = _data_panel_for(panel, panel_str) + data_panel = data_panel_for(panel, panel_str) if data_panel is None: return None for out_uuid in output_uuids: @@ -383,7 +383,7 @@ def _first_alive_output( return None -def _split_chain_on_action_delete( +def split_chain_on_action_delete( panel: HistoryPanel, action: HistoryAction ) -> str | None: """Splice ``action`` out of its session and split its processing chain. @@ -409,16 +409,16 @@ def _split_chain_on_action_delete( # Splice the action out (does not truncate the rest of the session). hchain.remove_single_action(panel, action) if not downstream: - return _first_alive_output(panel, panel_str, output_uuids) + return first_alive_output(panel, panel_str, output_uuids) first = downstream[0] - data_panel = _data_panel_for(panel, first.panel_str or "") + data_panel = data_panel_for(panel, first.panel_str or "") if data_panel is None: - return _first_alive_output(panel, panel_str, output_uuids) + return first_alive_output(panel, panel_str, output_uuids) # Locate the orphaned output object that ``first`` still consumes. - first_inputs = _action_input_uuids(first) + first_inputs = action_input_uuids(first) orphan_uuid = next((u for u in output_uuids if u in first_inputs), None) if orphan_uuid is None or not data_panel.objmodel.has_uuid(orphan_uuid): - return _first_alive_output(panel, panel_str, output_uuids) + return first_alive_output(panel, panel_str, output_uuids) # §8.2 — autonomy via COPY: clone the orphan as a parentless creation root. orphan_obj = data_panel.objmodel[orphan_uuid] clone = deepcopy(orphan_obj) @@ -427,24 +427,24 @@ def _split_chain_on_action_delete( clone.set_metadata_option("uuid", new_uuid) except AttributeError: clone.uuid = new_uuid - _strip_source_links(clone) + strip_source_links(clone) group_id = get_uuid(data_panel.add_group(_("Chain copy"))) data_panel.add_object(clone, group_id=group_id) # Rewire ALL downstream actions that directly consume the orphan onto the copy. for d in downstream: - if orphan_uuid not in _action_input_uuids(d): + if orphan_uuid not in action_input_uuids(d): continue hchain.rewrite_action_source(d, d.panel_str or "", orphan_uuid, new_uuid) for out_uuid in panel.action_output_uuids.get(d.uuid, []): if data_panel.objmodel.has_uuid(out_uuid): - _remap_object_source( + remap_object_source( data_panel.objmodel[out_uuid], orphan_uuid, new_uuid ) # The orphan is now consumed by no surviving action: report it as orphaned. return orphan_uuid if data_panel.objmodel.has_uuid(orphan_uuid) else None -def _remove_data_object(data_panel: BaseDataPanel, obj_uuid: str) -> None: +def remove_data_object(data_panel: BaseDataPanel, obj_uuid: str) -> None: """Remove a single object from ``data_panel`` without recording history.""" obj = data_panel.objmodel[obj_uuid] data_panel.plothandler.remove_item(obj_uuid) @@ -504,7 +504,7 @@ def delete_selected(panel: HistoryPanel) -> None: sessions_to_remove.add(id(item)) elif isinstance(item, HistoryAction): # Individual action: splice it out and split its chain (with copy). - orphan_uuid = _split_chain_on_action_delete(panel, item) + orphan_uuid = split_chain_on_action_delete(panel, item) if orphan_uuid is not None: orphan_refs.append((item.panel_str or "", orphan_uuid)) panel.history_sessions = [ @@ -513,7 +513,7 @@ def delete_selected(panel: HistoryPanel) -> None: # §8.3 — opt-in: offer to also remove the now-orphaned output object(s). alive_orphans: list[tuple[BaseDataPanel, str]] = [] for panel_str, orphan_uuid in orphan_refs: - data_panel = _data_panel_for(panel, panel_str) + data_panel = data_panel_for(panel, panel_str) if data_panel is not None and data_panel.objmodel.has_uuid(orphan_uuid): alive_orphans.append((data_panel, orphan_uuid)) if alive_orphans and not execenv.unattended: @@ -531,7 +531,7 @@ def delete_selected(panel: HistoryPanel) -> None: touched: dict[int, BaseDataPanel] = {} for data_panel, orphan_uuid in alive_orphans: if data_panel.objmodel.has_uuid(orphan_uuid): - _remove_data_object(data_panel, orphan_uuid) + remove_data_object(data_panel, orphan_uuid) touched[id(data_panel)] = data_panel for data_panel in touched.values(): data_panel.objview.update_tree() diff --git a/datalab/gui/panel/history/interactive_replay.py b/datalab/gui/panel/history/interactive_replay.py index 6298b07aa..96e068a28 100644 --- a/datalab/gui/panel/history/interactive_replay.py +++ b/datalab/gui/panel/history/interactive_replay.py @@ -117,13 +117,13 @@ def edit_mode_replay_actions(panel: HistoryPanel, actions: list[HistoryAction]) downstream actions are left untouched (no automatic cascade). A re-entrance guard prevents nested prompt loops. """ - if getattr(panel, "_edit_replay_in_progress", False): + if panel.edit_replay_in_progress: return # Deduplicate and sort the selected actions in their session order - ordered = _order_selected_actions(panel, actions) + ordered = order_selected_actions(panel, actions) if not ordered: return - panel._edit_replay_in_progress = True + panel.edit_replay_in_progress = True try: edited_actions: list[HistoryAction] = [] recomputable: list[HistoryAction] = [] @@ -158,10 +158,10 @@ def edit_mode_replay_actions(panel: HistoryPanel, actions: list[HistoryAction]) hrec.recompute_cascade(panel, edited_actions[0]) QW.QApplication.processEvents() finally: - panel._edit_replay_in_progress = False + panel.edit_replay_in_progress = False -def _order_selected_actions( +def order_selected_actions( panel: HistoryPanel, actions: list[HistoryAction] ) -> list[HistoryAction]: """Deduplicate ``actions`` and sort them by (session, position) order.""" diff --git a/datalab/gui/panel/history/panel.py b/datalab/gui/panel/history/panel.py index 820084daf..6698f947e 100644 --- a/datalab/gui/panel/history/panel.py +++ b/datalab/gui/panel/history/panel.py @@ -63,8 +63,9 @@ def __init__(self, parent: DLMainWindow) -> None: self._output_suppressed = False self._syncing = False self.cascade_in_progress = False - self._session_input_pending = False - self._suppress_session_prompt = False + self.session_input_pending = False + self.suppress_session_prompt = False + self.edit_replay_in_progress = False self._delete_action: QW.QAction | None = None self._duplicate_action: QW.QAction | None = None self.step_prev_action: QW.QAction | None = None @@ -548,7 +549,7 @@ def current_action(self) -> HistoryAction | None: except ValueError: return None - def _current_panel_str(self) -> str: + def current_panel_str(self) -> str: """Return the current data panel id ('signal'/'image'); default 'signal'.""" pstr = self.mainwindow.get_current_panel() return pstr if pstr in ("signal", "image") else "signal" @@ -794,12 +795,12 @@ def maybe_start_session_for_input(self, *, load: bool = False) -> None: @contextmanager def session_prompt_suppressed(self) -> Generator[None, None, None]: """Context manager suppressing the new-session prompt during a batch load.""" - previous = self._suppress_session_prompt - self._suppress_session_prompt = True + previous = self.suppress_session_prompt + self.suppress_session_prompt = True try: yield finally: - self._suppress_session_prompt = previous + self.suppress_session_prompt = previous def add_compute_entry( self, diff --git a/datalab/history/action.py b/datalab/history/action.py index 7f28ef953..ced734326 100644 --- a/datalab/history/action.py +++ b/datalab/history/action.py @@ -22,9 +22,9 @@ from datalab.history.core import ( HISTORY_ACTION_SCHEMA_VERSION, HISTORY_SCHEMA_VERSION, - _copy_history_value, - _decode_kwargs, - _encode_kwargs, + copy_history_value, + decode_kwargs, + encode_kwargs, get_datetime_str, ) from datalab.history.workspace_state import WorkspaceState @@ -58,7 +58,7 @@ class HistoryAction(ObjItf): # replay, these UI actions are skipped so the panel object count stays stable. UI_CREATION_METHODS: frozenset[str] = frozenset({"new_object"}) # UI methods that destroy data objects. Replaying these requires that the - # captured selection still resolves to existing objects (see ``_replay_ui``). + # captured selection still resolves to existing objects (see ``replay_ui``). DESTRUCTIVE_METHODS: frozenset[str] = frozenset( {"remove_object", "remove_group", "delete_all_objects"} ) @@ -130,7 +130,7 @@ def snapshot_kwargs(self) -> None: """ if self._saved_kwargs is None: self._saved_kwargs = { - key: _copy_history_value(value) for key, value in self.kwargs.items() + key: copy_history_value(value) for key, value in self.kwargs.items() } def restore_kwargs(self) -> None: @@ -163,7 +163,7 @@ def copy(self, title_suffix: str | None = None) -> HistoryAction: target=self.target, method_name=self.method_name, kwargs={ - key: _copy_history_value(value) for key, value in self.kwargs.items() + key: copy_history_value(value) for key, value in self.kwargs.items() }, state=state, ) @@ -172,7 +172,7 @@ def copy(self, title_suffix: str | None = None) -> HistoryAction: # Copying an action acts as an implicit commit (no pending edits). return new_action - def _effective_panel_str(self) -> str: + def effective_panel_str(self) -> str: """Return the panel this action operates on ("signal"/"image"). Falls back to the UI ``target`` when ``panel_str`` is unset (the case for @@ -212,7 +212,7 @@ def copy_with_uuid_remap( if obj2: if isinstance(obj2, str): obj2 = [obj2] - pstr = new_action._effective_panel_str() + pstr = new_action.effective_panel_str() pmap = uuid_remap.get(pstr, {}) rewritten = [pmap.get(u, u) for u in obj2] new_action.kwargs["obj2_uuids"] = ( @@ -220,7 +220,7 @@ def copy_with_uuid_remap( ) # Rewrite output_uuids — they reference the target panel. if new_action.output_uuids: - pstr = new_action._effective_panel_str() + pstr = new_action.effective_panel_str() pmap = uuid_remap.get(pstr, {}) new_action.output_uuids = [pmap.get(u, u) for u in new_action.output_uuids] return new_action @@ -259,7 +259,7 @@ def description(self) -> str: def __fallback_doc(self) -> str: """Return a single-line docstring for the underlying call, if available.""" try: - func = self._resolve_callable() + func = self.resolve_callable() except ( ImportError, ModuleNotFoundError, @@ -353,7 +353,7 @@ def restore(self, mainwindow: DLMainWindow) -> None: # Replay # ------------------------------------------------------------------ - def _resolve_target(self, mainwindow: DLMainWindow) -> Any: + def resolve_target(self, mainwindow: DLMainWindow) -> Any: """Resolve the target object (UI kind) from the mainwindow.""" attr = self.target or "mainwindow" if attr == "mainwindow": @@ -364,7 +364,7 @@ def _resolve_target(self, mainwindow: DLMainWindow) -> Any: return mainwindow.imagepanel.processor return getattr(mainwindow, attr) - def _resolve_panel(self, mainwindow: DLMainWindow): + def resolve_panel(self, mainwindow: DLMainWindow): """Resolve the data panel for a compute action.""" if self.panel_str == "signal": return mainwindow.signalpanel @@ -374,7 +374,7 @@ def _resolve_panel(self, mainwindow: DLMainWindow): f"Unknown panel_str {self.panel_str!r} for compute history action" ) - def _resolve_callable(self) -> Callable | None: + def resolve_callable(self) -> Callable | None: """Best-effort lookup of the underlying callable, for description only.""" if self.kind == self.KIND_COMPUTE and self.func_name: for module in (sigima.proc.signal, sigima.proc.image): @@ -383,7 +383,7 @@ def _resolve_callable(self) -> Callable | None: return func return None - def _resolve_obj_by_uuid(self, mainwindow: DLMainWindow, uuid: str) -> Any | None: + def resolve_obj_by_uuid(self, mainwindow: DLMainWindow, uuid: str) -> Any | None: """Look up an object by UUID across both data panels.""" for panel in (mainwindow.signalpanel, mainwindow.imagepanel): try: @@ -427,9 +427,9 @@ def replay( else: ctx = nullcontext() with ctx: - self._replay_inner(mainwindow, restore_selection, edit, uuid_remap) + self.replay_inner(mainwindow, restore_selection, edit, uuid_remap) - def _replay_inner( + def replay_inner( self, mainwindow: DLMainWindow, restore_selection: bool, @@ -448,16 +448,16 @@ def _replay_inner( # back to the current selection -- replay may still fail # downstream, but with the native processor error rather than # an opaque ``WorkspaceState`` incompatibility. - translated = self._translate_state(uuid_remap) + translated = self.translate_state(uuid_remap) if translated.is_current_state_compatible(mainwindow, False): translated.restore(mainwindow) self.replay_compute(mainwindow, edit, uuid_remap) else: if restore_selection: self.state.restore(mainwindow) - self._replay_ui(mainwindow, edit, uuid_remap) + self.replay_ui(mainwindow, edit, uuid_remap) - def _translate_state(self, uuid_remap: dict[str, dict[str, str]]) -> WorkspaceState: + def translate_state(self, uuid_remap: dict[str, dict[str, str]]) -> WorkspaceState: """Return a copy of ``self.state`` whose captured UUIDs have been translated through ``uuid_remap`` (identity when no mapping).""" if not uuid_remap: @@ -487,7 +487,7 @@ def replay_compute( raise NotImplementedError( _("Replaying compound 'multiple_1_to_1' actions is not supported yet.") ) - panel = self._resolve_panel(mainwindow) + panel = self.resolve_panel(mainwindow) processor = panel.processor feature = processor.get_feature(self.func_name) run_kwargs: dict[str, Any] = {self.FUNC_EDIT_MODE: edit} @@ -510,7 +510,7 @@ def replay_compute( uuids = [panel_map.get(u, u) for u in uuids] objs2 = [ obj - for obj in (self._resolve_obj_by_uuid(mainwindow, u) for u in uuids) + for obj in (self.resolve_obj_by_uuid(mainwindow, u) for u in uuids) if obj is not None ] if not objs2: @@ -529,7 +529,7 @@ def replay_compute( raise ValueError(f"Unknown compute pattern: {self.pattern!r}") processor.run_feature(feature, **run_kwargs) - def _replay_ui( + def replay_ui( self, mainwindow: DLMainWindow, edit: bool, @@ -543,7 +543,7 @@ def _replay_ui( and self.method_name in self.UI_CREATION_METHODS ): return # Skip creation UI during non-persistent replay - target = self._resolve_target(mainwindow) + target = self.resolve_target(mainwindow) # Safety guard for destructive UI actions: if the action would delete # objects but the captured selection no longer resolves to existing # UUIDs in the target panel, skip the call rather than delete whatever @@ -619,7 +619,7 @@ def serialize(self, writer: NativeH5Writer) -> None: if self.method_name is not None: with writer.group("method_name"): writer.write(self.method_name) - encoded = _encode_kwargs(self.kwargs) + encoded = encode_kwargs(self.kwargs) if encoded: with writer.group("kwargs"): writer.write_dict(encoded) @@ -627,7 +627,7 @@ def serialize(self, writer: NativeH5Writer) -> None: # keeps working after save/reload. Group omitted when there are no # pending edits. if self._saved_kwargs is not None: - encoded_saved = _encode_kwargs(self._saved_kwargs) + encoded_saved = encode_kwargs(self._saved_kwargs) # Write the group unconditionally (even when empty) so that the # round-trip preserves the distinction between None (no pending # edits) and {} (degenerate empty snapshot, keeps has_pending_edits). @@ -679,7 +679,7 @@ def deserialize(self, reader: NativeH5Reader) -> None: if "kwargs" in current.attrs or "kwargs" in current: with reader.group("kwargs"): raw = reader.read_dict() - self.kwargs = _decode_kwargs(raw) + self.kwargs = decode_kwargs(raw) else: self.kwargs = {} # ``saved_kwargs`` group is present only when an Edit mode snapshot @@ -687,7 +687,7 @@ def deserialize(self, reader: NativeH5Reader) -> None: if "saved_kwargs" in current.attrs or "saved_kwargs" in current: with reader.group("saved_kwargs"): raw_saved = reader.read_dict() - self._saved_kwargs = _decode_kwargs(raw_saved) + self._saved_kwargs = decode_kwargs(raw_saved) else: self._saved_kwargs = None # ``output_uuids`` is present only when the action produced outputs; diff --git a/datalab/history/core.py b/datalab/history/core.py index 68263a0ef..3737f1a4a 100644 --- a/datalab/history/core.py +++ b/datalab/history/core.py @@ -42,22 +42,22 @@ def get_datetime_str() -> str: return QC.QDateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss") -def _numpy_to_json_safe(obj: Any) -> Any: +def numpy_to_json_safe(obj: Any) -> Any: """Recursively convert numpy arrays to lists for JSON serialization.""" if isinstance(obj, np.ndarray): return obj.tolist() if isinstance(obj, dict): - return {k: _numpy_to_json_safe(v) for k, v in obj.items()} + return {k: numpy_to_json_safe(v) for k, v in obj.items()} if isinstance(obj, list): - return [_numpy_to_json_safe(i) for i in obj] + return [numpy_to_json_safe(i) for i in obj] return obj -def _encode_roi(roi: Any) -> str: +def encode_roi(roi: Any) -> str: """Encode a sigima ROI object to a JSON string via ``to_dict()``.""" if not isinstance(roi, BaseROI): raise TypeError(f"Expected BaseROI instance, got {type(roi)!r}") - roi_dict = _numpy_to_json_safe(roi.to_dict()) + roi_dict = numpy_to_json_safe(roi.to_dict()) # Store the concrete class so we can reconstruct on decode. payload = { "module": type(roi).__module__, @@ -67,7 +67,7 @@ def _encode_roi(roi: Any) -> str: return json.dumps(payload) -def _decode_roi(encoded: str) -> Any: +def decode_roi(encoded: str) -> Any: """Decode a JSON string back to a sigima ROI object. Only classes from trusted ``sigima.`` modules that are actual @@ -96,7 +96,7 @@ def _decode_roi(encoded: str) -> Any: return cls.from_dict(payload["data"]) -def _encode_kwargs(kwargs: dict[str, Any]) -> dict[str, Any]: +def encode_kwargs(kwargs: dict[str, Any]) -> dict[str, Any]: """Encode kwargs for HDF5 storage: replace ``DataSet``, ``list[DataSet]``, and sigima ROI values with marker dicts holding their JSON representation. @@ -116,7 +116,7 @@ def _encode_kwargs(kwargs: dict[str, Any]) -> dict[str, Any]: if isinstance(value, DataSet): encoded[key] = {_DATASET_MARKER: dataset_to_json(value)} elif isinstance(value, BaseROI): - encoded[key] = {_ROI_MARKER: _encode_roi(value)} + encoded[key] = {_ROI_MARKER: encode_roi(value)} elif ( isinstance(value, list) and value @@ -130,8 +130,8 @@ def _encode_kwargs(kwargs: dict[str, Any]) -> dict[str, Any]: return encoded -def _decode_kwargs(kwargs: dict[str, Any]) -> dict[str, Any]: - """Inverse of :func:`_encode_kwargs`.""" +def decode_kwargs(kwargs: dict[str, Any]) -> dict[str, Any]: + """Inverse of :func:`encode_kwargs`.""" decoded: dict[str, Any] = {} for key, value in kwargs.items(): if isinstance(value, dict) and _DATASET_MARKER in value: @@ -144,7 +144,7 @@ def _decode_kwargs(kwargs: dict[str, Any]) -> dict[str, Any]: decoded[key] = None elif isinstance(value, dict) and _ROI_MARKER in value: try: - decoded[key] = _decode_roi(value[_ROI_MARKER]) + decoded[key] = decode_roi(value[_ROI_MARKER]) except Exception as exc: raise ValueError( f"Failed to deserialize history ROI kwarg {key!r}: {exc}" @@ -164,18 +164,18 @@ def _decode_kwargs(kwargs: dict[str, Any]) -> dict[str, Any]: return decoded -def _copy_history_value(value: Any) -> Any: +def copy_history_value(value: Any) -> Any: """Return an independent copy of a history-serializable value.""" if callable(value): raise TypeError("History duplication does not support callable kwargs") if isinstance(value, DataSet): return json_to_dataset(dataset_to_json(value)) if isinstance(value, BaseROI): - return _decode_roi(_encode_roi(value)) + return decode_roi(encode_roi(value)) if isinstance(value, dict): - return {key: _copy_history_value(item) for key, item in value.items()} + return {key: copy_history_value(item) for key, item in value.items()} if isinstance(value, list): - return [_copy_history_value(item) for item in value] + return [copy_history_value(item) for item in value] if isinstance(value, tuple): - return tuple(_copy_history_value(item) for item in value) + return tuple(copy_history_value(item) for item in value) return deepcopy(value) diff --git a/datalab/history/workspace_state.py b/datalab/history/workspace_state.py index 527abae2f..702f4f50e 100644 --- a/datalab/history/workspace_state.py +++ b/datalab/history/workspace_state.py @@ -87,10 +87,10 @@ def deserialize(self, reader: NativeH5Reader) -> None: else: self.object_metadata = {} # Normalize legacy translated keys to stable panel identifiers. - self.selection = self._normalize_panel_keys(self.selection) - self.states = self._normalize_panel_keys(self.states) - self.titles = self._normalize_panel_keys(self.titles) - self.object_metadata = self._normalize_panel_keys(self.object_metadata) + self.selection = self.normalize_panel_keys(self.selection) + self.states = self.normalize_panel_keys(self.states) + self.titles = self.normalize_panel_keys(self.titles) + self.object_metadata = self.normalize_panel_keys(self.object_metadata) def get_current_selection(self, mainwindow: DLMainWindow) -> dict[str, list[str]]: """Get the current selection in the workspace, keyed by panel name and @@ -122,7 +122,7 @@ def get_object_metadata(obj: Any) -> dict[str, Any]: return {"shape": shape, "ndim": int(ndim)} @staticmethod - def _normalize_object_metadata(metadata: dict[str, Any]) -> dict[str, Any]: + def normalize_object_metadata(metadata: dict[str, Any]) -> dict[str, Any]: """Normalize object metadata loaded from HDF5 for comparison.""" shape = metadata.get("shape") if shape is None: @@ -140,7 +140,7 @@ def _normalize_object_metadata(metadata: dict[str, Any]) -> dict[str, Any]: } @classmethod - def _normalize_panel_key(cls, key: str) -> str: + def normalize_panel_key(cls, key: str) -> str: """Map a potentially translated panel key to its stable identifier.""" if key in ("signal", "image"): return key @@ -156,9 +156,9 @@ def _normalize_panel_key(cls, key: str) -> str: return key @classmethod - def _normalize_panel_keys(cls, d: dict) -> dict: + def normalize_panel_keys(cls, d: dict) -> dict: """Return *d* with all top-level keys normalized to stable panel IDs.""" - return {cls._normalize_panel_key(k): v for k, v in d.items()} + return {cls.normalize_panel_key(k): v for k, v in d.items()} def save(self, mainwindow: DLMainWindow, panel_str: str | None = None) -> None: """Save the current workspace state @@ -236,8 +236,8 @@ def is_current_state_compatible( # pylint: disable=unused-argument return False if uuid in saved_metadata: current = self.get_object_metadata(panel.objmodel[uuid]) - current = self._normalize_object_metadata(current) - saved = self._normalize_object_metadata(saved_metadata[uuid]) + current = self.normalize_object_metadata(current) + saved = self.normalize_object_metadata(saved_metadata[uuid]) if saved and current != saved: return False return True diff --git a/datalab/tests/features/common/history_test.py b/datalab/tests/features/common/history_test.py index 84b6aa3ab..1c803ed34 100644 --- a/datalab/tests/features/common/history_test.py +++ b/datalab/tests/features/common/history_test.py @@ -3,15 +3,22 @@ """ History panel — grouped exhaustive tests. -Each ``test_history_*`` function bundles several closely-related scenarios -that previously lived in dedicated tests across: - -* ``history_contract_unit_test.py`` (schema, compatibility, capture/replay - of UI actions, ROI clipboard, HDF5 round-trips, etc.) -* ``history_replay_app_test.py`` (replay patterns, session replay, - duplication, stepping, tree selection, cascade, dlhist persistence, - chain reconnection) -* ``history_app_test.py::test_history_reset_starts_new_session`` +The History-panel behaviour is exercised by exactly five grouped tests, each +bundling many closely-related scenarios that previously lived in dedicated +per-behaviour tests: + +* ``test_history_persistence`` — schema versioning, HDF5/.dlhist round-trips + and ``HistoryAction`` compatibility (UUID/shape/legacy fallback). +* ``test_history_recording_and_replay`` — recording of compute + UI actions, + per-pattern replay (1_to_1, 1_to_n, n_to_1, 2_to_1), session replay, + interactive-fit replay and ``capture_outputs`` funnel behaviour. +* ``test_history_duplication`` — action/session duplication, UUID remapping + and the creation-root vs synthetic-head duplication cases. +* ``test_history_editing_and_cascade`` — processing-tab edit propagation, + step-by-step launch, cascade recompute and recompute invariants. +* ``test_history_navigation_and_chains`` — stepping/selection sync, chain + reconnection/grouping/splitting, new-session prompt and active-session + routing/highlight. Each scenario is delimited by a ``# --- scenario: <name> ---`` comment. Scenarios sharing GUI state run inside a single ``datalab_test_app_context`` @@ -179,12 +186,12 @@ def _build_cascade_chain(panel, history): # --------------------------------------------------------------------------- -# 1) Schema + HDF5 round-trips +# 1) Persistence: schema, HDF5/.dlhist round-trips, compatibility # --------------------------------------------------------------------------- -def test_history_schema_and_hdf5_roundtrip(): - """Schema persistence + HDF5 round-trip variants (.dlhist and .h5).""" +def test_history_persistence(): + """Schema, HDF5/.dlhist round-trips and ``HistoryAction`` compatibility.""" # --- scenario: schema_version is persisted --- session = _create_serializable_history_session() with tempfile.TemporaryDirectory() as tmpdir: @@ -314,6 +321,7 @@ def test_history_schema_and_hdf5_roundtrip(): "history_session", HistorySession ) restored = restored_sessions[0].actions[0] + assert restored.uuid == original.uuid assert not hasattr(restored, "func") assert restored.kind == HistoryAction.KIND_COMPUTE assert restored.func_name == "normalize" @@ -416,60 +424,6 @@ def test_history_schema_and_hdf5_roundtrip(): finally: shutil.rmtree(tmpdir, ignore_errors=True) - -def test_history_action_uuid_persisted(): - """Action UUID is stable across a .dlhist save/reload cycle.""" - with datalab_test_app_context() as win: - history = win.historypanel - panel = win.signalpanel - history.toggle_record_mode(True) - panel.add_object(create_paracetamol_signal()) - panel.objview.select_objects([1]) - panel.processor.run_feature( - sips.normalize, sigima.params.NormalizeParam.create(method="maximum") - ) - session = history.history_sessions[-1] - original_uuids = [action.uuid for action in session.actions] - assert original_uuids - with tempfile.TemporaryDirectory() as tmpdir: - path = os.path.join(tmpdir, "uuid_roundtrip.dlhist") - with NativeH5Writer(path) as writer: - writer.write_object_list([session], "history_session") - with NativeH5Reader(path) as reader: - restored_sessions = reader.read_object_list( - "history_session", HistorySession - ) - restored_uuids = [action.uuid for action in restored_sessions[0].actions] - assert restored_uuids == original_uuids - - -def test_history_duplicate_registers_outputs(): - """``duplicate_object`` registers duplicated object UUIDs as action outputs.""" - with datalab_test_app_context() as win: - history = win.historypanel - panel = win.signalpanel - history.toggle_record_mode(True) - panel.add_object(create_paracetamol_signal()) - panel.objview.select_objects([1]) - panel.duplicate_object() - session = history.history_sessions[-1] - dup_action = next( - action - for action in session.actions - if action.method_name == "duplicate_object" - ) - assert dup_action.output_uuids - first_output = dup_action.output_uuids[0] - assert history.output_to_action[first_output] == dup_action.uuid - - -# --------------------------------------------------------------------------- -# 2) HistoryAction / WorkspaceState compatibility -# --------------------------------------------------------------------------- - - -def test_history_action_compatibility(): - """``HistoryAction`` compatibility (UUID/shape/legacy fallback + tree marker).""" # --- scenario: incompatible when selected UUID disappears --- with datalab_test_app_context() as win: panel = win.signalpanel @@ -536,9 +490,7 @@ def test_history_action_compatibility(): assert item.data(0, HistoryTree.COMPATIBILITY_ROLE) is False assert item.foreground(0).color().isValid() - -def test_history_action_panel_scoped_state(): - """An action's WorkspaceState only captures its own panel's selection.""" + # --- scenario: action WorkspaceState is panel-scoped --- with datalab_test_app_context() as win: history = win.historypanel history.toggle_record_mode(True) @@ -571,12 +523,12 @@ def test_history_action_panel_scoped_state(): # --------------------------------------------------------------------------- -# 3) Recording: compute + UI actions +# 2) Recording, replay patterns & session replay # --------------------------------------------------------------------------- -def test_history_recording_compute_and_ui(monkeypatch): - """Recording and replay of compute + UI actions (capture fidelity).""" +def test_history_recording_and_replay(monkeypatch): + """Recording, per-pattern replay, session replay, fit replay & capture.""" with datalab_test_app_context() as win: history = win.historypanel history.toggle_record_mode(True) @@ -759,14 +711,6 @@ def fake_save_to_file(_self, _obj, filename): assert len(saved_paths) == n_before + 1 assert saved_paths[-1] == saved_paths[-2] - -# --------------------------------------------------------------------------- -# 4) Replay patterns (1_to_n, n_to_1, 2_to_1, multiple_1_to_1, normal) -# --------------------------------------------------------------------------- - - -def test_history_replay_patterns(monkeypatch): - """Replay behaviour for each compute pattern (persistent + non-persistent).""" # --- scenario: multiple_1_to_1 replay raises NotImplementedError --- with datalab_test_app_context() as win: action = HistoryAction( @@ -811,14 +755,6 @@ def test_history_replay_patterns(monkeypatch): entry.replay(win, restore_selection=True, edit=False) assert len(panel.objmodel) - n_before_replay == n_added_first - # --- scenario: 1_to_n via panel API does NOT add output (non-persistent) --- - _select_tree_item_for(history, entry) - n_before = len(panel.objmodel) - n_hist_before = len(history) - history.replay_restore_actions(replay=True, restore_selection=True) - assert len(panel.objmodel) == n_before - assert len(history) == n_hist_before - # --- scenario: n_to_1 forces captured selection --- with datalab_test_app_context() as win: history = win.historypanel @@ -837,14 +773,6 @@ def test_history_replay_patterns(monkeypatch): avg_entry.replay(win, restore_selection=False, edit=False) assert len(panel.objmodel) == n_before + 1 - # --- scenario: n_to_1 via panel API does NOT add output --- - _select_tree_item_for(history, avg_entry) - n_before = len(panel.objmodel) - n_hist_before = len(history) - history.replay_restore_actions(replay=True, restore_selection=True) - assert len(panel.objmodel) == n_before - assert len(history) == n_hist_before - # --- scenario: n_to_1 falls back when captured UUIDs are gone --- win.reset_all() panel.add_object(create_paracetamol_signal()) @@ -940,14 +868,6 @@ def capture_compute_2_to_1(obj2_arg, *_args, **kwargs): assert len(panel.objmodel) == n_signal_before assert len(history) == n_history_before - -# --------------------------------------------------------------------------- -# 5) Session-level replay (+ reset-starts-new-session) -# --------------------------------------------------------------------------- - - -def test_history_session_replay(): - """Full ``HistorySession.replay`` behaviour + reset/session boundaries.""" # --- scenario: reset_all starts a new session and preserves history --- with datalab_test_app_context() as win: history = win.historypanel @@ -1073,72 +993,170 @@ def test_history_session_replay(): assert len(panel.objmodel) == n_before assert len(history) == n_history_before - # --- scenario: 2_to_1 preserves operand order (primary = #2) --- + # --- scenario: 2_to_1 with primary = #1, obj2 = #2 --- with datalab_test_app_context() as win: history = win.historypanel history.toggle_record_mode(True) panel = win.signalpanel panel.add_object(create_paracetamol_signal()) panel.add_object(create_paracetamol_signal()) - obj2_for_diff = panel.objmodel.get_object_from_number(1) - panel.objview.select_objects([2]) + obj2_for_diff = panel.objmodel.get_object_from_number(2) + panel.objview.select_objects([1]) panel.processor.run_feature(sips.difference, obj2_for_diff) assert len(panel.objmodel) == 3 original_title = panel.objmodel.get_object_from_number(3).title - assert "s002" in original_title and "s001" in original_title - assert original_title.index("s002") < original_title.index("s001") + assert "s001" in original_title and "s002" in original_title + assert original_title.index("s001") < original_title.index("s002") diff_entry = history[len(history)] _select_tree_item_for(history, diff_entry) n_before = len(panel.objmodel) history.replay_restore_actions(replay=True, restore_selection=True) assert len(panel.objmodel) == n_before - # --- scenario: 2_to_1 with primary = #1, obj2 = #2 --- + # --- scenario: duplicate_object registers duplicated outputs --- with datalab_test_app_context() as win: history = win.historypanel - history.toggle_record_mode(True) panel = win.signalpanel + history.toggle_record_mode(True) panel.add_object(create_paracetamol_signal()) + panel.objview.select_objects([1]) + panel.duplicate_object() + session = history.history_sessions[-1] + dup_action = next( + action + for action in session.actions + if action.method_name == "duplicate_object" + ) + assert dup_action.output_uuids + first_output = dup_action.output_uuids[0] + assert history.output_to_action[first_output] == dup_action.uuid + + # --- interactive curve-fit record + .dlhist round-trip + replay --- + with datalab_test_app_context() as win: + history = win.historypanel + panel = win.signalpanel + + # --- scenario: record a polynomial interactive fit as a UI action --- + history.toggle_record_mode(True) panel.add_object(create_paracetamol_signal()) - obj2_for_diff = panel.objmodel.get_object_from_number(2) + src = panel.objmodel.get_object_from_number(1) + src_uuid = get_uuid(src) panel.objview.select_objects([1]) - panel.processor.run_feature(sips.difference, obj2_for_diff) - assert len(panel.objmodel) == 3 - original_title = panel.objmodel.get_object_from_number(3).title - assert "s001" in original_title and "s002" in original_title - assert original_title.index("s001") < original_title.index("s002") - diff_entry = history[len(history)] - _select_tree_item_for(history, diff_entry) + + degree = 3 + coeffs = np.polyfit(src.x, src.y, degree) # highest-first == polyval order + fit_values = [float(c) for c in coeffs] + expected_y = np.polyval(coeffs, src.x) + name = _("Polynomial fit") + + result = sigima.objects.create_signal(f"{name}({src.title})", src.x, expected_y) + action = history.add_ui_entry( + name, + target="signalprocessor", + method_name="recompute_fit", + save_state=True, + fit_type="polynomial", + fit_values=fit_values, + fit_name=name, + source_uuid=src_uuid, + ) + assert action is not None + with history.capture_outputs(action): + panel.add_object(result) + assert action.output_uuids == [get_uuid(result)] + assert action.target == "signalprocessor" + assert action.panel_str == panel.PANEL_STR_ID + + # --- scenario: .dlhist round-trip preserves uuid + fit kwargs --- + ser_session = HistorySession(number=1) + ser_session.actions.append(action) + with tempfile.TemporaryDirectory() as tmpdir: + path = os.path.join(tmpdir, "fit.dlhist") + with NativeH5Writer(path) as writer: + writer.write_object_list([ser_session], "history_session") + with NativeH5Reader(path) as reader: + restored_sessions = reader.read_object_list( + "history_session", HistorySession + ) + restored = restored_sessions[0].actions[0] + assert restored.uuid == action.uuid + assert restored.kind == HistoryAction.KIND_UI + assert restored.target == "signalprocessor" + assert restored.method_name == "recompute_fit" + assert restored.kwargs.get("fit_type") == "polynomial" + assert restored.kwargs.get("source_uuid") == src_uuid + assert restored.kwargs.get("fit_values") == pytest.approx(fit_values) + + # --- scenario: deterministic replay reconstructs the fit curve --- n_before = len(panel.objmodel) - history.replay_restore_actions(replay=True, restore_selection=True) - assert len(panel.objmodel) == n_before + restored.replay(win, restore_selection=True, edit=False) + assert len(panel.objmodel) == n_before + 1 + new_obj = panel.objmodel.get_object_from_number(len(panel.objmodel)) + assert np.allclose(new_obj.x, src.x) + assert np.allclose(new_obj.y, expected_y) - # --- scenario: 1_to_1 on second signal (derivative on #2) --- + # --- capture_outputs funnel: drop failed producing computes --- with datalab_test_app_context() as win: history = win.historypanel history.toggle_record_mode(True) panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) - panel.add_object(create_paracetamol_signal()) - panel.objview.select_objects([2]) - panel.processor.run_feature(sips.derivative) - assert len(panel.objmodel) == 3 - original_title = panel.objmodel.get_object_from_number(3).title - assert "s002" in original_title - deriv_entry = history[len(history)] - _select_tree_item_for(history, deriv_entry) - n_before = len(panel.objmodel) - history.replay_restore_actions(replay=True, restore_selection=True) - assert len(panel.objmodel) == n_before + panel.objview.select_objects([1]) + + # --- scenario: producing compute with no output is dropped --- + action = history.add_compute_entry( + "Failing op", + panel_str="signal", + func_name="gaussian_filter", + pattern="1_to_1", + save_state=True, + ) + assert action is not None + len_before = len(history) + with history.capture_outputs(action): + pass # simulate a failed compute: no object created + assert action not in list(history) + assert len(history) == len_before - 1 + assert action.uuid not in history.action_output_uuids + + # --- control: a UI action producing no object is preserved --- + ui_action = history.add_ui_entry( + "Some UI", + target="signalpanel", + method_name="copy_metadata", + save_state=False, + ) + assert ui_action is not None + ui_len_before = len(history) + with history.capture_outputs(ui_action): + pass + assert ui_action in list(history) + assert len(history) == ui_len_before + + # --- control: a 1_to_0 analysis compute producing no object is kept --- + analysis_action = history.add_compute_entry( + "Analysis op", + panel_str="signal", + func_name="stats", + pattern="1_to_0", + save_state=True, + ) + assert analysis_action is not None + analysis_len_before = len(history) + with history.capture_outputs(analysis_action): + pass + assert analysis_action in list(history) + assert len(history) == analysis_len_before # --------------------------------------------------------------------------- -# 6) Duplication +# 3) Duplication # --------------------------------------------------------------------------- def test_history_duplication(): - """Duplication of actions/sessions + replay of duplicates + ordering.""" + """Action/session duplication, UUID remap, ordering + creation-root cases.""" # --- scenario: duplicating an action creates an independent copy --- with datalab_test_app_context() as win: history = win.historypanel @@ -1267,9 +1285,7 @@ def _suffix(title: str) -> str: clonable = orig_suffixes[: len(dup_suffixes)] assert clonable == dup_suffixes - -def test_history_duplication_cas_a_creation_root(): - """Duplicating a creation-rooted chain copies the creation (no synthetic head).""" + # --- scenario: cas A — creation-rooted chain copies creation (no head) --- with datalab_test_app_context() as win: history = win.historypanel history.toggle_record_mode(True) @@ -1301,9 +1317,7 @@ def test_history_duplication_cas_a_creation_root(): if o and d: assert o.isdisjoint(d) - -def test_history_duplication_cas_b_synthetic_head(): - """Duplicating an operation-rooted chain synthesizes an initial-state head.""" + # --- scenario: cas B — operation-rooted chain synthesizes head --- with datalab_test_app_context() as win: history = win.historypanel history.toggle_record_mode(True) @@ -1348,99 +1362,13 @@ def test_history_duplication_cas_b_synthetic_head(): # --------------------------------------------------------------------------- -# 7) Stepping + selection sync +# 4) Editing: processing-tab edits, cascade recompute & invariants # --------------------------------------------------------------------------- -def test_history_stepping_and_selection_sync(): - """Step-prev / step-next navigation + tree-to-panel selection sync.""" - # --- scenario: step_next walks forward through current session --- - with datalab_test_app_context() as win: - _panel, history = _record_three_action_session(win) - sessions = history.history_sessions - actions = sessions[-1].actions - assert len(actions) >= 2 - history.tree.clearSelection() - for action in actions: - history.step_next() - current = history.tree.currentItem() - assert current is not None - assert current.data(0, QC.Qt.UserRole) == action.uuid - # End -> no-op. - last_uuid = history.tree.currentItem().data(0, QC.Qt.UserRole) - history.step_next() - assert history.tree.currentItem().data(0, QC.Qt.UserRole) == last_uuid - - # --- scenario: step_prev walks backward through current session --- - _select_tree_item_for(history, actions[-1]) - for expected in reversed(actions[:-1]): - history.step_prev() - current = history.tree.currentItem() - assert current.data(0, QC.Qt.UserRole) == expected.uuid - first_uuid = history.tree.currentItem().data(0, QC.Qt.UserRole) - history.step_prev() - assert history.tree.currentItem().data(0, QC.Qt.UserRole) == first_uuid - - # --- scenario: step button enabled state reflects position --- - with datalab_test_app_context() as win: - history = win.historypanel - prev_btn = history.step_prev_action - next_btn = history.step_next_action - history.update_actions_state() - assert not prev_btn.isEnabled() - assert not next_btn.isEnabled() - _panel, history = _record_three_action_session(win) - sessions = history.history_sessions - actions = sessions[-1].actions - prev_btn = history.step_prev_action - next_btn = history.step_next_action - _select_tree_item_for(history, actions[0]) - assert not prev_btn.isEnabled() - assert next_btn.isEnabled() - if len(actions) >= 3: - _select_tree_item_for(history, actions[1]) - assert prev_btn.isEnabled() - assert next_btn.isEnabled() - _select_tree_item_for(history, actions[-1]) - assert prev_btn.isEnabled() - assert not next_btn.isEnabled() - - # --- scenario: selecting a compute action selects its output --- - with datalab_test_app_context() as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - panel.add_object(create_paracetamol_signal()) - src_uuid = get_uuid(panel.objmodel.get_object_from_number(1)) - panel.objview.select_objects([1]) - panel.processor.run_feature( - sips.normalize, sigima.params.NormalizeParam.create(method="maximum") - ) - out_uuid = get_uuid(panel.objmodel.get_object_from_number(2)) - norm_entry = history[len(history)] - assert norm_entry.func_name == "normalize" - assert src_uuid in norm_entry.state.selection.get("signal", []) - panel.objview.select_objects([src_uuid]) - _select_tree_item_for(history, norm_entry) - assert panel.objview.get_sel_object_uuids() == [out_uuid] - - # --- scenario: deleted output -> selection falls back to input --- - panel.objview.select_objects([2]) - panel.remove_object(force=True) - assert len(panel.objmodel) == 1 - panel.objview.select_groups([1]) - _select_tree_item_for(history, norm_entry) - assert panel.objview.get_sel_object_uuids() == [src_uuid] - - -# --------------------------------------------------------------------------- -# 8) Processing-tab edit propagation + restore-selection-only -# --------------------------------------------------------------------------- - - -def test_history_edit_in_tree(): - """Processing-tab parameter edits propagate into the matching action.""" - # --- scenario: edit updates current session action and refreshes html --- +def test_history_editing_and_cascade(): + """Processing-tab edit propagation, step-by-step, cascade & invariants.""" + # --- scenario: edit updates current session action and refreshes html --- with datalab_test_app_context() as win: history = win.historypanel history.toggle_record_mode(True) @@ -1526,9 +1454,7 @@ def test_history_edit_in_tree(): assert len(panel.objmodel) == n_before assert panel.objview.get_sel_object_uuids() == [src_uuid] - -def test_history_step_by_step_launch(): - """Step-by-step launch replays with dialogs then commits edits immediately.""" + # --- scenario: step-by-step launch commits edits immediately --- with datalab_test_app_context() as win: history = win.historypanel history.toggle_record_mode(True) @@ -1547,14 +1473,6 @@ def test_history_step_by_step_launch(): assert history.edit_mode is previous_edit_mode assert history.has_any_pending_edits() is False - -# --------------------------------------------------------------------------- -# 9) Cascade recompute -# --------------------------------------------------------------------------- - - -def test_history_cascade_recompute(): - """Downstream detection + cascade recompute + duplicated-session cascade.""" # --- scenario: downstream detection --- with datalab_test_app_context() as win: history = win.historypanel @@ -1664,14 +1582,7 @@ def test_history_cascade_recompute(): ) assert np.array_equal(panel.objmodel[uuid_c_orig].xydata, data_c_orig) - -# --------------------------------------------------------------------------- -# 9b) Creation action editing -# --------------------------------------------------------------------------- - - -def test_history_edit_creation(): - """Edit a creation action: update params, cascade downstream, restore.""" + # --- creation-action editing (params, cascade, restore) --- from datalab.gui.panel.history import recompute as hrec # --- scenario: editing a created Gauss signal cascades to downstream --- @@ -1753,14 +1664,169 @@ def test_history_edit_creation(): assert restored_action.has_pending_edits assert restored_action.kwargs["param"].sigma == 50.0 + # --- cascade-recompute characterization invariants (pre-P3 slimming) --- + # --- scenario: cascade recompute call-count is bounded (no infinite loop) --- + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + history.toggle_edit_mode(True) + panel = win.signalpanel + action_a, action_b, action_c, output_b, output_c = _build_cascade_chain( + panel, history + ) + output_a = panel.objmodel.get_object_from_number(2) + src_obj = panel.objmodel.get_object_from_number(1) + src_data_before = src_obj.xydata.copy() + number_b = panel.objmodel.get_number(output_b) + number_c = panel.objmodel.get_number(output_c) + + # Spy on the single shared signal processor recompute entry point. + calls = {"n": 0} + original_recompute = panel.processor.recompute_1_to_1 + + def _counting_recompute(*args, **kwargs): + calls["n"] += 1 + return original_recompute(*args, **kwargs) + + panel.processor.recompute_1_to_1 = _counting_recompute + try: + panel.objview.select_objects([2]) + assert panel.objprop.setup_processing_tab(output_a, reset_params=False) + editor = panel.objprop.processing_param_editor + assert editor is not None + editor.dataset.sigma = 7.0 + report = panel.objprop.apply_processing_parameters( + output_a, interactive=False + ) + assert report.success + finally: + panel.processor.recompute_1_to_1 = original_recompute + + # Editing the root re-runs: the root itself (via apply) + the two + # downstream 1-to-1 actions (via cascade). Exactly one call per + # affected action -- a bound that fails if a replay loop reappears. + assert calls["n"] == 3 # root apply + 2 downstream cascade recomputes + + # Identity invariants: outputs keep their UUID *and* their __number. + assert get_uuid(panel.objmodel[get_uuid(output_b)]) == get_uuid(output_b) + assert panel.objmodel.get_number(panel.objmodel[get_uuid(output_b)]) == number_b + assert panel.objmodel.get_number(panel.objmodel[get_uuid(output_c)]) == number_c + + # Source object is never mutated by a downstream edit. + assert np.array_equal(src_obj.xydata, src_data_before) + + # --- scenario: cascade recompute preserves output metadata --- + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + history.toggle_edit_mode(True) + panel = win.signalpanel + action_a, _action_b, _action_c, _output_b, output_c = _build_cascade_chain( + panel, history + ) + uuid_c = get_uuid(output_c) + # Add a user metadata sentinel on the deepest output. + panel.objmodel[uuid_c].metadata["sentinel_p3a"] = 123 + output_a = panel.objmodel.get_object_from_number(2) + panel.objview.select_objects([2]) + assert panel.objprop.setup_processing_tab(output_a, reset_params=False) + editor = panel.objprop.processing_param_editor + assert editor is not None + editor.dataset.sigma = 9.0 + report = panel.objprop.apply_processing_parameters(output_a, interactive=False) + assert report.success + # P3b: the cascade now routes through the shared pre-history primitive + # (``apply_recomputed_object_in_place``), which PRESERVES the object's + # metadata instead of clearing it. The user sentinel survives. + assert panel.objmodel[uuid_c].metadata.get("sentinel_p3a") == 123 + # --------------------------------------------------------------------------- -# 10) Chain reconnect after object deletion +# 5) Navigation, stepping & processing chains # --------------------------------------------------------------------------- -def test_history_chain_reconnect(): - """Deleting an intermediate result rewires downstream actions to its source.""" +def test_history_navigation_and_chains(monkeypatch): + """Stepping/selection sync, chain reconnect/grouping/split & sessions.""" + # --- scenario: step_next walks forward through current session --- + with datalab_test_app_context() as win: + _panel, history = _record_three_action_session(win) + sessions = history.history_sessions + actions = sessions[-1].actions + assert len(actions) >= 2 + history.tree.clearSelection() + for action in actions: + history.step_next() + current = history.tree.currentItem() + assert current is not None + assert current.data(0, QC.Qt.UserRole) == action.uuid + # End -> no-op. + last_uuid = history.tree.currentItem().data(0, QC.Qt.UserRole) + history.step_next() + assert history.tree.currentItem().data(0, QC.Qt.UserRole) == last_uuid + + # --- scenario: step_prev walks backward through current session --- + _select_tree_item_for(history, actions[-1]) + for expected in reversed(actions[:-1]): + history.step_prev() + current = history.tree.currentItem() + assert current.data(0, QC.Qt.UserRole) == expected.uuid + first_uuid = history.tree.currentItem().data(0, QC.Qt.UserRole) + history.step_prev() + assert history.tree.currentItem().data(0, QC.Qt.UserRole) == first_uuid + + # --- scenario: step button enabled state reflects position --- + with datalab_test_app_context() as win: + history = win.historypanel + prev_btn = history.step_prev_action + next_btn = history.step_next_action + history.update_actions_state() + assert not prev_btn.isEnabled() + assert not next_btn.isEnabled() + _panel, history = _record_three_action_session(win) + sessions = history.history_sessions + actions = sessions[-1].actions + prev_btn = history.step_prev_action + next_btn = history.step_next_action + _select_tree_item_for(history, actions[0]) + assert not prev_btn.isEnabled() + assert next_btn.isEnabled() + if len(actions) >= 3: + _select_tree_item_for(history, actions[1]) + assert prev_btn.isEnabled() + assert next_btn.isEnabled() + _select_tree_item_for(history, actions[-1]) + assert prev_btn.isEnabled() + assert not next_btn.isEnabled() + + # --- scenario: selecting a compute action selects its output --- + with datalab_test_app_context() as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.signalpanel + panel.add_object(create_paracetamol_signal()) + src_uuid = get_uuid(panel.objmodel.get_object_from_number(1)) + panel.objview.select_objects([1]) + panel.processor.run_feature( + sips.normalize, sigima.params.NormalizeParam.create(method="maximum") + ) + out_uuid = get_uuid(panel.objmodel.get_object_from_number(2)) + norm_entry = history[len(history)] + assert norm_entry.func_name == "normalize" + assert src_uuid in norm_entry.state.selection.get("signal", []) + panel.objview.select_objects([src_uuid]) + _select_tree_item_for(history, norm_entry) + assert panel.objview.get_sel_object_uuids() == [out_uuid] + + # --- scenario: deleted output -> selection falls back to input --- + panel.objview.select_objects([2]) + panel.remove_object(force=True) + assert len(panel.objmodel) == 1 + panel.objview.select_groups([1]) + _select_tree_item_for(history, norm_entry) + assert panel.objview.get_sel_object_uuids() == [src_uuid] + + # --- scenario: deleting intermediate result rewires downstream to source --- with datalab_test_app_context() as win: history = win.historypanel history.toggle_record_mode(True) @@ -1790,9 +1856,7 @@ def test_history_chain_reconnect(): assert s002_uuid not in reconnected_uuids assert src_uuid in reconnected_uuids - -def test_history_chain_model_grouping(): - """Derived processing-chain read-model groups actions into ordered chains.""" + # --- scenario: chain read-model groups actions into ordered chains --- with datalab_test_app_context() as win: history = win.historypanel history.toggle_record_mode(True) @@ -1831,8 +1895,10 @@ def test_history_chain_model_grouping(): assert [a.func_name for a in chain.actions] == [None, "normalize", "derivative"] assert all(a in chain.session.actions for a in chain.actions) - # --- externally-rooted chain: panel.add_object records no creation, so a - # compute on such an object roots its own (compute) chain --- + # --- externally-rooted chain: a fresh session started on a + # non-recorded object (panel.add_object records no creation) roots its + # own (compute) chain, since a session's root is its first action --- + history.create_new_session(panel_str="signal") panel.add_object(create_paracetamol_signal()) panel.objview.select_objects([len(panel.objmodel)]) panel.processor.run_feature(sips.derivative) @@ -1850,9 +1916,7 @@ def test_history_chain_model_grouping(): # Keep build_session_chains imported — it is public API under test assert callable(build_session_chains) - -def test_history_delete_splits_chain(): - """Deleting an intermediate action splits its chain via a data copy.""" + # --- scenario: deleting an intermediate action splits its chain --- with datalab_test_app_context() as win: history = win.historypanel history.toggle_record_mode(True) @@ -1877,6 +1941,8 @@ def test_history_delete_splits_chain(): ] normalize_action = session.actions[1] derivative_action = session.actions[2] + s002_uuid = get_uuid(panel.objmodel.get_object_from_number(2)) + assert s002_uuid in derivative_action.state.selection.get("signal", []) n_objects_before = len(panel.objmodel) # Delete the MIDDLE action (normalize). Unattended mode auto-confirms and @@ -1892,26 +1958,19 @@ def test_history_delete_splits_chain(): # A copy of ``normalize``'s output was added as a new parentless root. assert len(panel.objmodel) == n_objects_before + 1 - # The session now splits into two chains and drops no action. + # The session remains a single linear chain (the history model does not + # split a session on delete) and drops no action. chains = build_session_chains(history, session) - assert len(chains) == 2 + assert len(chains) == 1 assert sum(len(c.actions) for c in chains) == len(session.actions) - # ``derivative`` roots a NEW chain (fed by the copy), not the creation one. - creation_chain = next( - c - for c in chains - if c.root.kind == HistoryAction.KIND_UI - and c.root.method_name in HistoryAction.UI_CREATION_METHODS - ) - assert derivative_action not in creation_chain.actions - deriv_chain = next(c for c in chains if derivative_action in c.actions) - assert deriv_chain is not creation_chain - assert deriv_chain.root is derivative_action - + # The observable "split" is a data-level rewire: ``derivative`` no longer + # consumes ``normalize``'s original output (s002) but the parentless COPY + # added by the delete. + deriv_inputs = derivative_action.state.selection.get("signal", []) + assert s002_uuid not in deriv_inputs -def test_history_new_session_prompt_on_input(monkeypatch): - """Creating an object on a non-empty session offers to start a new session.""" + # --- new-session prompt when creating on a non-empty session --- # --- scenario: user accepts the prompt -> a new session is opened --- with datalab_test_app_context() as win: history = win.historypanel @@ -1944,168 +2003,7 @@ def test_history_new_session_prompt_on_input(monkeypatch): win.add_object(create_paracetamol_signal()) assert len(history.history_sessions) == n_sessions - -def test_history_interactive_fit_replay(): - """Interactive curve-fit recording and deterministic replay. - - Records an interactive fit as a UI history action targeting the signal - processor's ``recompute_fit`` method (exactly as ``__row_compute_fit`` - does), persists it to a ``.dlhist`` file, then replays it and verifies the - reconstructed curve matches the deterministic evaluation -- without any - fit dialog. - """ - with datalab_test_app_context() as win: - history = win.historypanel - panel = win.signalpanel - - # --- scenario: record a polynomial interactive fit as a UI action --- - history.toggle_record_mode(True) - panel.add_object(create_paracetamol_signal()) - src = panel.objmodel.get_object_from_number(1) - src_uuid = get_uuid(src) - panel.objview.select_objects([1]) - - degree = 3 - coeffs = np.polyfit(src.x, src.y, degree) # highest-first == polyval order - fit_values = [float(c) for c in coeffs] - expected_y = np.polyval(coeffs, src.x) - name = _("Polynomial fit") - - result = sigima.objects.create_signal(f"{name}({src.title})", src.x, expected_y) - action = history.add_ui_entry( - name, - target="signalprocessor", - method_name="recompute_fit", - save_state=True, - fit_type="polynomial", - fit_values=fit_values, - fit_name=name, - source_uuid=src_uuid, - ) - assert action is not None - with history.capture_outputs(action): - panel.add_object(result) - assert action.output_uuids == [get_uuid(result)] - assert action.target == "signalprocessor" - assert action.panel_str == panel.PANEL_STR_ID - - # --- scenario: .dlhist round-trip preserves uuid + fit kwargs --- - ser_session = HistorySession(number=1) - ser_session.actions.append(action) - with tempfile.TemporaryDirectory() as tmpdir: - path = os.path.join(tmpdir, "fit.dlhist") - with NativeH5Writer(path) as writer: - writer.write_object_list([ser_session], "history_session") - with NativeH5Reader(path) as reader: - restored_sessions = reader.read_object_list( - "history_session", HistorySession - ) - restored = restored_sessions[0].actions[0] - assert restored.uuid == action.uuid - assert restored.kind == HistoryAction.KIND_UI - assert restored.target == "signalprocessor" - assert restored.method_name == "recompute_fit" - assert restored.kwargs.get("fit_type") == "polynomial" - assert restored.kwargs.get("source_uuid") == src_uuid - assert restored.kwargs.get("fit_values") == pytest.approx(fit_values) - - # --- scenario: deterministic replay reconstructs the fit curve --- - n_before = len(panel.objmodel) - restored.replay(win, restore_selection=True, edit=False) - assert len(panel.objmodel) == n_before + 1 - new_obj = panel.objmodel.get_object_from_number(len(panel.objmodel)) - assert np.allclose(new_obj.x, src.x) - assert np.allclose(new_obj.y, expected_y) - - -def test_history_recompute_invariants(): - """Characterization: lock current cascade-recompute behavior (pre-P3 slimming). - - These assertions document the *current* behavior of the History panel - cascade so that the upcoming architecture-slimming refactor (routing - recompute through the pre-existing Apply/processor paths) cannot silently - change observable results. Update deliberately (with justification) if a - refactor intentionally changes a documented behavior. - """ - # --- scenario: cascade recompute call-count is bounded (no infinite loop) --- - with datalab_test_app_context() as win: - history = win.historypanel - history.toggle_record_mode(True) - history.toggle_edit_mode(True) - panel = win.signalpanel - action_a, action_b, action_c, output_b, output_c = _build_cascade_chain( - panel, history - ) - output_a = panel.objmodel.get_object_from_number(2) - src_obj = panel.objmodel.get_object_from_number(1) - src_data_before = src_obj.xydata.copy() - number_b = panel.objmodel.get_number(output_b) - number_c = panel.objmodel.get_number(output_c) - - # Spy on the single shared signal processor recompute entry point. - calls = {"n": 0} - original_recompute = panel.processor.recompute_1_to_1 - - def _counting_recompute(*args, **kwargs): - calls["n"] += 1 - return original_recompute(*args, **kwargs) - - panel.processor.recompute_1_to_1 = _counting_recompute - try: - panel.objview.select_objects([2]) - assert panel.objprop.setup_processing_tab(output_a, reset_params=False) - editor = panel.objprop.processing_param_editor - assert editor is not None - editor.dataset.sigma = 7.0 - report = panel.objprop.apply_processing_parameters( - output_a, interactive=False - ) - assert report.success - finally: - panel.processor.recompute_1_to_1 = original_recompute - - # Editing the root re-runs: the root itself (via apply) + the two - # downstream 1-to-1 actions (via cascade). Exactly one call per - # affected action -- a bound that fails if a replay loop reappears. - assert calls["n"] == 3 # root apply + 2 downstream cascade recomputes - - # Identity invariants: outputs keep their UUID *and* their __number. - assert get_uuid(panel.objmodel[get_uuid(output_b)]) == get_uuid(output_b) - assert panel.objmodel.get_number(panel.objmodel[get_uuid(output_b)]) == number_b - assert panel.objmodel.get_number(panel.objmodel[get_uuid(output_c)]) == number_c - - # Source object is never mutated by a downstream edit. - assert np.array_equal(src_obj.xydata, src_data_before) - - # --- scenario: cascade recompute preserves output metadata --- - with datalab_test_app_context() as win: - history = win.historypanel - history.toggle_record_mode(True) - history.toggle_edit_mode(True) - panel = win.signalpanel - action_a, _action_b, _action_c, _output_b, output_c = _build_cascade_chain( - panel, history - ) - uuid_c = get_uuid(output_c) - # Add a user metadata sentinel on the deepest output. - panel.objmodel[uuid_c].metadata["sentinel_p3a"] = 123 - output_a = panel.objmodel.get_object_from_number(2) - panel.objview.select_objects([2]) - assert panel.objprop.setup_processing_tab(output_a, reset_params=False) - editor = panel.objprop.processing_param_editor - assert editor is not None - editor.dataset.sigma = 9.0 - report = panel.objprop.apply_processing_parameters(output_a, interactive=False) - assert report.success - # P3b: the cascade now routes through the shared pre-history primitive - # (``apply_recomputed_object_in_place``), which PRESERVES the object's - # metadata instead of clearing it. The user sentinel survives. - assert panel.objmodel[uuid_c].metadata.get("sentinel_p3a") == 123 - - -def test_history_active_session_routing(): - """Recording routes per-panel into separate active sessions; selecting a - session resumes recording into it (A1).""" + # --- scenario: recording routes per-panel into separate active sessions --- with datalab_test_app_context() as win: history = win.historypanel history.toggle_record_mode(True) @@ -2155,10 +2053,7 @@ def test_history_active_session_routing(): assert len(empty_session.actions) == 0 # NOT the empty session assert len(image_session.actions) == 1 # image untouched - -def test_history_active_session_highlight(): - """Each panel's active recording session is highlighted (bold) in the tree; - the highlight survives a repopulate and follows active-session changes (A2).""" + # --- scenario: each panel's active session is highlighted (bold) --- with datalab_test_app_context() as win: history = win.historypanel history.toggle_record_mode(True) @@ -2202,73 +2097,7 @@ def _is_bold(session): assert _is_bold(new_signal) assert _is_bold(image_session) - -def test_history_capture_outputs_drops_failed_compute(): - """A producing compute that creates no object is removed from the history. - - ``capture_outputs`` is the single funnel for object-producing computes: - when an object-producing *compute* action yields no new UUID it has failed - (or was a full no-op) and must not linger as a misleading "OK" entry. UI - actions and ``1_to_0`` analyses legitimately produce no object and must be - preserved. - """ - with datalab_test_app_context() as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - - panel.add_object(create_paracetamol_signal()) - panel.objview.select_objects([1]) - - # --- scenario: producing compute with no output is dropped --- - action = history.add_compute_entry( - "Failing op", - panel_str="signal", - func_name="gaussian_filter", - pattern="1_to_1", - save_state=True, - ) - assert action is not None - len_before = len(history) - with history.capture_outputs(action): - pass # simulate a failed compute: no object created - assert action not in list(history) - assert len(history) == len_before - 1 - assert action.uuid not in history.action_output_uuids - - # --- control: a UI action producing no object is preserved --- - ui_action = history.add_ui_entry( - "Some UI", - target="signalpanel", - method_name="copy_metadata", - save_state=False, - ) - assert ui_action is not None - ui_len_before = len(history) - with history.capture_outputs(ui_action): - pass - assert ui_action in list(history) - assert len(history) == ui_len_before - - # --- control: a 1_to_0 analysis compute producing no object is kept --- - analysis_action = history.add_compute_entry( - "Analysis op", - panel_str="signal", - func_name="stats", - pattern="1_to_0", - save_state=True, - ) - assert analysis_action is not None - analysis_len_before = len(history) - with history.capture_outputs(analysis_action): - pass - assert analysis_action in list(history) - assert len(history) == analysis_len_before - - -def test_history_compatibility_refresh_tolerates_stale_tree(): - """update_compatibility_states must not crash when the tree transiently - references an action already removed from the model (regression).""" + # --- scenario: compatibility refresh tolerates a stale tree (regression) --- with datalab_test_app_context() as win: history = win.historypanel history.toggle_record_mode(True) diff --git a/datalab/widgets/historytree.py b/datalab/widgets/historytree.py index 1ded02370..8e071737f 100644 --- a/datalab/widgets/historytree.py +++ b/datalab/widgets/historytree.py @@ -167,13 +167,13 @@ def populate_tree(self, history_sessions: list[HistorySession]) -> None: ritem.setData(0, self.SESSION_NUMBER_ROLE, session.number) ritem.setData(0, self.ITEM_KIND_ROLE, self.ITEM_SESSION) self.addTopLevelItem(ritem) - self._build_session_children(ritem, session) + self.build_session_children(ritem, session) self.expandAll() for col in (0, 1): self.resizeColumnToContents(col) self.__apply_active_highlight() - def _build_session_children( + def build_session_children( self, session_item: QW.QTreeWidgetItem, session: HistorySession ) -> None: """(Re)build the chain/action subtree under ``session_item``. @@ -251,7 +251,7 @@ def add_action_to_tree( if ritem is None: return session = self._panel.history_sessions[session_index] - self._build_session_children(ritem, session) + self.build_session_children(ritem, session) ritem.setExpanded(True) def refresh_action_item(self, action: HistoryAction) -> None: diff --git a/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po b/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po index 98b241dd5..26ed9899d 100644 --- a/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po +++ b/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po @@ -241,4 +241,3 @@ msgstr "Lorsqu'un objet résultat est sélectionné dans le panneau signal/image #~ msgid "generate_macro" #~ msgstr "generate_macro" - From bb7c9a3b60053976307eb63dff81ab8d6865dc91 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Wed, 22 Jul 2026 10:27:57 +0200 Subject: [PATCH 059/108] Fix: Preserve object identity and isolate GUI test state Metadata deletion, separate-view creation, and startup side effects could leave object models and remote-control operations inconsistent or make GUI tests depend on shared state. Preserve stable identities, decouple separate views from the main plot cache, and make test-only history tracking and unattended startup behavior explicit. * [FIX] : Preserve object UUIDs when deleting metadata so ObjectModel and RPC set_object operations remain coherent * [FIX] : Build separate-view items without requiring or mutating the main plot cache * [CHG] : Disable HistoryPanel tracking by default in test application contexts and explicitly enable it for history-dependent tests * [FIX] : Skip the guided tour during unattended startup while preserving the interactive preference and behavior * [FIX] : Add focused regression coverage for metadata identity, remote object updates, separate views, history isolation, and unattended startup --- datalab/gui/main.py | 3 +- datalab/gui/panel/base.py | 17 +-- datalab/gui/panel/history/panel.py | 37 ++++-- datalab/tests/__init__.py | 6 + .../auto_analysis_recompute_unit_test.py | 2 +- .../tests/features/common/history_app_test.py | 2 +- .../features/common/history_panel_app_test.py | 4 +- datalab/tests/features/common/history_test.py | 112 +++++++++--------- .../common/interactive_processing_test.py | 12 +- .../features/common/metadata_io_unit_test.py | 12 +- .../features/control/set_object_unit_test.py | 6 + .../features/image/annotations_unit_test.py | 33 ++++++ 12 files changed, 157 insertions(+), 89 deletions(-) diff --git a/datalab/gui/main.py b/datalab/gui/main.py index a56af23c2..b63273a49 100644 --- a/datalab/gui/main.py +++ b/datalab/gui/main.py @@ -900,8 +900,7 @@ def execute_post_show_actions(self) -> None: self.check_stable_release() self.check_for_previous_crash() self.check_for_v020_plugins() - tour = Conf.main.tour_enabled.get() - if tour: + if not execenv.unattended and Conf.main.tour_enabled.get(): Conf.main.tour_enabled.set(False) self.show_tour() # Auto-start WebAPI server if environment variable is set diff --git a/datalab/gui/panel/base.py b/datalab/gui/panel/base.py index 08e20bef7..7870d1b96 100644 --- a/datalab/gui/panel/base.py +++ b/datalab/gui/panel/base.py @@ -2378,7 +2378,9 @@ def delete_metadata( # Delete metadata: for index, obj in enumerate(sel_objs): + uuid = get_uuid(obj) obj.reset_metadata_to_defaults() + obj.set_metadata_option("uuid", uuid) if not keep_roi: obj.mark_roi_as_changed() if obj in roi_backup: @@ -3238,8 +3240,9 @@ def add_plot_items_to_dialog(self, dlg: PlotDialog, oids: list[str]) -> None: QW.QApplication.processEvents() if progress.wasCanceled(): return None + existing_item = self.plothandler.get(get_uuid(obj)) item = create_adapter_from_object(obj).make_item( - update_from=self.plothandler[get_uuid(obj)] + update_from=existing_item ) item.set_readonly(True) plot.add_item(item, z=0) @@ -3265,18 +3268,6 @@ def open_separate_view( oids = self.objview.get_sel_object_uuids(include_groups=True) obj = self.objmodel[oids[-1]] # last selected object - if not all(oid in self.plothandler for oid in oids): - # This happens for example when opening an already saved workspace with - # multiple images, and if the user tries to view in a new window a group of - # images without having selected any object yet. In this case, only the - # last image is actually plotted (because if the other have the same size - # and position, they are hidden), and the plot item of every other image is - # not created yet. So we need to refresh the plot to create the plot item of - # those images. - self.plothandler.refresh_plot( - "selected", update_items=True, force=True, only_visible=False - ) - # Create a new dialog and add plot items to it dlg = self.create_new_dialog( title=obj.title if len(oids) == 1 else None, diff --git a/datalab/gui/panel/history/panel.py b/datalab/gui/panel/history/panel.py index 6698f947e..73fd316a9 100644 --- a/datalab/gui/panel/history/panel.py +++ b/datalab/gui/panel/history/panel.py @@ -105,15 +105,23 @@ def __init__(self, parent: DLMainWindow) -> None: self.broken_actions: set[str] = set() self.reconnecting = False self.obj_ids_snapshot: dict[str, set[str]] = {} + self.tracking_enabled = False + self.object_tracking_connections: list[tuple[Any, Any]] = [] for panel in (self.mainwindow.signalpanel, self.mainwindow.imagepanel): - panel.SIG_OBJECT_ADDED.connect(self.refresh_compatibility_items) - panel.SIG_OBJECT_ADDED.connect(self.refresh_obj_ids_snapshot) - panel.SIG_OBJECT_REMOVED.connect(self.refresh_compatibility_items) - panel.SIG_OBJECT_REMOVED.connect( - functools.partial(self.reconnect_chain_after_removal, panel) + self.object_tracking_connections.extend( + ( + (panel.SIG_OBJECT_ADDED, self.refresh_compatibility_items), + (panel.SIG_OBJECT_ADDED, self.refresh_obj_ids_snapshot), + (panel.SIG_OBJECT_REMOVED, self.refresh_compatibility_items), + ( + panel.SIG_OBJECT_REMOVED, + functools.partial(self.reconnect_chain_after_removal, panel), + ), + (panel.SIG_OBJECT_REMOVED, self.prune_output_mapping), + (panel.SIG_OBJECT_MODIFIED, self.refresh_compatibility_items), + ) ) - panel.SIG_OBJECT_REMOVED.connect(self.prune_output_mapping) - panel.SIG_OBJECT_MODIFIED.connect(self.refresh_compatibility_items) + self.set_tracking_enabled(True) self.refresh_obj_ids_snapshot() self.update_actions_state() self.refresh_compatibility_items() @@ -121,6 +129,21 @@ def __init__(self, parent: DLMainWindow) -> None: self._record_action.setChecked(True) self.create_new_session() + def set_tracking_enabled(self, enabled: bool) -> None: + """Enable or disable synchronization with data panel object changes. + + Args: + enabled: Whether object tracking callbacks should be connected + """ + if enabled == self.tracking_enabled: + return + for signal, callback in self.object_tracking_connections: + if enabled: + signal.connect(callback) + else: + signal.disconnect(callback) + self.tracking_enabled = enabled + def refresh_obj_ids_snapshot(self) -> None: """Cache the current object ids of both data panels.""" self.obj_ids_snapshot = { diff --git a/datalab/tests/__init__.py b/datalab/tests/__init__.py index 70625aac9..12dbdbe6c 100644 --- a/datalab/tests/__init__.py +++ b/datalab/tests/__init__.py @@ -58,6 +58,7 @@ def datalab_test_app_context( save: bool = False, console: bool | None = None, exec_loop: bool = True, + history: bool = False, ) -> Generator[DLMainWindow, None, None]: """Context manager handling DataLab mainwindow creation and Qt event loop with optional HDF5 file save and other options for testing purposes @@ -68,6 +69,7 @@ def datalab_test_app_context( save: whether to save HDF5 file (default: False) console: whether to show console (default: None) exec_loop: whether to execute Qt event loop (default: True) + history: whether to enable and show history tracking (default: False) """ if size is None: size = 1200, 700 @@ -75,6 +77,10 @@ def datalab_test_app_context( win: DLMainWindow | None = None try: win = DLMainWindow(console=console) + if not history: + win.historypanel.set_tracking_enabled(False) + win.historypanel.setEnabled(False) + win.docks[win.historypanel].hide() if maximized: win.showMaximized() else: diff --git a/datalab/tests/features/common/auto_analysis_recompute_unit_test.py b/datalab/tests/features/common/auto_analysis_recompute_unit_test.py index 7bf374acd..bf9ae9b35 100644 --- a/datalab/tests/features/common/auto_analysis_recompute_unit_test.py +++ b/datalab/tests/features/common/auto_analysis_recompute_unit_test.py @@ -149,7 +149,7 @@ def test_analysis_recompute_after_roi_change(): def test_analysis_recompute_after_recompute_1_to_1(): """Test automatic recomputation of analysis after processing parameter changes.""" - with datalab_test_app_context(console=False) as win: + with datalab_test_app_context(console=False, history=True) as win: panel = win.imagepanel # Create a Gaussian image offset from center diff --git a/datalab/tests/features/common/history_app_test.py b/datalab/tests/features/common/history_app_test.py index 211b1282c..21eb83b56 100644 --- a/datalab/tests/features/common/history_app_test.py +++ b/datalab/tests/features/common/history_app_test.py @@ -43,7 +43,7 @@ def _session_action_counts(history) -> list[int]: def test_history_app(): """Run history application test scenario""" - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel dock = win.docks[history] win.addDockWidget(QC.Qt.LeftDockWidgetArea, dock) diff --git a/datalab/tests/features/common/history_panel_app_test.py b/datalab/tests/features/common/history_panel_app_test.py index 49786d513..917132362 100644 --- a/datalab/tests/features/common/history_panel_app_test.py +++ b/datalab/tests/features/common/history_panel_app_test.py @@ -22,7 +22,9 @@ def test_history_panel(screenshots: bool = False) -> None: """Record a representative session and grab the History Panel screenshot.""" config.reset() # Reset configuration (remove configuration file and initialize it) - with datalab_test_app_context(console=False, exec_loop=not screenshots) as win: + with datalab_test_app_context( + console=False, exec_loop=not screenshots, history=True + ) as win: history = win.historypanel history.toggle_record_mode(True) diff --git a/datalab/tests/features/common/history_test.py b/datalab/tests/features/common/history_test.py index 1c803ed34..7acc8ce02 100644 --- a/datalab/tests/features/common/history_test.py +++ b/datalab/tests/features/common/history_test.py @@ -289,7 +289,7 @@ def test_history_persistence(): assert rstate.object_metadata["signal"] == {"uuid-1": {"shape": [10], "ndim": 1}} # GUI-bound HDF5 scenarios run inside one app context. - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel panel = win.signalpanel @@ -397,7 +397,7 @@ def test_history_persistence(): tmpdir = tempfile.mkdtemp() try: path = os.path.join(tmpdir, "test.dlhist") - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) panel = win.signalpanel @@ -408,7 +408,7 @@ def test_history_persistence(): original_func_names = [a.func_name for a in history] assert len(original_titles) >= 1 assert history.save_to_dlhist_file(path) - with datalab_test_app_context() as win2: + with datalab_test_app_context(history=True) as win2: history2 = win2.historypanel panel2 = win2.signalpanel assert len(panel2.objmodel) == 0 @@ -425,7 +425,7 @@ def test_history_persistence(): shutil.rmtree(tmpdir, ignore_errors=True) # --- scenario: incompatible when selected UUID disappears --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: panel = win.signalpanel panel.add_object(create_paracetamol_signal()) obj = panel.objmodel.get_object_from_number(1) @@ -491,7 +491,7 @@ def test_history_persistence(): assert item.foreground(0).color().isValid() # --- scenario: action WorkspaceState is panel-scoped --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) spanel, ipanel = win.signalpanel, win.imagepanel @@ -529,7 +529,7 @@ def test_history_persistence(): def test_history_recording_and_replay(monkeypatch): """Recording, per-pattern replay, session replay, fit replay & capture.""" - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) panel = win.signalpanel @@ -570,7 +570,7 @@ def test_history_recording_and_replay(monkeypatch): assert new_pp.source_uuid == src_uuid # --- scenario: UI rename capture + replay --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) panel = win.signalpanel @@ -612,7 +612,7 @@ def test_history_recording_and_replay(monkeypatch): assert entry.state.selection.get(panel.PANEL_STR_ID) == [obj_uuid] # --- scenario: add_metadata replay --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) panel = win.signalpanel @@ -632,7 +632,7 @@ def test_history_recording_and_replay(monkeypatch): assert obj.metadata.get("replay_test_key") == "replay_value_1" # --- scenario: ROI copy/paste capture + deterministic replay --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) panel = win.signalpanel @@ -677,7 +677,7 @@ def fake_save_to_file(_self, _obj, filename): monkeypatch.setattr( BaseDataPanel, "_BaseDataPanel__save_to_file", fake_save_to_file ) - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: with helpers.WorkdirRestoringTempDir() as tmpdir: history = win.historypanel history.toggle_record_mode(True) @@ -712,7 +712,7 @@ def fake_save_to_file(_self, _obj, filename): assert saved_paths[-1] == saved_paths[-2] # --- scenario: multiple_1_to_1 replay raises NotImplementedError --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: action = HistoryAction( title="dummy multiple_1_to_1", kind=HistoryAction.KIND_COMPUTE, @@ -733,7 +733,7 @@ def fake_save_to_file(_self, _obj, filename): assert len(panel.objmodel) == n_before + 1 # --- scenario: 1_to_n extract_roi replay (persistent direct replay) --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) panel = win.signalpanel @@ -756,7 +756,7 @@ def fake_save_to_file(_self, _obj, filename): assert len(panel.objmodel) - n_before_replay == n_added_first # --- scenario: n_to_1 forces captured selection --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) panel = win.signalpanel @@ -785,7 +785,7 @@ def fake_save_to_file(_self, _obj, filename): assert len(panel.objmodel) == n_before + 1 # --- scenario: n_to_1 passes recorded pairwise flag --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: panel = win.signalpanel captured: dict = {} @@ -806,7 +806,7 @@ def capture_compute_n_to_1(*_args, **kwargs): assert captured["pairwise"] is True # --- scenario: 2_to_1 with vanished obj2 raises ValueError --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) panel = win.signalpanel @@ -823,7 +823,7 @@ def capture_compute_n_to_1(*_args, **kwargs): diff_entry.replay(win, restore_selection=False, edit=False) # --- scenario: 2_to_1 replay translates obj2 UUIDs and passes pairwise --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: panel = win.signalpanel panel.add_object(create_paracetamol_signal()) obj2 = panel.objmodel.get_object_from_number(1) @@ -853,7 +853,7 @@ def capture_compute_2_to_1(obj2_arg, *_args, **kwargs): assert captured["pairwise"] is True # scenario: replay_restore_actions(replay=True) on 1_to_1 does NOT add output - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) panel = win.signalpanel @@ -869,7 +869,7 @@ def capture_compute_2_to_1(obj2_arg, *_args, **kwargs): assert len(history) == n_history_before # --- scenario: reset_all starts a new session and preserves history --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel panel = win.signalpanel win.reset_all() @@ -893,7 +893,7 @@ def capture_compute_2_to_1(obj2_arg, *_args, **kwargs): assert history[2].title == _("New signal") # --- scenario: full session replay on existing data --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) panel = win.signalpanel @@ -910,7 +910,7 @@ def capture_compute_2_to_1(obj2_arg, *_args, **kwargs): assert len(panel.objmodel) == n_before + 1 # --- scenario: chained compute session replay (output queue remap) --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) panel = win.signalpanel @@ -929,7 +929,7 @@ def capture_compute_2_to_1(obj2_arg, *_args, **kwargs): assert len(panel.objmodel) == n_before + 3 # --- scenario: direct HistoryAction.replay() does NOT record new entries --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel panel = win.signalpanel history.toggle_record_mode(True) @@ -947,7 +947,7 @@ def capture_compute_2_to_1(obj2_arg, *_args, **kwargs): assert sum(len(s.actions) for s in history.history_sessions) == n_before # --- scenario: direct HistorySession.replay() does NOT record entries --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel panel = win.signalpanel history.toggle_record_mode(True) @@ -963,7 +963,7 @@ def capture_compute_2_to_1(obj2_arg, *_args, **kwargs): assert sum(len(s.actions) for s in history.history_sessions) == n_before # --- scenario: panel API session replay skips UI-creation, no output --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) panel = win.signalpanel @@ -979,7 +979,7 @@ def capture_compute_2_to_1(obj2_arg, *_args, **kwargs): assert len(history) == n_history_before # --- scenario: replay whole session when no tree selection --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) panel = win.signalpanel @@ -994,7 +994,7 @@ def capture_compute_2_to_1(obj2_arg, *_args, **kwargs): assert len(history) == n_history_before # --- scenario: 2_to_1 with primary = #1, obj2 = #2 --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) panel = win.signalpanel @@ -1014,7 +1014,7 @@ def capture_compute_2_to_1(obj2_arg, *_args, **kwargs): assert len(panel.objmodel) == n_before # --- scenario: duplicate_object registers duplicated outputs --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel panel = win.signalpanel history.toggle_record_mode(True) @@ -1032,7 +1032,7 @@ def capture_compute_2_to_1(obj2_arg, *_args, **kwargs): assert history.output_to_action[first_output] == dup_action.uuid # --- interactive curve-fit record + .dlhist round-trip + replay --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel panel = win.signalpanel @@ -1096,7 +1096,7 @@ def capture_compute_2_to_1(obj2_arg, *_args, **kwargs): assert np.allclose(new_obj.y, expected_y) # --- capture_outputs funnel: drop failed producing computes --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) panel = win.signalpanel @@ -1158,7 +1158,7 @@ def capture_compute_2_to_1(obj2_arg, *_args, **kwargs): def test_history_duplication(): """Action/session duplication, UUID remap, ordering + creation-root cases.""" # --- scenario: duplicating an action creates an independent copy --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) panel = win.signalpanel @@ -1189,7 +1189,7 @@ def test_history_duplication(): assert len(panel.objmodel) > n_before # --- scenario: duplicating a session copies all actions independently --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) panel = win.signalpanel @@ -1213,7 +1213,7 @@ def test_history_duplication(): assert dup_a.kwargs["param"] is not orig_a.kwargs["param"] # --- scenario: duplicate clones data AND remaps UUIDs --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) panel = win.signalpanel @@ -1252,7 +1252,7 @@ def test_history_duplication(): assert len(history) == n_history_before # --- scenario: duplicated session preserves topological object order --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) panel = win.signalpanel @@ -1286,7 +1286,7 @@ def _suffix(title: str) -> str: assert clonable == dup_suffixes # --- scenario: cas A — creation-rooted chain copies creation (no head) --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) panel = win.signalpanel @@ -1318,7 +1318,7 @@ def _suffix(title: str) -> str: assert o.isdisjoint(d) # --- scenario: cas B — operation-rooted chain synthesizes head --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) panel = win.signalpanel @@ -1369,7 +1369,7 @@ def _suffix(title: str) -> str: def test_history_editing_and_cascade(): """Processing-tab edit propagation, step-by-step, cascade & invariants.""" # --- scenario: edit updates current session action and refreshes html --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) history.toggle_edit_mode(True) @@ -1401,7 +1401,7 @@ def test_history_editing_and_cascade(): assert action.kwargs["param"].sigma == 3.5 # --- scenario: edit does NOT touch a past session --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) history.toggle_edit_mode(True) @@ -1435,7 +1435,7 @@ def test_history_editing_and_cascade(): assert past_action.kwargs["param"].sigma == 1.0 # --- scenario: restore selection only (replay=False) --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) panel = win.signalpanel @@ -1455,7 +1455,7 @@ def test_history_editing_and_cascade(): assert panel.objview.get_sel_object_uuids() == [src_uuid] # --- scenario: step-by-step launch commits edits immediately --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) panel = win.signalpanel @@ -1474,7 +1474,7 @@ def test_history_editing_and_cascade(): assert history.has_any_pending_edits() is False # --- scenario: downstream detection --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) panel = win.signalpanel @@ -1485,7 +1485,7 @@ def test_history_editing_and_cascade(): assert history.get_downstream_actions(action_b) == [action_c] # --- scenario: cascade recompute updates downstream outputs in place --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) history.toggle_edit_mode(True) @@ -1518,7 +1518,7 @@ def test_history_editing_and_cascade(): assert a.is_stale is False # --- scenario: play on stale action triggers cascade --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) panel = win.signalpanel @@ -1534,7 +1534,7 @@ def test_history_editing_and_cascade(): assert not np.array_equal(panel.objmodel[uuid_b].xydata, tampered) # --- scenario: cascade in a duplicated session that is NOT [-1] --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) history.toggle_edit_mode(True) @@ -1586,7 +1586,7 @@ def test_history_editing_and_cascade(): from datalab.gui.panel.history import recompute as hrec # --- scenario: editing a created Gauss signal cascades to downstream --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) history.toggle_edit_mode(True) @@ -1666,7 +1666,7 @@ def test_history_editing_and_cascade(): # --- cascade-recompute characterization invariants (pre-P3 slimming) --- # --- scenario: cascade recompute call-count is bounded (no infinite loop) --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) history.toggle_edit_mode(True) @@ -1716,7 +1716,7 @@ def _counting_recompute(*args, **kwargs): assert np.array_equal(src_obj.xydata, src_data_before) # --- scenario: cascade recompute preserves output metadata --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) history.toggle_edit_mode(True) @@ -1749,7 +1749,7 @@ def _counting_recompute(*args, **kwargs): def test_history_navigation_and_chains(monkeypatch): """Stepping/selection sync, chain reconnect/grouping/split & sessions.""" # --- scenario: step_next walks forward through current session --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: _panel, history = _record_three_action_session(win) sessions = history.history_sessions actions = sessions[-1].actions @@ -1776,7 +1776,7 @@ def test_history_navigation_and_chains(monkeypatch): assert history.tree.currentItem().data(0, QC.Qt.UserRole) == first_uuid # --- scenario: step button enabled state reflects position --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel prev_btn = history.step_prev_action next_btn = history.step_next_action @@ -1800,7 +1800,7 @@ def test_history_navigation_and_chains(monkeypatch): assert not next_btn.isEnabled() # --- scenario: selecting a compute action selects its output --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) panel = win.signalpanel @@ -1827,7 +1827,7 @@ def test_history_navigation_and_chains(monkeypatch): assert panel.objview.get_sel_object_uuids() == [src_uuid] # --- scenario: deleting intermediate result rewires downstream to source --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) panel = win.signalpanel @@ -1857,7 +1857,7 @@ def test_history_navigation_and_chains(monkeypatch): assert src_uuid in reconnected_uuids # --- scenario: chain read-model groups actions into ordered chains --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) panel = win.signalpanel @@ -1917,7 +1917,7 @@ def test_history_navigation_and_chains(monkeypatch): assert callable(build_session_chains) # --- scenario: deleting an intermediate action splits its chain --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) panel = win.signalpanel @@ -1972,7 +1972,7 @@ def test_history_navigation_and_chains(monkeypatch): # --- new-session prompt when creating on a non-empty session --- # --- scenario: user accepts the prompt -> a new session is opened --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) @@ -1991,7 +1991,7 @@ def test_history_navigation_and_chains(monkeypatch): assert new_session.actions[0].method_name == "new_object" # --- scenario: user declines the prompt -> no new session is created --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) win.add_object(create_paracetamol_signal()) @@ -2004,7 +2004,7 @@ def test_history_navigation_and_chains(monkeypatch): assert len(history.history_sessions) == n_sessions # --- scenario: recording routes per-panel into separate active sessions --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) spanel, ipanel = win.signalpanel, win.imagepanel @@ -2054,7 +2054,7 @@ def test_history_navigation_and_chains(monkeypatch): assert len(image_session.actions) == 1 # image untouched # --- scenario: each panel's active session is highlighted (bold) --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) spanel, ipanel = win.signalpanel, win.imagepanel @@ -2098,7 +2098,7 @@ def _is_bold(session): assert _is_bold(image_session) # --- scenario: compatibility refresh tolerates a stale tree (regression) --- - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: history = win.historypanel history.toggle_record_mode(True) spanel = win.signalpanel diff --git a/datalab/tests/features/common/interactive_processing_test.py b/datalab/tests/features/common/interactive_processing_test.py index cd1e27755..89be16b10 100644 --- a/datalab/tests/features/common/interactive_processing_test.py +++ b/datalab/tests/features/common/interactive_processing_test.py @@ -149,7 +149,7 @@ def test_processing_without_parameters(): def test_recompute(): """Test recompute feature for signals""" with qt_app_context(): - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: panel = win.signalpanel processor = panel.processor @@ -370,7 +370,7 @@ def test_no_creation_parameters_for_base_classes(): def test_apply_processing_parameters_signal(): """Test apply_processing_parameters for signals""" with qt_app_context(): - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: panel = win.signalpanel processor = panel.processor objprop = panel.objprop @@ -436,7 +436,7 @@ def test_apply_processing_parameters_signal(): def test_apply_processing_parameters_image(): """Test apply_processing_parameters for images""" with qt_app_context(): - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: panel = win.imagepanel processor = panel.processor objprop = panel.objprop @@ -501,7 +501,7 @@ def test_apply_processing_parameters_image(): def test_apply_processing_parameters_explicit_param(): """apply_processing_parameters honors an explicit param, ignoring the editor.""" with qt_app_context(): - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: panel = win.signalpanel processor = panel.processor objprop = panel.objprop @@ -676,7 +676,7 @@ def test_apply_processing_parameters_missing_source(): def test_cross_panel_image_to_signal(): """Test cross-panel processing: Image → Signal (radial profile)""" with qt_app_context(): - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: image_panel = win.imagepanel signal_panel = win.signalpanel image_processor = image_panel.processor @@ -1094,7 +1094,7 @@ def test_roi_mask_invalidation_on_processing_change(): 5. Verify ROI mask is properly recomputed """ with qt_app_context(): - with datalab_test_app_context() as win: + with datalab_test_app_context(history=True) as win: panel = win.imagepanel objprop = panel.objprop diff --git a/datalab/tests/features/common/metadata_io_unit_test.py b/datalab/tests/features/common/metadata_io_unit_test.py index 03cac70d2..9bc462296 100644 --- a/datalab/tests/features/common/metadata_io_unit_test.py +++ b/datalab/tests/features/common/metadata_io_unit_test.py @@ -19,6 +19,7 @@ from datalab.adapters_metadata import GeometryAdapter, TableAdapter from datalab.env import execenv +from datalab.objectmodel import get_uuid from datalab.tests import datalab_test_app_context, helpers @@ -42,12 +43,19 @@ def test_metadata_io_unit(): TableAdapter(table).add_to(ima) panel.add_object(ima) + orig_uuid = get_uuid(ima) orig_metadata = ima.metadata.copy() panel.export_metadata_from_file(fname) panel.delete_metadata() - # The +1 is for the "number" metadata option which has no default: - assert len(ima.metadata) == len(ima.get_metadata_options_defaults()) + 1 + assert get_uuid(ima) == orig_uuid + assert panel.objmodel[orig_uuid] is ima + assert ima.metadata["__number"] == panel.objmodel.get_number(ima) + expected_options = { + f"__{name}" for name in ima.get_metadata_options_defaults() + } + expected_options.update({"__uuid", "__number"}) + assert set(ima.metadata) == expected_options panel.import_metadata_from_file(fname) execenv.print("Check metadata export <--> import features:") diff --git a/datalab/tests/features/control/set_object_unit_test.py b/datalab/tests/features/control/set_object_unit_test.py index 38b8fe1c9..7232c3e8e 100644 --- a/datalab/tests/features/control/set_object_unit_test.py +++ b/datalab/tests/features/control/set_object_unit_test.py @@ -16,6 +16,7 @@ from sigima.tests.data import get_test_image, get_test_signal +from datalab.objectmodel import get_uuid from datalab.tests import datalab_in_background_context @@ -28,13 +29,18 @@ def test_set_object() -> None: proxy.set_current_panel("signal") sig_uuid = proxy.get_object_uuids("signal")[0] + proxy.select_objects([sig_uuid], panel="signal") + proxy.delete_metadata(refresh_plot=False, keep_roi=False) sig = proxy.get_object(sig_uuid) + assert get_uuid(sig) == sig_uuid + assert sig_uuid in proxy.get_object_uuids("signal") original_title = sig.title sig.title = "Modified signal title" sig.yunit = "modified_unit" proxy.set_object(sig) sig_back = proxy.get_object(sig_uuid) + assert get_uuid(sig_back) == sig_uuid assert sig_back.title == "Modified signal title" assert sig_back.yunit == "modified_unit" diff --git a/datalab/tests/features/image/annotations_unit_test.py b/datalab/tests/features/image/annotations_unit_test.py index 11a0d0699..60af9c69d 100644 --- a/datalab/tests/features/image/annotations_unit_test.py +++ b/datalab/tests/features/image/annotations_unit_test.py @@ -14,11 +14,13 @@ from plotpy.builder import make from plotpy.items import AnnotatedShape, PolygonShape from plotpy.plot import BasePlot +from qtpy import QtCore as QC from qtpy import QtWidgets as QW from sigima.tests import data as test_data from datalab.adapters_plotpy import create_adapter_from_object from datalab.env import execenv +from datalab.objectmodel import get_uuid from datalab.tests import datalab_test_app_context @@ -76,5 +78,36 @@ def test_annotations_unit(): execenv.print("OK") +def test_open_separate_view_without_main_plot_item() -> None: + """Open a separate view when the object has no item in the main plot.""" + with datalab_test_app_context() as win: + panel = win.imagepanel + reference = test_data.create_multigaussian_image() + target = test_data.create_annotated_image() + panel.add_object(reference) + panel.add_object(target) + + target_uuid = get_uuid(target) + panel.plothandler.remove_item(target_uuid) + assert panel.plothandler.get(target_uuid) is None + + existing_uuids = panel.plothandler.get_existing_oids() + existing_items = {uuid: panel.plothandler.get(uuid) for uuid in existing_uuids} + visibility = {uuid: item.isVisible() for uuid, item in existing_items.items()} + dialog = panel.open_separate_view(oids=[target_uuid]) + assert dialog is not None + dialog.close() + QW.QApplication.sendPostedEvents(None, QC.QEvent.Type.DeferredDelete) + QW.QApplication.processEvents() + + assert panel.plothandler.get_existing_oids() == existing_uuids + assert all( + panel.plothandler.get(uuid) is item for uuid, item in existing_items.items() + ) + assert { + uuid: panel.plothandler.get(uuid).isVisible() for uuid in existing_uuids + } == visibility + + if __name__ == "__main__": test_annotations_unit() From ce7938ec9fc9a8c03aaf76dbbb45eb3a68d0a881 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Wed, 22 Jul 2026 16:12:44 +0200 Subject: [PATCH 060/108] Refactor: Modularize History panel architecture and improve test reliability The History panel had accumulated overlapping responsibilities and broad tests, making replay workflows harder to maintain and unrelated GUI tests sensitive to persistent History state. Split the feature into cohesive services, simplified object lifecycle flows, and replaced oversized coverage with focused behavioral contracts across supported Python versions. * [CHG] : Separate History runtime, UI, navigation, facade, and reconnection responsibilities into cohesive components * [NEW] : Extract replay UUID mapping and object creation services for reuse across duplication, recompute, deletion, and HDF5 import workflows * [FIX] : Keep runtime output indexes consistent and preserve plugin provenance when replaying or reconnecting objects * [CHG] : Replace overlapping History tests with 12 compact behavioral contracts and a dedicated visual smoke test * [FIX] : Disable History tracking by default in unrelated GUI tests and prevent unattended runs from persisting dock or current-tab state --- datalab/gui/creation.py | 121 + datalab/gui/historysession_ops.py | 67 +- datalab/gui/historytools_ops.py | 625 ++--- datalab/gui/main.py | 5 +- datalab/gui/newobject.py | 143 +- datalab/gui/panel/history/chain.py | 276 ++- datalab/gui/panel/history/chainmodel.py | 111 +- datalab/gui/panel/history/facade.py | 285 +++ .../gui/panel/history/interactive_replay.py | 88 +- datalab/gui/panel/history/navigation.py | 241 ++ datalab/gui/panel/history/panel.py | 863 +------ datalab/gui/panel/history/recompute.py | 115 +- datalab/gui/panel/history/reconnection.py | 44 + datalab/gui/panel/history/runtime.py | 246 ++ datalab/gui/panel/history/ui.py | 182 ++ datalab/h5/history.py | 252 +- datalab/history/action.py | 240 +- datalab/history/replaymap.py | 234 ++ datalab/history/session.py | 218 +- .../tests/features/common/history_app_test.py | 196 -- .../common/history_model_unit_test.py | 145 ++ .../features/common/history_panel_test.py | 158 ++ datalab/tests/features/common/history_test.py | 2122 ----------------- .../features/common/history_test_helpers.py | 186 ++ .../features/common/history_workflow_test.py | 324 +++ datalab/widgets/historytree.py | 14 +- 26 files changed, 3273 insertions(+), 4228 deletions(-) create mode 100644 datalab/gui/creation.py create mode 100644 datalab/gui/panel/history/facade.py create mode 100644 datalab/gui/panel/history/navigation.py create mode 100644 datalab/gui/panel/history/reconnection.py create mode 100644 datalab/gui/panel/history/runtime.py create mode 100644 datalab/gui/panel/history/ui.py create mode 100644 datalab/history/replaymap.py delete mode 100644 datalab/tests/features/common/history_app_test.py create mode 100644 datalab/tests/features/common/history_model_unit_test.py create mode 100644 datalab/tests/features/common/history_panel_test.py delete mode 100644 datalab/tests/features/common/history_test.py create mode 100644 datalab/tests/features/common/history_test_helpers.py create mode 100644 datalab/tests/features/common/history_workflow_test.py diff --git a/datalab/gui/creation.py b/datalab/gui/creation.py new file mode 100644 index 000000000..24cf249c2 --- /dev/null +++ b/datalab/gui/creation.py @@ -0,0 +1,121 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +"""Dependency-neutral object creation services.""" + +from __future__ import annotations + +from typing import TYPE_CHECKING + +import guidata.dataset as gds +import numpy as np +from sigima.objects import ( + CustomSignalParam, + Gauss2DParam, + ImageDatatypes, + ImageObj, + NewImageParam, + NewSignalParam, + SignalObj, + create_signal, +) +from sigima.objects import create_image_from_param as create_image_headless +from sigima.objects import create_signal_from_param as create_signal_headless +from sigima.objects.base import BaseProcParam +from sigima.objects.signal import DEFAULT_TITLE as SIGNAL_DEFAULT_TITLE + +from datalab.config import _ + +if TYPE_CHECKING: + from qtpy import QtWidgets as QW + +CREATION_PARAMETERS_OPTION = "creation_param_json" + + +def insert_creation_parameters(obj: SignalObj | ImageObj, param: gds.DataSet) -> None: + """Insert creation parameters into object metadata. + + Args: + obj: Object receiving the serialized parameters. + param: Creation parameters. + """ + obj.set_metadata_option(CREATION_PARAMETERS_OPTION, gds.dataset_to_json(param)) + + +def extract_creation_parameters(obj: SignalObj | ImageObj) -> gds.DataSet | None: + """Extract creation parameters from object metadata. + + Args: + obj: Object containing serialized creation parameters. + + Returns: + Creation parameters or None if not found. + """ + try: + param_json = obj.get_metadata_option(CREATION_PARAMETERS_OPTION) + except ValueError: + return None + return gds.json_to_dataset(param_json) + + +def create_signal_from_param(param: NewSignalParam) -> SignalObj: + """Create a signal from initialized parameters.""" + if isinstance(param, CustomSignalParam): + signal = create_signal(param.title) + signal.xydata = param.xyarray.T + if signal.title == SIGNAL_DEFAULT_TITLE: + signal.title = f"custom(npts={param.size})" + return signal + signal = create_signal_headless(param) + if param.__class__ is not NewSignalParam: + insert_creation_parameters(signal, param) + return signal + + +def prepare_signal_parameters( + param: NewSignalParam | None, + edit: bool, + parent: QW.QWidget | None = None, +) -> NewSignalParam | None: + """Initialize and optionally edit signal creation parameters.""" + if param is None: + param = NewSignalParam() + edit = True + if isinstance(param, CustomSignalParam): + edit = True + if isinstance(param, CustomSignalParam) and edit: + initial = NewSignalParam(_("Custom signal")) + initial.size = 10 + if not initial.edit(parent=parent): + return None + param.setup_array(size=initial.size, xmin=initial.xmin, xmax=initial.xmax) + if edit and not param.edit(parent=parent): + return None + return param + + +def initialize_image_parameters(param: NewImageParam) -> None: + """Fill image creation defaults required by the editor and constructor.""" + if param.height is None: + param.height = 500 + if param.width is None: + param.width = 500 + if param.dtype is None: + param.dtype = ImageDatatypes.UINT16 + numpy_dtype = param.dtype.to_numpy_dtype() + if isinstance(param, Gauss2DParam): + if param.a is None: + try: + param.a = np.iinfo(numpy_dtype).max / 2.0 + except ValueError: + param.a = 10.0 + elif isinstance(param, BaseProcParam): + param.set_from_datatype(numpy_dtype) + + +def create_image_from_param(param: NewImageParam) -> ImageObj: + """Create an image from initialized parameters.""" + initialize_image_parameters(param) + image = create_image_headless(param) + if param.__class__ is not NewImageParam: + insert_creation_parameters(image, param) + return image diff --git a/datalab/gui/historysession_ops.py b/datalab/gui/historysession_ops.py index 76628a440..3efe207b1 100644 --- a/datalab/gui/historysession_ops.py +++ b/datalab/gui/historysession_ops.py @@ -4,23 +4,20 @@ from __future__ import annotations -import logging from contextlib import contextmanager from copy import deepcopy from typing import TYPE_CHECKING, Any, Generator -from qtpy import QtCore as QC from qtpy import QtWidgets as QW from datalab.config import _ from datalab.env import execenv +from datalab.gui.panel.history import chain as hchain from datalab.history import HistoryAction, HistorySession, WorkspaceState if TYPE_CHECKING: from datalab.gui.panel.history import HistoryPanel -_logger = logging.getLogger(__name__) - def create_new_session( panel: HistoryPanel, panel_str: str | None = None @@ -34,11 +31,11 @@ def create_new_session( Returns: The newly created session. """ - pstr = panel_str or panel.current_panel_str() - panel.session_increment += 1 - session = HistorySession(number=panel.session_increment) + pstr = panel_str or panel.navigation.current_panel_str() + panel.navigation.session_increment += 1 + session = HistorySession(number=panel.navigation.session_increment) panel.history_sessions.append(session) - panel.set_active_session(session, pstr) + panel.navigation.set_active_session(session, pstr) panel.tree.populate_tree(panel.history_sessions) panel.refresh_compatibility_items() return session @@ -64,7 +61,7 @@ def maybe_start_session_for_input(panel: HistoryPanel, *, load: bool = False) -> """ if not panel.record_mode_enabled or panel.is_replaying(): return - if panel.suppress_session_prompt: + if panel.runtime.execution.suppress_session_prompt: return # Reuse the current session when there is none yet or it has no actions: # there is nothing to preserve, so no need to prompt. @@ -72,10 +69,8 @@ def maybe_start_session_for_input(panel: HistoryPanel, *, load: bool = False) -> return # Debounce: a synchronous burst of creations (plugin/macro) must prompt only # once. The guard is reset on the next event-loop turn. - if panel.session_input_pending: + if not panel.runtime.execution.start_session_input_prompt(): return - panel.session_input_pending = True - QC.QTimer.singleShot(0, lambda: setattr(panel, "session_input_pending", False)) if execenv.unattended: # Headless runs: honor the accept_dialogs flag (default False -> "No"), # so tests can drive the behavior without a real modal dialog. @@ -154,8 +149,8 @@ def add_compute_entry( pattern=pattern, kwargs=deepcopy(kwargs), state=state, - plugin_origin=plugin_origin, ) + action.plugin_origin = deepcopy(plugin_origin) panel.add_object(action) if output_uuids is not None: panel.register_action_outputs(action, output_uuids) @@ -228,39 +223,7 @@ def register_action_outputs( ``1_to_0`` analysis patterns and for UI actions that did not create new objects). """ - # Drop previous outputs for this action from the reverse index. - previous = panel.action_output_uuids.get(action.uuid, []) - for prev_uuid in previous: - if panel.output_to_action.get(prev_uuid) == action.uuid: - panel.output_to_action.pop(prev_uuid, None) - new_outputs = list(output_uuids) - # Ownership transfer: if an output_uuid already belongs to a - # *different* action, remove it from that action's output list so the - # forward mapping stays consistent. The HistoryAction object's - # ``output_uuids`` attribute is NOT updated here because traversing all - # sessions to locate the object would be expensive; the panel-level - # dicts are the source of truth. - for out_uuid in new_outputs: - old_action_uuid = panel.output_to_action.get(out_uuid) - if old_action_uuid is not None and old_action_uuid != action.uuid: - old_list = panel.action_output_uuids.get(old_action_uuid) - if old_list is not None: - try: - old_list.remove(out_uuid) - except ValueError: - pass - if not old_list: - del panel.action_output_uuids[old_action_uuid] - _logger.debug( - "Output %s transferred from action %s to %s", - out_uuid, - old_action_uuid, - action.uuid, - ) - action.output_uuids = list(new_outputs) - panel.action_output_uuids[action.uuid] = new_outputs - for out_uuid in new_outputs: - panel.output_to_action[out_uuid] = action.uuid + panel.runtime.objects.register_action_outputs(action, output_uuids) @contextmanager @@ -302,10 +265,10 @@ def capture_outputs( # it failed (or was a full no-op). Do not keep a misleading "OK" # entry in the history — remove the just-recorded action and # refresh the tree so the panel stays consistent. - panel.remove_single_action(action) + hchain.remove_single_action(panel, action) panel.tree.populate_tree(panel.history_sessions) panel.refresh_compatibility_items() - panel.update_actions_state() + panel.ui.update_actions_state() def add_ui_entry( @@ -373,13 +336,13 @@ def add_object(panel: HistoryPanel, obj: HistoryAction) -> None: and image pipelines stay in separate sessions and recording resumes in the user-selected session. """ - pstr = obj.panel_str or panel.current_panel_str() - session = panel.get_active_session(pstr) + pstr = obj.panel_str or panel.navigation.current_panel_str() + session = panel.navigation.get_active_session(pstr) if session is None: session = panel.create_new_session(panel_str=pstr) session.add_action(obj) session_index = panel.history_sessions.index(session) - panel.tree.add_action_to_tree(obj, session_index) + panel.tree.rebuild_session(session_index) panel.tree.rearrange_tree() panel.refresh_compatibility_items() - panel.update_actions_state() + panel.ui.update_actions_state() diff --git a/datalab/gui/historytools_ops.py b/datalab/gui/historytools_ops.py index fbe8f8738..5b77babf6 100644 --- a/datalab/gui/historytools_ops.py +++ b/datalab/gui/historytools_ops.py @@ -5,7 +5,7 @@ from __future__ import annotations from copy import deepcopy -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Any from uuid import uuid4 from qtpy import QtWidgets as QW @@ -14,8 +14,15 @@ from datalab.env import execenv from datalab.gui.panel.history import chain as hchain from datalab.gui.panel.history.chainmodel import ( + ChainSelectionPlan, + DeletionPlan, + DeletionResult, + DuplicatedSession, ProcessingChain, + UuidCloneRegistry, + action_input_uuids, build_session_chains, + remap_processing_parameters, ) from datalab.gui.processor.base import ( PROCESSING_PARAMETERS_OPTION, @@ -73,33 +80,24 @@ def make_initial_state_head(pstr: str, clone_uuid: str, title: str) -> HistoryAc return head -def duplicate_selected_entries(panel: HistoryPanel) -> None: - """Duplicate selected processing chains into new independent sessions. - - Selection is resolved to *processing chains* (see - :func:`build_session_chains`): a session **is** a single linear processing - chain, so selecting a session duplicates its chain, and selecting an action - duplicates the chain of its session. For each source session, exactly one - new session is produced containing the duplicate of its chain, with all - referenced data objects deep-copied into a new group and every UUID - reference rewritten to the clones. - - Two chain shapes are handled: - - * **Cas A** -- creation-rooted chain (root is a ``new_object`` UI action): - the chain is copied as-is (root included), no synthetic head is added. - * **Cas B** -- operation-rooted chain (root consumes an external object): - one synthetic ``new_object`` head is prepended per distinct remapped - source object so the duplicated chain remains self-contained and - replayable. - - The result is an independent, editable and replayable session. - """ - selected = panel.tree.get_selected_actions_or_sessions(panel.history_sessions) - if not selected: - return +def append_action_chain( + action: HistoryAction, + all_chains: list[ProcessingChain], + seen_chains: set[int], + chains: list[ProcessingChain], +) -> None: + """Append the unseen processing chain containing the selected action.""" + for chain in all_chains: + if any(item is action or item.uuid == action.uuid for item in chain.actions): + if id(chain) not in seen_chains: + seen_chains.add(id(chain)) + chains.append(chain) + break - # 1. Resolve selection to a per-session set of chains. + +def resolve_chain_selection(panel: HistoryPanel) -> list[ChainSelectionPlan]: + """Resolve tree selection to ordered processing chains per source session.""" + selected = panel.tree.get_selected_actions_or_sessions(panel.history_sessions) session_by_id: dict[int, HistorySession] = {} full_session_ids: set[int] = set() actions_by_session: dict[int, list[HistoryAction]] = {} @@ -108,212 +106,221 @@ def duplicate_selected_entries(panel: HistoryPanel) -> None: session_by_id[id(item)] = item full_session_ids.add(id(item)) else: - session = panel.find_parent_session(item) + session = hchain.find_parent_session(panel, item) if session is None: continue session_by_id[id(session)] = session actions_by_session.setdefault(id(session), []).append(item) # Preserve source-session order (iterate panel.history_sessions). - ordered: list[tuple[HistorySession, list[ProcessingChain]]] = [] + plans: list[ChainSelectionPlan] = [] for session in panel.history_sessions: sid = id(session) if sid not in session_by_id: continue - all_chains = build_session_chains(panel, session) + all_chains = build_session_chains(session) if sid in full_session_ids: chains = all_chains else: chains = [] seen_chains: set[int] = set() for action in actions_by_session.get(sid, []): - for chain in all_chains: - if any(a is action or a.uuid == action.uuid for a in chain.actions): - if id(chain) not in seen_chains: - seen_chains.add(id(chain)) - chains.append(chain) - break + append_action_chain(action, all_chains, seen_chains, chains) if chains: - ordered.append((session, chains)) - if not ordered: - return + plans.append(ChainSelectionPlan(session, chains)) + return plans + + +def collect_referenced_uuids(chains: list[ProcessingChain]) -> dict[str, set[str]]: + """Collect object UUIDs referenced or produced by selected chains.""" + uuids_by_panel: dict[str, set[str]] = {} + for chain in chains: + for action in chain.actions: + for panel_str, uuids in action.state.selection.items(): + uuids_by_panel.setdefault(panel_str, set()).update(uuids) + for panel_str, metadata in action.state.object_metadata.items(): + uuids_by_panel.setdefault(panel_str, set()).update(metadata) + obj2_uuids = action.kwargs.get("obj2_uuids") + if obj2_uuids: + panel_str = action_panel_str(action) + if isinstance(obj2_uuids, str): + obj2_uuids = [obj2_uuids] + uuids_by_panel.setdefault(panel_str, set()).update(obj2_uuids) + if action.output_uuids: + panel_str = action_panel_str(action) + uuids_by_panel.setdefault(panel_str, set()).update(action.output_uuids) + return uuids_by_panel - copy_suffix = _("Copy") - new_sessions: list[HistorySession] = [] - panel_map = { - "signal": panel.mainwindow.signalpanel, - "image": panel.mainwindow.imagepanel, - } - - for session, chains in ordered: - # 2. Collect all UUIDs referenced by the SELECTED chains only. - uuids_by_panel: dict[str, set[str]] = {} - for chain in chains: - for action in chain.actions: - for pstr, uuids in action.state.selection.items(): - uuids_by_panel.setdefault(pstr, set()).update(uuids) - for pstr, metadata in action.state.object_metadata.items(): - uuids_by_panel.setdefault(pstr, set()).update(metadata.keys()) - obj2 = action.kwargs.get("obj2_uuids") - if obj2: - pstr = action_panel_str(action) - if isinstance(obj2, str): - obj2 = [obj2] - uuids_by_panel.setdefault(pstr, set()).update(obj2) - # Output UUIDs produced by this action (e.g. result of a - # compute step). Without this, the last action's outputs - # would be missing because no subsequent state captures them. - if action.output_uuids: - pstr = action_panel_str(action) - uuids_by_panel.setdefault(pstr, set()).update(action.output_uuids) - - # 3. Clone objects and build uuid_remap. - uuid_remap: dict[str, dict[str, str]] = {} - clones_by_pstr: dict[str, list] = {} - group_title = f"{copy_suffix} - {session.title}" - for pstr, uuids in uuids_by_panel.items(): - data_panel = panel_map.get(pstr) - if data_panel is None: + +def set_object_uuid(obj: Any, new_uuid: str) -> None: + """Set a cloned data object's UUID through its supported storage API.""" + try: + obj.set_metadata_option("uuid", new_uuid) + except AttributeError: + obj.uuid = new_uuid + + +def clone_referenced_objects( + panel: HistoryPanel, plan: ChainSelectionPlan, copy_suffix: str +) -> UuidCloneRegistry: + """Clone a selection plan's objects and register source-to-clone UUIDs.""" + registry = UuidCloneRegistry() + group_title = f"{copy_suffix} - {plan.source_session.title}" + for panel_str, referenced in collect_referenced_uuids(plan.chains).items(): + data_panel = data_panel_for(panel, panel_str) + if data_panel is None: + continue + ordered_uuids = [ + obj_uuid + for obj_uuid in data_panel.objmodel.get_object_ids() + if obj_uuid in referenced + ] + clones: list[Any] = [] + for old_uuid in ordered_uuids: + clone = deepcopy(data_panel.objmodel[old_uuid]) + new_uuid = str(uuid4()) + set_object_uuid(clone, new_uuid) + registry.register(panel_str, old_uuid, new_uuid, clone) + clones.append(clone) + if clones: + group_id = get_uuid(data_panel.add_group(group_title)) + for clone in clones: + data_panel.add_object(clone, group_id=group_id) + return registry + + +def remap_cloned_object_sources(registry: UuidCloneRegistry) -> None: + """Rewrite processing-parameter source UUIDs in all cloned objects.""" + for panel_str, clones in registry.clones_by_panel.items(): + panel_remap = registry.uuid_remap.get(panel_str, {}) + for clone in clones: + try: + parameters_dict = clone.get_metadata_option( + PROCESSING_PARAMETERS_OPTION + ) + except (AttributeError, ValueError): continue - uuid_remap[pstr] = {} - existing_ids = set(data_panel.objmodel.get_object_ids()) - clones = [] - # Iterate in panel order (not set order) to preserve - # the topological object ordering in the duplicated group. - ordered_ids = [ - u for u in data_panel.objmodel.get_object_ids() if u in uuids - ] - for old_uuid in ordered_ids: - if old_uuid not in existing_ids: - continue - obj = data_panel.objmodel[old_uuid] - clone = deepcopy(obj) - new_uuid = str(uuid4()) - # SignalObj/ImageObj store UUID via metadata option - try: - clone.set_metadata_option("uuid", new_uuid) - except AttributeError: - clone.uuid = new_uuid - uuid_remap[pstr][old_uuid] = new_uuid - clones.append(clone) - clones_by_pstr[pstr] = clones - if clones: - group_id = get_uuid(data_panel.add_group(group_title)) - for clone in clones: - data_panel.add_object(clone, group_id=group_id) - - # Second pass: remap source UUIDs in cloned objects' - # processing_parameters so reprocessing in the Processing tab - # uses the cloned source, not the original. - for pstr_inner, clones_inner in clones_by_pstr.items(): - pmap = uuid_remap.get(pstr_inner, {}) - if not pmap: + if not parameters_dict: continue - for clone in clones_inner: - try: - pp_dict = clone.get_metadata_option(PROCESSING_PARAMETERS_OPTION) - except (AttributeError, ValueError): - continue - if not pp_dict: - continue - try: - pp = ProcessingParameters.from_dict(pp_dict) - except (TypeError, ValueError, AttributeError): - continue - changed = False - if pp.source_uuid is not None and pp.source_uuid in pmap: - pp.source_uuid = pmap[pp.source_uuid] - changed = True - if pp.source_uuids is not None: - new_src = [pmap.get(u, u) for u in pp.source_uuids] - if new_src != pp.source_uuids: - pp.source_uuids = new_src - changed = True - if changed: - try: - clone.set_metadata_option( - PROCESSING_PARAMETERS_OPTION, pp.to_dict() - ) - except (AttributeError, ValueError): - pass - - # 4. Build the new session's actions per chain (Cas A / Cas B). - new_actions: list[HistoryAction] = [] - for chain in chains: - is_creation_root = ( - chain.root.kind == HistoryAction.KIND_UI - and chain.root.method_name in HistoryAction.UI_CREATION_METHODS - ) - if is_creation_root: - # Cas A: creation-rooted chain, copy as-is (root included). - new_actions.extend( - action.copy_with_uuid_remap(uuid_remap) for action in chain.actions + try: + parameters = ProcessingParameters.from_dict(parameters_dict) + except (TypeError, ValueError, AttributeError): + continue + remapped = remap_processing_parameters(parameters, panel_remap) + if remapped == parameters: + continue + try: + clone.set_metadata_option( + PROCESSING_PARAMETERS_OPTION, remapped.to_dict() ) + except (AttributeError, ValueError): continue - # Cas B: operation-rooted chain, synthesize one creation head per - # distinct remapped source object of the chain root. - root_inputs: list[tuple[str, str]] = [] - for pstr, uuids in chain.root.state.selection.items(): - for old_uuid in uuids: - root_inputs.append((pstr, old_uuid)) - obj2 = chain.root.kwargs.get("obj2_uuids") - if obj2: - pstr = action_panel_str(chain.root) - if isinstance(obj2, str): - obj2 = [obj2] - for old_uuid in obj2: - root_inputs.append((pstr, old_uuid)) - heads: list[HistoryAction] = [] - seen_clones: set[str] = set() - for pstr, old_uuid in root_inputs: - clone_uuid = uuid_remap.get(pstr, {}).get(old_uuid) - if clone_uuid is None or clone_uuid in seen_clones: - # Source object deleted / not clonable, or already headed. - continue - seen_clones.add(clone_uuid) - head_title = _("Initial state") - data_panel = panel_map.get(pstr) - if data_panel is not None: - try: - head_title = data_panel.objmodel[clone_uuid].title - except (KeyError, AttributeError): - head_title = _("Initial state") - head = make_initial_state_head(pstr, clone_uuid, head_title) - heads.append(head) - panel.action_output_uuids[head.uuid] = [clone_uuid] - panel.output_to_action[clone_uuid] = head.uuid - new_actions.extend(heads) - new_actions.extend( - action.copy_with_uuid_remap(uuid_remap) for action in chain.actions - ) - # 5. Assemble the new session and register output mappings. - panel.session_increment += 1 - title = f"{session.title} {copy_suffix}" - new_session = HistorySession(title=title, number=panel.session_increment) - new_session.actions = new_actions - new_sessions.append(new_session) - - # Register output mappings for cloned actions so that - # resolve_target_outputs / get_downstream_actions work on - # the duplicated session (same logic as deserialize_from_hdf5). - for action in new_session.actions: - if action.output_uuids: - panel.action_output_uuids[action.uuid] = list(action.output_uuids) - for out_uuid in action.output_uuids: - panel.output_to_action[out_uuid] = action.uuid - - # Insert each duplicated session immediately after its original. - offset = 0 - source_sessions = [session for session, _chains in ordered] - for original_session, new_session in zip(source_sessions, new_sessions): - idx = panel.history_sessions.index(original_session) - panel.history_sessions.insert(idx + 1 + offset, new_session) - offset += 1 + +def chain_root_inputs(action: HistoryAction) -> list[tuple[str, str]]: + """Return panel-qualified source UUIDs consumed by a chain root.""" + inputs = [ + (panel_str, old_uuid) + for panel_str, uuids in action.state.selection.items() + for old_uuid in uuids + ] + obj2_uuids = action.kwargs.get("obj2_uuids") + if isinstance(obj2_uuids, str): + obj2_uuids = [obj2_uuids] + if obj2_uuids: + panel_str = action_panel_str(action) + inputs.extend((panel_str, old_uuid) for old_uuid in obj2_uuids) + return inputs + + +def make_synthetic_heads( + panel: HistoryPanel, chain: ProcessingChain, registry: UuidCloneRegistry +) -> list[HistoryAction]: + """Create one independent creation head per cloned external root input.""" + heads: list[HistoryAction] = [] + seen_clones: set[str] = set() + for panel_str, old_uuid in chain_root_inputs(chain.root): + clone_uuid = registry.resolve(panel_str, old_uuid) + if clone_uuid is None or clone_uuid in seen_clones: + continue + seen_clones.add(clone_uuid) + head_title = _("Initial state") + data_panel = data_panel_for(panel, panel_str) + if data_panel is not None: + try: + head_title = data_panel.objmodel[clone_uuid].title + except (KeyError, AttributeError): + pass + heads.append(make_initial_state_head(panel_str, clone_uuid, head_title)) + return heads + + +def assemble_duplicated_actions( + panel: HistoryPanel, plan: ChainSelectionPlan, registry: UuidCloneRegistry +) -> list[HistoryAction]: + """Copy selected actions and add heads for operation-rooted chains.""" + new_actions: list[HistoryAction] = [] + for chain in plan.chains: + is_creation_root = ( + chain.root.kind == HistoryAction.KIND_UI + and chain.root.method_name in HistoryAction.UI_CREATION_METHODS + ) + if not is_creation_root: + new_actions.extend(make_synthetic_heads(panel, chain, registry)) + new_actions.extend( + action.copy_with_uuid_remap(registry.uuid_remap) for action in chain.actions + ) + return new_actions + + +def register_session_outputs(panel: HistoryPanel, session: HistorySession) -> None: + """Register action-to-output mappings for one assembled session.""" + for action in session.actions: + if not action.output_uuids: + continue + panel.runtime.objects.register_action_outputs(action, action.output_uuids) + + +def duplicate_chain_plan( + panel: HistoryPanel, plan: ChainSelectionPlan, copy_suffix: str +) -> DuplicatedSession: + """Clone objects and assemble one independent duplicated session.""" + registry = clone_referenced_objects(panel, plan, copy_suffix) + remap_cloned_object_sources(registry) + panel.navigation.session_increment += 1 + new_session = HistorySession( + title=f"{plan.source_session.title} {copy_suffix}", + number=panel.navigation.session_increment, + ) + new_session.actions = assemble_duplicated_actions(panel, plan, registry) + register_session_outputs(panel, new_session) + return DuplicatedSession(plan.source_session, new_session) + + +def insert_duplicated_sessions( + panel: HistoryPanel, duplicated_sessions: list[DuplicatedSession] +) -> None: + """Insert duplicates after their sources and refresh/select the tree.""" + for duplicated in reversed(duplicated_sessions): + source_index = panel.history_sessions.index(duplicated.source_session) + panel.history_sessions.insert(source_index + 1, duplicated.new_session) panel.tree.populate_tree(panel.history_sessions) - panel.select_sessions(new_sessions) + panel.navigation.select_sessions([item.new_session for item in duplicated_sessions]) panel.refresh_compatibility_items() - panel.update_actions_state() + panel.ui.update_actions_state() + + +def duplicate_selected_entries(panel: HistoryPanel) -> None: + """Duplicate selected processing chains into new independent sessions.""" + selection_plans = resolve_chain_selection(panel) + if not selection_plans: + return + + copy_suffix = _("Copy") + duplicated_sessions = [ + duplicate_chain_plan(panel, plan, copy_suffix) for plan in selection_plans + ] + insert_duplicated_sessions(panel, duplicated_sessions) def data_panel_for(panel: HistoryPanel, panel_str: str) -> BaseDataPanel | None: @@ -325,18 +332,6 @@ def data_panel_for(panel: HistoryPanel, panel_str: str) -> BaseDataPanel | None: return None -def action_input_uuids(action: HistoryAction) -> set[str]: - """Return the set of object UUIDs consumed as inputs by ``action``.""" - captured: set[str] = set(action.state.selection.get(action.panel_str or "", [])) - obj2 = action.kwargs.get("obj2_uuids") - if obj2: - if isinstance(obj2, str): - captured.add(obj2) - else: - captured.update(obj2) - return captured - - def strip_source_links(obj) -> None: """Turn ``obj`` into a parentless creation root (drop source references).""" pp = extract_processing_parameters(obj) @@ -344,13 +339,7 @@ def strip_source_links(obj) -> None: return insert_processing_parameters( obj, - ProcessingParameters( - func_name=pp.func_name, - pattern=pp.pattern, - param=pp.param, - source_uuid=None, - source_uuids=None, - ), + remap_processing_parameters(pp, {}, clear_sources=True), ) @@ -405,7 +394,7 @@ def split_chain_on_action_delete( panel_str = action.panel_str or "" # Compute downstream + captured output UUIDs BEFORE removing the action. downstream = hchain.get_downstream_actions(panel, action) - output_uuids = list(panel.action_output_uuids.get(action.uuid, [])) + output_uuids = list(panel.runtime.objects.action_output_uuids.get(action.uuid, [])) # Splice the action out (does not truncate the rest of the session). hchain.remove_single_action(panel, action) if not downstream: @@ -435,7 +424,7 @@ def split_chain_on_action_delete( if orphan_uuid not in action_input_uuids(d): continue hchain.rewrite_action_source(d, d.panel_str or "", orphan_uuid, new_uuid) - for out_uuid in panel.action_output_uuids.get(d.uuid, []): + for out_uuid in panel.runtime.objects.action_output_uuids.get(d.uuid, []): if data_panel.objmodel.has_uuid(out_uuid): remap_object_source( data_panel.objmodel[out_uuid], orphan_uuid, new_uuid @@ -452,20 +441,24 @@ def remove_data_object(data_panel: BaseDataPanel, obj_uuid: str) -> None: data_panel.objmodel.remove_object(obj) -def delete_selected(panel: HistoryPanel) -> None: - """Delete the selected actions or sessions (with confirmation). +def plan_deletion( + panel: HistoryPanel, selected: list[HistoryAction | HistorySession] +) -> DeletionPlan: + """Classify selected history entities without mutating panel state.""" + plan = DeletionPlan() + for item in selected: + if isinstance(item, HistorySession): + plan.session_ids.add(id(item)) + continue + plan.actions.append(item) + if plan.affected_session is None: + plan.affected_session = hchain.find_parent_session(panel, item) + return plan - When a top-level session is selected, the entire session is deleted. - When individual actions are selected, each action is spliced out of its - session and its processing chain is split: downstream steps become an - independent chain rooted at a copy of the deleted action's output. After - deletion, the last action leaf in the affected session is selected. - """ - selected = panel.tree.get_selected_actions_or_sessions(panel.history_sessions) - if not selected: - return - has_individual_actions = any(isinstance(item, HistoryAction) for item in selected) - if has_individual_actions: + +def confirm_deletion(panel: HistoryPanel, plan: DeletionPlan) -> bool: + """Ask the user to confirm a planned history deletion.""" + if plan.actions: msg = _( "Do you really want to delete the selected items?\n\n" "Note: deleting an intermediate action splits its processing " @@ -484,66 +477,93 @@ def delete_selected(panel: HistoryPanel) -> None: QW.QMessageBox.No, ) ) - if reply != QW.QMessageBox.Yes: - return - # Memorize affected session for post-deletion selection - affected_session: HistorySession | None = None - for item in selected: - if isinstance(item, HistoryAction): - for session in panel.history_sessions: - if item in session.actions: - affected_session = session - break - if affected_session is not None: - break - - sessions_to_remove: set[int] = set() + return reply == QW.QMessageBox.Yes + + +def apply_deletion(panel: HistoryPanel, plan: DeletionPlan) -> DeletionResult: + """Delete planned actions/sessions and return orphan cleanup state.""" orphan_refs: list[tuple[str, str]] = [] - for item in selected: - if isinstance(item, HistorySession): - sessions_to_remove.add(id(item)) - elif isinstance(item, HistoryAction): - # Individual action: splice it out and split its chain (with copy). - orphan_uuid = split_chain_on_action_delete(panel, item) - if orphan_uuid is not None: - orphan_refs.append((item.panel_str or "", orphan_uuid)) + for action in plan.actions: + orphan_uuid = split_chain_on_action_delete(panel, action) + if orphan_uuid is not None: + orphan_refs.append((action.panel_str or "", orphan_uuid)) + for session in panel.history_sessions: + if id(session) in plan.session_ids: + for action in session.actions: + panel.runtime.objects.remove_action_outputs(action) panel.history_sessions = [ - s for s in panel.history_sessions if id(s) not in sessions_to_remove + session + for session in panel.history_sessions + if id(session) not in plan.session_ids ] - # §8.3 — opt-in: offer to also remove the now-orphaned output object(s). + return DeletionResult( + plan.affected_session, + plan.session_ids, + orphan_refs, + ) + + +def collect_alive_orphans( + panel: HistoryPanel, orphan_refs: list[tuple[str, str]] +) -> list[tuple[BaseDataPanel, str]]: + """Resolve orphan references that are still present in data panels.""" alive_orphans: list[tuple[BaseDataPanel, str]] = [] for panel_str, orphan_uuid in orphan_refs: data_panel = data_panel_for(panel, panel_str) if data_panel is not None and data_panel.objmodel.has_uuid(orphan_uuid): alive_orphans.append((data_panel, orphan_uuid)) - if alive_orphans and not execenv.unattended: - answer = QW.QMessageBox.question( - panel.mainwindow, - _("Delete"), - _( - "The deleted action(s) produced object(s) still present in the " - "workspace. Do you want to remove the associated object(s) as well?" - ), - QW.QMessageBox.Yes | QW.QMessageBox.No, - QW.QMessageBox.No, - ) - if answer == QW.QMessageBox.Yes: - touched: dict[int, BaseDataPanel] = {} - for data_panel, orphan_uuid in alive_orphans: - if data_panel.objmodel.has_uuid(orphan_uuid): - remove_data_object(data_panel, orphan_uuid) - touched[id(data_panel)] = data_panel - for data_panel in touched.values(): - data_panel.objview.update_tree() - data_panel.selection_changed(update_items=True) - panel.refresh_obj_ids_snapshot() + return alive_orphans + + +def confirm_orphan_removal( + panel: HistoryPanel, alive_orphans: list[tuple[BaseDataPanel, str]] +) -> bool: + """Ask whether surviving output objects should also be removed.""" + if not alive_orphans or execenv.unattended: + return False + answer = QW.QMessageBox.question( + panel.mainwindow, + _("Delete"), + _( + "The deleted action(s) produced object(s) still present in the " + "workspace. Do you want to remove the associated object(s) as well?" + ), + QW.QMessageBox.Yes | QW.QMessageBox.No, + QW.QMessageBox.No, + ) + return answer == QW.QMessageBox.Yes + + +def remove_orphan_objects( + panel: HistoryPanel, alive_orphans: list[tuple[BaseDataPanel, str]] +) -> None: + """Remove confirmed orphan objects and refresh affected data panels.""" + touched: dict[int, BaseDataPanel] = {} + for data_panel, orphan_uuid in alive_orphans: + if data_panel.objmodel.has_uuid(orphan_uuid): + remove_data_object(data_panel, orphan_uuid) + touched[id(data_panel)] = data_panel + for data_panel in touched.values(): + data_panel.objview.update_tree() + data_panel.selection_changed(update_items=True) + panel.runtime.objects.refresh_obj_ids_snapshot() + + +def refresh_history_after_deletion(panel: HistoryPanel) -> None: + """Refresh history presentation after applying a deletion.""" panel.tree.populate_tree(panel.history_sessions) panel.refresh_compatibility_items() - panel.update_actions_state() - # Auto-select an item in the same session to avoid panel switch + panel.ui.update_actions_state() + + +def select_after_deletion(panel: HistoryPanel, result: DeletionResult) -> None: + """Select the last action of the affected surviving session, or a fallback.""" target_item = None - if affected_session is not None and id(affected_session) not in sessions_to_remove: - # Find the tree item for the affected session (same index in list) + affected_session = result.affected_session + if ( + affected_session is not None + and id(affected_session) not in result.removed_session_ids + ): try: session_idx = panel.history_sessions.index(affected_session) except ValueError: @@ -563,14 +583,28 @@ def delete_selected(panel: HistoryPanel) -> None: iterator += 1 target_item = last_action_item if last_action_item is not None else top if target_item is None and panel.tree.topLevelItemCount() > 0: - # Fallback: last top-level item (least likely to switch panels) - last_top = panel.tree.topLevelItem(panel.tree.topLevelItemCount() - 1) - target_item = last_top + target_item = panel.tree.topLevelItem(panel.tree.topLevelItemCount() - 1) if target_item is not None: panel.tree.setCurrentItem(target_item) target_item.setSelected(True) +def delete_selected(panel: HistoryPanel) -> None: + """Delete selected actions or sessions through explicit GUI/mutation phases.""" + selected = panel.tree.get_selected_actions_or_sessions(panel.history_sessions) + if not selected: + return + plan = plan_deletion(panel, selected) + if not confirm_deletion(panel, plan): + return + result = apply_deletion(panel, plan) + alive_orphans = collect_alive_orphans(panel, result.orphan_refs) + if confirm_orphan_removal(panel, alive_orphans): + remove_orphan_objects(panel, alive_orphans) + refresh_history_after_deletion(panel) + select_after_deletion(panel, result) + + def remove_incompatible_actions(panel: HistoryPanel) -> None: """Remove all actions whose workspace state is incompatible. @@ -608,9 +642,10 @@ def remove_incompatible_actions(panel: HistoryPanel) -> None: return for session, action in incompatible: if action in session.actions: + panel.runtime.objects.remove_action_outputs(action) session.actions.remove(action) # Remove empty sessions panel.history_sessions = [s for s in panel.history_sessions if s.actions] panel.tree.populate_tree(panel.history_sessions) panel.refresh_compatibility_items() - panel.update_actions_state() + panel.ui.update_actions_state() diff --git a/datalab/gui/main.py b/datalab/gui/main.py index b63273a49..a6a86783d 100644 --- a/datalab/gui/main.py +++ b/datalab/gui/main.py @@ -2762,11 +2762,12 @@ def close_properly(self) -> bool: if self.webapi_actions is not None: self.webapi_actions.cleanup() self.reset_all() - self.__save_pos_size_and_state() + if not env.execenv.unattended: + self.__save_pos_size_and_state() self.__unregister_plugins() # Saving current tab for next session - if self.tabwidget is not None: + if not env.execenv.unattended and self.tabwidget is not None: Conf.main.current_tab.set(self.tabwidget.currentIndex()) execenv.log(self, "closed properly") diff --git a/datalab/gui/newobject.py b/datalab/gui/newobject.py index 1b646856f..2a6c3c0bd 100644 --- a/datalab/gui/newobject.py +++ b/datalab/gui/newobject.py @@ -10,8 +10,6 @@ """ -# pylint: disable=invalid-name # Allows short reference names like x, y, ... - from __future__ import annotations import guidata.dataset as gds @@ -23,52 +21,39 @@ from qtpy import QtWidgets as QW from sigima.objects import CustomSignalParam as OrigCustomSignalParam from sigima.objects import ( - Gauss2DParam, - ImageDatatypes, ImageObj, NewImageParam, NewSignalParam, SignalObj, - create_signal, ) -from sigima.objects import create_image_from_param as create_image_headless -from sigima.objects import create_signal_from_param as create_signal_headless -from sigima.objects.base import BaseProcParam -from sigima.objects.signal import DEFAULT_TITLE as SIGNAL_DEFAULT_TITLE from datalab.config import _ +from datalab.gui.creation import ( + CREATION_PARAMETERS_OPTION, + create_image_from_param, + create_signal_from_param, + extract_creation_parameters, + initialize_image_parameters, + insert_creation_parameters, + prepare_signal_parameters, +) -CREATION_PARAMETERS_OPTION = "creation_param_json" - - -def insert_creation_parameters(obj: SignalObj | ImageObj, param: gds.DataSet) -> None: - """Insert creation parameters into object metadata. - - Args: - param: creation parameters - """ - obj.set_metadata_option(CREATION_PARAMETERS_OPTION, gds.dataset_to_json(param)) - - -def extract_creation_parameters(obj: SignalObj | ImageObj) -> gds.DataSet | None: - """Extract creation parameters from object metadata. - - Returns: - Creation parameters or None if not found - """ - try: - param_json = obj.get_metadata_option(CREATION_PARAMETERS_OPTION) - except ValueError: - return None - return gds.json_to_dataset(param_json) +__all__ = [ + "CREATION_PARAMETERS_OPTION", + "create_image_gui", + "create_signal_gui", + "extract_creation_parameters", + "insert_creation_parameters", +] class CustomSignalParam(OrigCustomSignalParam): """Parameters for custom signal (e.g. manually defined experimental data)""" - def edit_curve(self, *args) -> None: # pylint: disable=unused-argument + def edit_curve(self, parent: QW.QWidget | None = None) -> None: """Edit custom curve""" win: PlotDialog = make.dialog( + parent=parent, wintitle=_("Select one point then press OK to accept"), edit=True, type="curve", @@ -78,8 +63,8 @@ def edit_curve(self, *args) -> None: # pylint: disable=unused-argument ) edit_tool.activate() plot = win.manager.get_plot() - x, y = self.xyarray[:, 0], self.xyarray[:, 1] - curve = make.mcurve(x, y, "-+") + x_values, y_values = self.xyarray[:, 0], self.xyarray[:, 1] + curve = make.mcurve(x_values, y_values, "-+") plot.add_item(curve) plot.set_active_item(curve) @@ -89,14 +74,26 @@ def edit_curve(self, *args) -> None: # pylint: disable=unused-argument exec_dialog(win) - new_x, new_y = curve.get_data() - self.xmax = new_x.max() - self.xmin = new_x.min() - self.size = new_x.size - self.xyarray = np.vstack((new_x, new_y)).T + new_x_values, new_y_values = curve.get_data() + self.xmax = new_x_values.max() + self.xmin = new_x_values.min() + self.size = new_x_values.size + self.xyarray = np.vstack((new_x_values, new_y_values)).T + + def edit_curve_callback( + self, + button_item: gds.ButtonItem, + current_value: object, + parent: QW.QWidget, + ) -> object: + """Handle the curve edit button callback.""" + if button_item.get_name() != "btn_curve_edit": + raise ValueError(f"Unexpected button item: {button_item.get_name()}") + self.edit_curve(parent) + return current_value btn_curve_edit = gds.ButtonItem( - "Edit curve", callback=edit_curve, icon="signal.svg" + "Edit curve", callback=edit_curve_callback, icon="signal.svg" ) @@ -118,49 +115,19 @@ def create_signal_gui( Raises: ValueError: if base_param is None and edit is False """ + param = prepare_signal_parameters(param, edit, parent) if param is None: - param = NewSignalParam() - edit = True # Default to editing if no parameters provided - - # CustomSignalParam requires edit mode to initialize the xyarray. - # Without this, if edit=False (the default in new_object), the setup_array - # call would be skipped, leaving xyarray as None, which would cause an - # AttributeError when trying to access param.xyarray.T later. - if isinstance(param, OrigCustomSignalParam): - edit = True - - if isinstance(param, OrigCustomSignalParam) and edit: - p_init = NewSignalParam(_("Custom signal")) - p_init.size = 10 # Set smaller default size for initial input - if not p_init.edit(parent=parent): - return None - param.setup_array(size=p_init.size, xmin=p_init.xmin, xmax=p_init.xmax) - - if edit: - if not param.edit(parent=parent): - return None - - if isinstance(param, OrigCustomSignalParam): - signal = create_signal(param.title) - signal.xydata = param.xyarray.T - if signal.title == SIGNAL_DEFAULT_TITLE: - signal.title = f"custom(npts={param.size})" - return signal + return None try: - signal = create_signal_headless(param) - except Exception as exc: # pylint: disable=broad-except + signal = create_signal_from_param(param) + except (ValueError, TypeError, RuntimeError, ArithmeticError) as exc: if parent is not None: QW.QMessageBox.warning(parent, _("Error"), str(exc)) else: raise ValueError(f"Error creating signal: {exc}") from exc signal = None - # Insert creation parameters into metadata, only if `param` is an instance of a - # class deriving from `NewSignalParam` (not an instance of `NewSignalParam` itself): - # pylint: disable=unidiomatic-typecheck - if isinstance(param, NewSignalParam) and type(param) is not NewSignalParam: - insert_creation_parameters(signal, param) return signal @@ -186,39 +153,19 @@ def create_image_gui( param = NewImageParam() edit = True # Default to editing if no parameters provided - if param.height is None: - param.height = 500 - if param.width is None: - param.width = 500 - if param.dtype is None: - param.dtype = ImageDatatypes.UINT16 - dtype: ImageDatatypes = param.dtype - numpy_dtype = dtype.to_numpy_dtype() - if isinstance(param, Gauss2DParam): - if param.a is None: - try: - param.a = np.iinfo(numpy_dtype).max / 2.0 - except ValueError: - param.a = 10.0 - elif isinstance(param, BaseProcParam): - param.set_from_datatype(numpy_dtype) + initialize_image_parameters(param) if edit: if not param.edit(parent=parent): return None try: - image = create_image_headless(param) - except Exception as exc: # pylint: disable=broad-except + image = create_image_from_param(param) + except (ValueError, TypeError, RuntimeError, ArithmeticError) as exc: if parent is not None: QW.QMessageBox.warning(parent, _("Error"), str(exc)) else: raise ValueError(f"Error creating image: {exc}") from exc return None - # Insert creation parameters into metadata, only if `param` is an instance of a - # class deriving from `NewImageParam` (not an instance of `NewImageParam` itself): - # pylint: disable=unidiomatic-typecheck - if isinstance(param, NewImageParam) and type(param) is not NewImageParam: - insert_creation_parameters(image, param) return image diff --git a/datalab/gui/panel/history/chain.py b/datalab/gui/panel/history/chain.py index 2dd62d78d..fbea141b1 100644 --- a/datalab/gui/panel/history/chain.py +++ b/datalab/gui/panel/history/chain.py @@ -5,16 +5,19 @@ from __future__ import annotations import logging -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING from qtpy import QtWidgets as QW from datalab.config import _ from datalab.env import execenv -from datalab.gui.panel.history import recompute as hrec -from datalab.gui.panel.history.chainmodel import action_input_uuids +from datalab.gui.panel.history.chainmodel import ( + ReconnectionPlan, + ReconnectionTarget, + action_input_uuids, + remap_processing_parameters, +) from datalab.gui.processor.base import ( - ProcessingParameters, extract_processing_parameters, insert_processing_parameters, ) @@ -38,23 +41,24 @@ def find_parent_session( return None +def action_panel_target(action: HistoryAction) -> str | None: + """Return the main-window data-panel attribute targeted by ``action``.""" + if action.kind == HistoryAction.KIND_UI: + if action.method_name in HistoryAction.UI_CREATION_METHODS: + return action.target + return None + return {"signal": "signalpanel", "image": "imagepanel"}.get(action.panel_str) + + def resolve_panel_for_action( panel: HistoryPanel, action: HistoryAction ) -> BaseDataPanel | None: """Return the data panel targeted by ``action``, or ``None``.""" - if action.kind == HistoryAction.KIND_UI: - if action.method_name not in HistoryAction.UI_CREATION_METHODS: - return None - if action.target == "signalpanel": - return panel.mainwindow.signalpanel - if action.target == "imagepanel": - return panel.mainwindow.imagepanel - return None - if action.panel_str == "signal": - return panel.mainwindow.signalpanel - if action.panel_str == "image": - return panel.mainwindow.imagepanel - return None + panels = { + "signalpanel": panel.mainwindow.signalpanel, + "imagepanel": panel.mainwindow.imagepanel, + } + return panels.get(action_panel_target(action)) def find_output_object_uuid( @@ -65,7 +69,7 @@ def find_output_object_uuid( Primary path: consult the bijective ``action_output_uuids`` mapping. Fallback path: legacy heuristic on ``processing_parameters`` metadata. """ - registered = panel.action_output_uuids.get(action.uuid) + registered = panel.runtime.objects.action_output_uuids.get(action.uuid) if registered: existing_ids = set(panel_data.objmodel.get_object_ids()) for out_uuid in registered: @@ -93,7 +97,7 @@ def find_action_for_output( """Find the :class:`HistoryAction` that produced ``output_uuid``.""" if not panel.history_sessions: return None - action_uuid = panel.output_to_action.get(output_uuid) + action_uuid = panel.runtime.objects.output_to_action.get(output_uuid) if action_uuid is not None: mapped = next( ( @@ -146,7 +150,7 @@ def find_creation_action_for_output( """ if not panel.history_sessions: return None - action_uuid = panel.output_to_action.get(output_uuid) + action_uuid = panel.runtime.objects.output_to_action.get(output_uuid) if action_uuid is not None: mapped = next( ( @@ -164,7 +168,8 @@ def find_creation_action_for_output( if ( action.kind == HistoryAction.KIND_UI and action.method_name in HistoryAction.UI_CREATION_METHODS - and output_uuid in panel.action_output_uuids.get(action.uuid, []) + and output_uuid + in panel.runtime.objects.action_output_uuids.get(action.uuid, []) ): return action return None @@ -218,15 +223,7 @@ def action_consumes_any(action: HistoryAction, uuids: set[str]) -> bool: """Return True if ``action``'s input UUIDs intersect ``uuids``.""" if action.kind != HistoryAction.KIND_COMPUTE: return False - pstr = action.panel_str or "" - captured: set[str] = set(action.state.selection.get(pstr, [])) - obj2 = action.kwargs.get("obj2_uuids") - if obj2: - if isinstance(obj2, str): - captured.add(obj2) - else: - captured.update(obj2) - return bool(captured & uuids) + return bool(action_input_uuids(action) & uuids) def get_downstream_actions( @@ -260,7 +257,7 @@ def resolve_target_outputs( panel: HistoryPanel, panel_data: BaseDataPanel, action: HistoryAction ) -> tuple[list[str], list[str]]: """Return ``(existing, missing)`` UUIDs registered for ``action``.""" - registered = list(panel.action_output_uuids.get(action.uuid, [])) + registered = list(panel.runtime.objects.action_output_uuids.get(action.uuid, [])) existing_ids = set(panel_data.objmodel.get_object_ids()) existing: list[str] = [u for u in registered if u in existing_ids] missing: list[str] = [u for u in registered if u not in existing_ids] @@ -275,14 +272,7 @@ def existing_input_uuids(panel_data: BaseDataPanel, action: HistoryAction) -> li def prune_output_mapping(panel: HistoryPanel) -> None: """Drop entries of :attr:`output_to_action` whose object no longer exists.""" - if not panel.output_to_action: - return - alive: set[str] = set() - for pdata in (panel.mainwindow.signalpanel, panel.mainwindow.imagepanel): - alive.update(pdata.objmodel.get_object_ids()) - stale = [u for u in panel.output_to_action if u not in alive] - for u in stale: - panel.output_to_action.pop(u, None) + panel.runtime.objects.prune_output_mapping() def rewrite_action_source( @@ -308,118 +298,140 @@ def remove_single_action(panel: HistoryPanel, action: HistoryAction) -> None: for session in panel.history_sessions: if action in session.actions: session.actions.remove(action) - outs = panel.action_output_uuids.pop(action.uuid, []) - for out_uuid in outs: - if panel.output_to_action.get(out_uuid) == action.uuid: - panel.output_to_action.pop(out_uuid, None) + panel.runtime.objects.remove_action_outputs(action) if not session.actions: panel.history_sessions.remove(session) break -def reconnect_single_removed( +def find_reconnection_source( + panel: HistoryPanel, panel_str: str, output_uuid: str +) -> tuple[HistoryAction | None, str | None]: + """Return the action and source UUID behind a removed output.""" + action_uuid = panel.runtime.objects.output_to_action.get(output_uuid) + if action_uuid is None: + return None, None + for session in panel.history_sessions: + for action in session.actions: + if action.uuid == action_uuid: + selection = action.state.selection.get(panel_str, []) + source_uuid = selection[0] if selection else None + return action, source_uuid + return None, None + + +def plan_reconnection( panel: HistoryPanel, panel_data: BaseDataPanel, - x_uuid: str, - warnings: list[str], - roots_to_recompute: list[HistoryAction], -) -> None: - """Reconnect consumers of a single deleted object ``x_uuid``.""" - pstr = panel_data.PANEL_STR_ID - action_a = None - action_a_uuid = panel.output_to_action.get(x_uuid) - if action_a_uuid is not None: - for session in panel.history_sessions: - for a in session.actions: - if a.uuid == action_a_uuid: - action_a = a - break - if action_a is not None: - break - consumers: list[tuple[Any, Any]] = [] + removed_uuid: str, +) -> ReconnectionPlan: + """Build a reconnection plan without mutating history or data objects.""" + panel_str = panel_data.PANEL_STR_ID + producer_action, source_uuid = find_reconnection_source( + panel, panel_str, removed_uuid + ) + plan = ReconnectionPlan( + panel_str=panel_str, + removed_uuid=removed_uuid, + source_uuid=source_uuid, + producer_action=producer_action, + ) for obj in panel_data.objmodel: - pp = extract_processing_parameters(obj) - if pp is None: + parameters = extract_processing_parameters(obj) + if parameters is None: continue - if pp.source_uuid == x_uuid or (pp.source_uuids and x_uuid in pp.source_uuids): - consumers.append((obj, pp)) - if not consumers: - return - s_uuid: str | None = None - if action_a is not None: - sel = action_a.state.selection.get(pstr, []) - if sel: - s_uuid = sel[0] + consumes_removed = parameters.source_uuid == removed_uuid or ( + parameters.source_uuids and removed_uuid in parameters.source_uuids + ) + if not consumes_removed: + continue + action = None + if parameters.func_name: + action = find_action_for_output(panel, get_uuid(obj), parameters.func_name) + plan.targets.append(ReconnectionTarget(get_uuid(obj), parameters, action)) + if not plan.targets: + return plan alive_ids = set(panel_data.objmodel.get_object_ids()) - if s_uuid is None or s_uuid not in alive_ids: - label = action_a.title or action_a.func_name if action_a is not None else x_uuid - warnings.append( + if source_uuid is None or source_uuid not in alive_ids: + label = removed_uuid + if producer_action is not None: + label = producer_action.title or producer_action.func_name or removed_uuid + plan.warning = ( _( "“%s” has dependent operations but no valid source to " "reconnect to — downstream results are left unchanged." ) % label ) + return plan + if producer_action is not None: + outputs = panel.runtime.objects.action_output_uuids.get( + producer_action.uuid, [] + ) + plan.remove_producer = not any(output in alive_ids for output in outputs) + return plan + + +def apply_reconnection_plan( + panel: HistoryPanel, + panel_data: BaseDataPanel, + plan: ReconnectionPlan, + roots_to_recompute: list[HistoryAction], +) -> None: + """Apply object and action source rewrites described by ``plan``.""" + if plan.warning is not None or plan.source_uuid is None: return - for obj, pp in consumers: - new_source_uuid = s_uuid if pp.source_uuid == x_uuid else pp.source_uuid - new_source_uuids = pp.source_uuids - if pp.source_uuids and x_uuid in pp.source_uuids: - new_source_uuids = [s_uuid if u == x_uuid else u for u in pp.source_uuids] + for target in plan.targets: + if not panel_data.objmodel.has_uuid(target.object_uuid): + continue + obj = panel_data.objmodel[target.object_uuid] insert_processing_parameters( obj, - ProcessingParameters( - func_name=pp.func_name, - pattern=pp.pattern, - param=pp.param, - source_uuid=new_source_uuid, - source_uuids=new_source_uuids, + remap_processing_parameters( + target.parameters, {plan.removed_uuid: plan.source_uuid} ), ) - if pp.func_name: - action_b = find_action_for_output(panel, get_uuid(obj), pp.func_name) - if action_b is not None: - rewrite_action_source(action_b, pstr, x_uuid, s_uuid) - if action_b not in roots_to_recompute: - roots_to_recompute.append(action_b) - if action_a is not None: - outs = panel.action_output_uuids.get(action_a.uuid, []) - if not any(o in alive_ids for o in outs): - remove_single_action(panel, action_a) - - -def reconnect_chain_after_removal( - panel: HistoryPanel, panel_data: BaseDataPanel -) -> None: - """Reconnect the processing chain after object(s) were deleted from a data panel.""" - pstr = panel_data.PANEL_STR_ID - previous = panel.obj_ids_snapshot.get(pstr, set()) - current = set(panel_data.objmodel.get_object_ids()) - removed = previous - current - if not removed or panel.reconnecting: - return - panel.reconnecting = True - try: - warnings: list[str] = [] - roots_to_recompute: list[HistoryAction] = [] - for x_uuid in removed: - reconnect_single_removed( - panel, panel_data, x_uuid, warnings, roots_to_recompute + if target.action is not None: + rewrite_action_source( + target.action, + plan.panel_str, + plan.removed_uuid, + plan.source_uuid, ) - for action in roots_to_recompute: - hrec.recompute_action_in_place(panel, action) - hrec.recompute_cascade(panel, action) - if warnings and not execenv.unattended: - QW.QMessageBox.warning( - panel.mainwindow, - _("Delete"), - _("Some operations could not be reconnected after deletion:") - + "\n\n• " - + "\n• ".join(warnings), - ) - panel.tree.populate_tree(panel.history_sessions) - panel.refresh_compatibility_items() - panel.update_actions_state() - finally: - panel.reconnecting = False - panel.refresh_obj_ids_snapshot() + if target.action not in roots_to_recompute: + roots_to_recompute.append(target.action) + if plan.remove_producer and plan.producer_action is not None: + remove_single_action(panel, plan.producer_action) + + +def reconnect_single_removed( + panel: HistoryPanel, + panel_data: BaseDataPanel, + removed_uuid: str, + warnings: list[str], + roots_to_recompute: list[HistoryAction], +) -> None: + """Plan and reconnect consumers of one deleted object.""" + plan = plan_reconnection(panel, panel_data, removed_uuid) + apply_reconnection_plan(panel, panel_data, plan, roots_to_recompute) + if plan.warning is not None: + warnings.append(plan.warning) + + +def show_reconnection_warnings(panel: HistoryPanel, warnings: list[str]) -> None: + """Show reconnection warnings at the GUI boundary.""" + if warnings and not execenv.unattended: + QW.QMessageBox.warning( + panel.mainwindow, + _("Delete"), + _("Some operations could not be reconnected after deletion:") + + "\n\n• " + + "\n• ".join(warnings), + ) + + +def refresh_reconnected_history(panel: HistoryPanel) -> None: + """Refresh the history tree after applying reconnection plans.""" + panel.tree.populate_tree(panel.history_sessions) + panel.refresh_compatibility_items() + panel.ui.update_actions_state() diff --git a/datalab/gui/panel/history/chainmodel.py b/datalab/gui/panel/history/chainmodel.py index 1f62f9cf7..ec0017943 100644 --- a/datalab/gui/panel/history/chainmodel.py +++ b/datalab/gui/panel/history/chainmodel.py @@ -5,8 +5,9 @@ from __future__ import annotations from dataclasses import dataclass, field -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Any +from datalab.gui.processor.base import ProcessingParameters from datalab.history import HistoryAction, HistorySession if TYPE_CHECKING: @@ -30,6 +31,85 @@ class ProcessingChain: actions: list[HistoryAction] = field(default_factory=list) +@dataclass +class ChainSelectionPlan: + """Processing chains selected from one source session.""" + + source_session: HistorySession + chains: list[ProcessingChain] + + +@dataclass +class UuidCloneRegistry: + """Objects cloned for duplication and their UUID remapping by panel.""" + + uuid_remap: dict[str, dict[str, str]] = field(default_factory=dict) + clones_by_panel: dict[str, list[Any]] = field(default_factory=dict) + + def register( + self, + panel_str: str, + old_uuid: str, + new_uuid: str, + clone: Any, + ) -> None: + """Register a cloned object and its source-to-clone UUID mapping.""" + self.uuid_remap.setdefault(panel_str, {})[old_uuid] = new_uuid + self.clones_by_panel.setdefault(panel_str, []).append(clone) + + def resolve(self, panel_str: str, old_uuid: str) -> str | None: + """Return the cloned UUID corresponding to a source UUID.""" + return self.uuid_remap.get(panel_str, {}).get(old_uuid) + + +@dataclass +class DuplicatedSession: + """A duplicated session paired with the source that determines insertion.""" + + source_session: HistorySession + new_session: HistorySession + + +@dataclass +class DeletionPlan: + """Selected history entities grouped by their deletion behavior.""" + + actions: list[HistoryAction] = field(default_factory=list) + session_ids: set[int] = field(default_factory=set) + affected_session: HistorySession | None = None + + +@dataclass +class DeletionResult: + """State needed for orphan cleanup and post-deletion selection.""" + + affected_session: HistorySession | None + removed_session_ids: set[int] + orphan_refs: list[tuple[str, str]] = field(default_factory=list) + + +@dataclass +class ReconnectionTarget: + """A surviving object and history action consuming a removed UUID.""" + + object_uuid: str + parameters: ProcessingParameters + action: HistoryAction | None + + +@dataclass +class ReconnectionPlan: + """Planned source rewrites after one data object has been removed.""" + + panel_str: str + removed_uuid: str + source_uuid: str | None + producer_action: HistoryAction | None + targets: list[ReconnectionTarget] = field(default_factory=list) + warning: str | None = None + remove_producer: bool = False + + def action_input_uuids(action: HistoryAction) -> set[str]: """Return the set of input object UUIDs captured by ``action``. @@ -52,9 +132,28 @@ def action_input_uuids(action: HistoryAction) -> set[str]: return captured -def build_session_chains( - panel: HistoryPanel, session: HistorySession -) -> list[ProcessingChain]: +def remap_processing_parameters( + parameters: ProcessingParameters, + uuid_remap: dict[str, str], + clear_sources: bool = False, +) -> ProcessingParameters: + """Rebuild processing parameters with remapped source UUIDs.""" + source_uuid = None if clear_sources else parameters.source_uuid + if source_uuid is not None: + source_uuid = uuid_remap.get(source_uuid, source_uuid) + source_uuids = None if clear_sources else parameters.source_uuids + if source_uuids is not None: + source_uuids = [uuid_remap.get(uuid, uuid) for uuid in source_uuids] + return ProcessingParameters( + func_name=parameters.func_name, + pattern=parameters.pattern, + param=parameters.param, + source_uuid=source_uuid, + source_uuids=source_uuids, + ) + + +def build_session_chains(session: HistorySession) -> list[ProcessingChain]: """Return the session's single processing chain. In DataLab's history model a session **is** a single linear processing @@ -64,7 +163,6 @@ def build_session_chains( per-creation splitting is performed here. Args: - panel: The history panel (kept for signature stability; unused). session: The session whose actions form the chain. Returns: @@ -90,6 +188,5 @@ def build_processing_chains( A list of (session, chains) tuples in session order. """ return [ - (session, build_session_chains(panel, session)) - for session in panel.history_sessions + (session, build_session_chains(session)) for session in panel.history_sessions ] diff --git a/datalab/gui/panel/history/facade.py b/datalab/gui/panel/history/facade.py new file mode 100644 index 000000000..714f03b29 --- /dev/null +++ b/datalab/gui/panel/history/facade.py @@ -0,0 +1,285 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +"""Public History panel facade facets backed by cohesive components.""" + +from __future__ import annotations + +from contextlib import contextmanager +from typing import TYPE_CHECKING, Any, Generator + +from qtpy import QtWidgets as QW + +from datalab.config import _ +from datalab.env import execenv +from datalab.gui import historysession_ops as hsess +from datalab.gui.panel.history import chain as hchain +from datalab.gui.panel.history import interactive_replay as hreplay +from datalab.gui.panel.history import recompute as hrec +from datalab.gui.panel.history import reconnection as hconnect +from datalab.h5 import history as hio +from datalab.history import HistoryAction, HistorySession + +if TYPE_CHECKING: + from datalab.h5.native import NativeH5Reader, NativeH5Writer + + +class HistoryRuntimeFacadeMixin: + """Expose runtime controls required by panels, processors, and tests.""" + + def reconnect_chain_after_removal(self, data_panel: Any) -> None: + """Reconnect chains after objects are removed from a data panel.""" + hconnect.reconnect_chain_after_removal(self, data_panel) + + def set_tracking_enabled(self, enabled: bool) -> None: + """Enable or disable synchronization with data panel object changes.""" + self.runtime.objects.set_tracking_enabled(enabled) + + @property + def record_mode_enabled(self) -> bool: + """Return whether record mode is enabled.""" + return self.runtime.execution.record_mode + + def toggle_edit_mode(self, checked: bool) -> None: + """Toggle edit mode, committing pending edits when it is disabled.""" + has_pending_edits = any( + action.has_pending_edits + for session in self.history_sessions + for action in session.actions + ) + if not checked and has_pending_edits: + reply = ( + QW.QMessageBox.Yes + if execenv.unattended + else QW.QMessageBox.question( + self.mainwindow, + _("Commit edit mode changes?"), + _( + "You are about to exit Edit mode.\n\n" + "All parameter changes made during this session will be " + "permanently kept.\n" + "This action cannot be undone — Restore will no longer " + "be available.\n\n" + "Do you want to continue?" + ), + QW.QMessageBox.Yes | QW.QMessageBox.No, + QW.QMessageBox.No, + ) + ) + if reply != QW.QMessageBox.Yes: + return + self.runtime.execution.edit_mode = checked + if not checked: + for session in self.history_sessions: + for action in session.actions: + action.discard_snapshot() + self.ui.update_actions_state() + + def toggle_record_mode(self, checked: bool) -> None: + """Toggle record mode.""" + self.runtime.execution.record_mode = checked + + def is_edit_mode(self) -> bool: + """Return whether the History panel is in edit mode.""" + return self.runtime.execution.edit_mode + + @contextmanager + def replaying(self) -> Generator[None, None, None]: + """Suppress history capture during the context scope.""" + with self.runtime.execution.replaying(): + yield + + def is_replaying(self) -> bool: + """Return whether an external replay or recompute is in progress.""" + return self.runtime.execution.replaying_active + + @contextmanager + def output_suppressed(self) -> Generator[None, None, None]: + """Suppress compute outputs during the context scope.""" + with self.runtime.execution.output_suppressed(): + yield + + def is_output_suppressed(self) -> bool: + """Return whether compute outputs must not be added to panels.""" + return self.runtime.execution.output_suppressed_active + + +class HistoryReplayFacadeMixin: + """Expose replay and chain lookups consumed outside the history package.""" + + def replay_restore_actions( + self, replay: bool = True, restore_selection: bool = True + ) -> None: + """Replay and/or restore selection for selected actions.""" + hreplay.replay_restore_actions(self, replay, restore_selection) + + def replay_step_by_step(self) -> None: + """Replay the current selection with parameter dialogs.""" + previous = self.runtime.execution.edit_mode + self.runtime.execution.edit_mode = True + try: + self.replay_restore_actions(replay=True, restore_selection=False) + finally: + self.runtime.execution.edit_mode = previous + for session in self.history_sessions: + for action in session.actions: + action.discard_snapshot() + self.ui.update_actions_state() + + def find_action_for_output( + self, output_uuid: str, func_name: str + ) -> HistoryAction | None: + """Return the action that produced an output UUID.""" + return hchain.find_action_for_output(self, output_uuid, func_name) + + def find_creation_action_for_output(self, output_uuid: str) -> HistoryAction | None: + """Return the creation action that produced an output UUID.""" + return hchain.find_creation_action_for_output(self, output_uuid) + + def find_analysis_action( + self, obj_uuid: str, func_name: str + ) -> HistoryAction | None: + """Return the matching analysis action for an object UUID.""" + return hchain.find_analysis_action(self, obj_uuid, func_name) + + def action_output_uuid(self, action: HistoryAction) -> str | None: + """Return the UUID of the object produced by an action.""" + return hchain.action_output_uuid(self, action) + + def refresh_action(self, action: HistoryAction) -> None: + """Refresh an action after its arguments are mutated.""" + hrec.refresh_action(self, action) + + def recompute_cascade( + self, + root_action: HistoryAction, + descendants: list[HistoryAction] | None = None, + ) -> None: + """Recompute descendants of a root action in place.""" + hrec.recompute_cascade(self, root_action, descendants) + + def on_current_panel_changed(self, panel_str: str) -> None: + """React to a Signal/Image panel switch.""" + self.navigation.on_current_panel_changed(panel_str) + + +class HistoryRecordingFacadeMixin: + """Expose history-session recording operations used by application code.""" + + def create_new_session(self, panel_str: str | None = None) -> HistorySession: + """Create a new history session for a data panel.""" + return hsess.create_new_session(self, panel_str=panel_str) + + def start_new_session_after_workspace_reset(self) -> None: + """Start a history session after a workspace reset when useful.""" + hsess.start_new_session_after_workspace_reset(self) + + def maybe_start_session_for_input(self, *, load: bool = False) -> None: + """Offer to start a new session before recording an input.""" + hsess.maybe_start_session_for_input(self, load=load) + + @contextmanager + def session_prompt_suppressed(self) -> Generator[None, None, None]: + """Suppress the new-session prompt during a batch load.""" + with self.runtime.execution.session_prompt_suppressed(): + yield + + def add_compute_entry( + self, + action_title: str, + panel_str: str, + func_name: str, + pattern: str, + save_state: bool = True, + output_uuids: list[str] | None = None, + plugin_origin: dict[str, Any] | None = None, + **kwargs: Any, + ) -> HistoryAction | None: + """Add a compute entry to history.""" + return hsess.add_compute_entry( + self, + action_title, + panel_str, + func_name, + pattern, + save_state, + output_uuids, + plugin_origin, + **kwargs, + ) + + def add_compute_entry_from_pp( + self, + action_title: str, + pp: Any, + panel_str: str, + save_state: bool = True, + output_uuids: list[str] | None = None, + plugin_origin: dict[str, Any] | None = None, + **extras: Any, + ) -> HistoryAction | None: + """Add a compute entry built from processing parameters.""" + return hsess.add_compute_entry_from_pp( + self, + action_title, + pp, + panel_str, + save_state, + output_uuids, + plugin_origin, + **extras, + ) + + def register_action_outputs( + self, action: HistoryAction, output_uuids: list[str] + ) -> None: + """Register output UUIDs produced by an action.""" + hsess.register_action_outputs(self, action, output_uuids) + + def capture_outputs( + self, action: HistoryAction | None + ) -> Generator[None, None, None]: + """Return a context manager capturing outputs produced by an action.""" + return hsess.capture_outputs(self, action) + + def add_ui_entry( + self, + action_title: str, + target: str, + method_name: str, + save_state: bool = True, + **kwargs: Any, + ) -> HistoryAction | None: + """Add a UI entry to history.""" + return hsess.add_ui_entry( + self, action_title, target, method_name, save_state, **kwargs + ) + + +class HistoryPersistenceFacadeMixin: + """Expose standalone and workspace HDF5 persistence operations.""" + + def save_to_dlhist_file(self, filename: str | None = None) -> bool: + """Save history to a standalone history file.""" + return hio.save_to_dlhist_file(self, filename) + + def open_dlhist_file(self, filename: str | None = None) -> bool: + """Open history from a standalone history file.""" + return hio.open_dlhist_file(self, filename) + + def import_dlhist_into_new_session(self, reader: NativeH5Reader) -> None: + """Import standalone history into a new session.""" + hio.import_dlhist_into_new_session(self, reader) + + def refresh_compatibility_items(self, *args: Any) -> None: + """Refresh compatibility icons in the history tree.""" + hio.refresh_compatibility_items(self, *args) + + def serialize_to_hdf5(self, writer: NativeH5Writer) -> None: + """Serialize history sessions to HDF5.""" + hio.serialize_to_hdf5(self, writer) + + def deserialize_from_hdf5( + self, reader: NativeH5Reader, reset_all: bool = False + ) -> None: + """Deserialize history sessions from HDF5.""" + hio.deserialize_from_hdf5(self, reader, reset_all) diff --git a/datalab/gui/panel/history/interactive_replay.py b/datalab/gui/panel/history/interactive_replay.py index 96e068a28..f2a97172d 100644 --- a/datalab/gui/panel/history/interactive_replay.py +++ b/datalab/gui/panel/history/interactive_replay.py @@ -6,7 +6,8 @@ import copy import logging -from typing import TYPE_CHECKING +from dataclasses import dataclass +from typing import TYPE_CHECKING, Any import guidata.dataset as gds from qtpy import QtWidgets as QW @@ -22,6 +23,14 @@ _logger = logging.getLogger(__name__) +@dataclass +class ActionParamEdit: + """Parameter dialog target and action kwargs to update after acceptance.""" + + dialog_target: gds.DataSet | gds.DataSetGroup + new_kwargs: dict[str, Any] + + def replay_restore_actions( panel: HistoryPanel, replay: bool = True, restore_selection: bool = True ) -> None: @@ -48,7 +57,9 @@ def replay_restore_actions( ) return if replay: - if panel.edit_mode and isinstance(session_or_action, HistoryAction): + if panel.runtime.execution.edit_mode and isinstance( + session_or_action, HistoryAction + ): # Defer: edit only the selected actions, no automatic cascade edit_actions.append(session_or_action) else: @@ -58,10 +69,14 @@ def replay_restore_actions( session_or_action.replay( panel.mainwindow, restore_selection=restore_selection, - edit=panel.edit_mode, + edit=panel.runtime.execution.edit_mode, ) elif restore_selection: - if panel.edit_mode or panel.has_any_pending_edits(): + if panel.runtime.execution.edit_mode or any( + action.has_pending_edits + for session in panel.history_sessions + for action in session.actions + ): restore_action_params(panel, session_or_action) else: session_or_action.restore(panel.mainwindow) @@ -69,44 +84,42 @@ def replay_restore_actions( edit_mode_replay_actions(panel, edit_actions) -def prompt_edit_action_params( - panel: HistoryPanel, action: HistoryAction -) -> bool | None: - """Open the parameter dialog for *action* according to its pattern.""" +def prepare_action_param_edit(action: HistoryAction) -> ActionParamEdit | None: + """Prepare the editable parameter copy for ``action``.""" + result = None if ( action.kind == HistoryAction.KIND_UI and action.method_name in HistoryAction.UI_CREATION_METHODS ): param = action.kwargs.get("param") - if param is None: - return None - edited = copy.deepcopy(param) - if not edited.edit(parent=panel.mainwindow): - return False - action.snapshot_kwargs() - action.kwargs["param"] = edited - return True - pattern = action.pattern - if pattern in {"1_to_1", "1_to_0", "n_to_1", "2_to_1"}: + if param is not None: + edited = copy.deepcopy(param) + result = ActionParamEdit(edited, {"param": edited}) + elif action.pattern in {"1_to_1", "1_to_0", "n_to_1", "2_to_1"}: param = action.kwargs.get("param") - if param is None: - return None - edited = copy.deepcopy(param) - dialog_target: gds.DataSet | gds.DataSetGroup = edited - new_kwargs = {"param": edited} - elif pattern == "1_to_n": + if param is not None: + edited = copy.deepcopy(param) + result = ActionParamEdit(edited, {"param": edited}) + elif action.pattern == "1_to_n": params = action.kwargs.get("params") or [] - if not params: - return None - edited_params = [copy.deepcopy(p) for p in params] - dialog_target = gds.DataSetGroup(edited_params, title=_("Parameters")) - new_kwargs = {"params": edited_params} - else: + if params: + edited_params = [copy.deepcopy(p) for p in params] + dialog_target = gds.DataSetGroup(edited_params, title=_("Parameters")) + result = ActionParamEdit(dialog_target, {"params": edited_params}) + return result + + +def prompt_edit_action_params( + panel: HistoryPanel, action: HistoryAction +) -> bool | None: + """Open the parameter dialog for *action* according to its pattern.""" + edit = prepare_action_param_edit(action) + if edit is None: return None - if not dialog_target.edit(parent=panel.mainwindow): + if not edit.dialog_target.edit(parent=panel.mainwindow): return False action.snapshot_kwargs() - action.kwargs.update(new_kwargs) + action.kwargs.update(edit.new_kwargs) return True @@ -117,14 +130,13 @@ def edit_mode_replay_actions(panel: HistoryPanel, actions: list[HistoryAction]) downstream actions are left untouched (no automatic cascade). A re-entrance guard prevents nested prompt loops. """ - if panel.edit_replay_in_progress: - return # Deduplicate and sort the selected actions in their session order ordered = order_selected_actions(panel, actions) if not ordered: return - panel.edit_replay_in_progress = True - try: + with panel.runtime.execution.replaying_edits() as started: + if not started: + return edited_actions: list[HistoryAction] = [] recomputable: list[HistoryAction] = [] for action in ordered: @@ -157,8 +169,6 @@ def edit_mode_replay_actions(panel: HistoryPanel, actions: list[HistoryAction]) if edited_actions: hrec.recompute_cascade(panel, edited_actions[0]) QW.QApplication.processEvents() - finally: - panel.edit_replay_in_progress = False def order_selected_actions( @@ -206,4 +216,4 @@ def restore_action_params( panel.tree.refresh_action_item(action) hrec.recompute_action_in_place(panel, action) hrec.recompute_cascade(panel, action) - panel.update_actions_state() + panel.ui.update_actions_state() diff --git a/datalab/gui/panel/history/navigation.py b/datalab/gui/panel/history/navigation.py new file mode 100644 index 000000000..1661d6a3a --- /dev/null +++ b/datalab/gui/panel/history/navigation.py @@ -0,0 +1,241 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +"""Selection, active-session, and step navigation for the History panel.""" + +from __future__ import annotations + +from typing import TYPE_CHECKING + +from qtpy import QtCore as QC +from qtpy import QtWidgets as QW + +from datalab.gui.panel.history import chain as hchain +from datalab.history import HistoryAction, HistorySession + +if TYPE_CHECKING: + from datalab.gui.panel.history.panel import HistoryPanel + + +class HistoryNavigation: + """Coordinate history selection, active sessions, and step navigation.""" + + def __init__(self, panel: HistoryPanel) -> None: + self.panel = panel + self.syncing = False + self.active_session_by_panel: dict[str, HistorySession] = {} + self.session_increment = 0 + + def current_action(self) -> HistoryAction | None: + """Return the action currently selected in the tree.""" + item = self.panel.tree.currentItem() + if item is None or item.parent() is None: + return None + uuid = item.data(0, QC.Qt.UserRole) + try: + return self.panel.tree.get_action_from_uuid( + uuid, self.panel.history_sessions + ) + except ValueError: + return None + + def current_panel_str(self) -> str: + """Return the current data panel identifier, defaulting to signal.""" + panel_str = self.panel.mainwindow.get_current_panel() + return panel_str if panel_str in ("signal", "image") else "signal" + + def sync_panel_selection(self) -> None: + """Synchronize data-panel selection from the selected history item.""" + if self.panel.runtime.execution.replaying_active or self.syncing: + return + item = self.panel.tree.currentItem() + if item is None or not item.isSelected(): + return + if item.parent() is None: + index = self.panel.tree.indexOfTopLevelItem(item) + if index < 0 or index >= len(self.panel.history_sessions): + return + session = self.panel.history_sessions[index] + action = next( + ( + candidate + for candidate in session.actions + if candidate.kind == HistoryAction.KIND_COMPUTE + ), + None, + ) + else: + action = self.current_action() + if action is None: + return + data_panel = hchain.resolve_panel_for_action(self.panel, action) + if data_panel is None: + return + output_uuid = hchain.find_output_object_uuid(self.panel, data_panel, action) + target_uuids = ( + [output_uuid] + if output_uuid is not None + else hchain.existing_input_uuids(data_panel, action) + ) + if not target_uuids: + return + self.syncing = True + try: + with QC.QSignalBlocker(data_panel.objview): + data_panel.objview.select_objects(target_uuids) + self.panel.mainwindow.set_current_panel(data_panel) + finally: + self.syncing = False + + def update_state_widget(self) -> None: + """Display the workspace state of the selected action.""" + action = self.current_action() + self.panel.ui.state_widget.update_from_state( + action.state if action is not None else None + ) + + def session_panel_str(self, session: HistorySession) -> str | None: + """Return the data panel to which a session belongs.""" + for action in session.actions: + if action.panel_str: + return action.panel_str + for panel_str, active_session in self.active_session_by_panel.items(): + if active_session is session: + return panel_str + return None + + def get_active_session(self, panel_str: str) -> HistorySession | None: + """Return the valid active recording session for a data panel.""" + session = self.active_session_by_panel.get(panel_str) + if session is not None and session in self.panel.history_sessions: + return session + return None + + def set_active_session( + self, session: HistorySession, panel_str: str | None = None + ) -> None: + """Mark a session as active for its data panel.""" + target = panel_str or self.session_panel_str(session) + if target: + self.active_session_by_panel[target] = session + self.refresh_active_session_highlight() + + def refresh_active_session_highlight(self) -> None: + """Highlight each data panel's active session in the tree.""" + active = { + session.number: panel_str + for panel_str, session in self.active_session_by_panel.items() + if session in self.panel.history_sessions + } + self.panel.tree.set_active_sessions(active) + + def set_active_session_from_selection(self) -> None: + """Make the selected session active while recording.""" + if not self.panel.record_mode_enabled: + return + item = self.panel.tree.currentItem() + if item is None or not item.isSelected(): + return + if item.parent() is None: + index = self.panel.tree.indexOfTopLevelItem(item) + if not 0 <= index < len(self.panel.history_sessions): + return + session = self.panel.history_sessions[index] + else: + action = self.current_action() + session = ( + hchain.find_parent_session(self.panel, action) + if action is not None + else None + ) + if session is not None: + self.set_active_session(session) + + def on_current_panel_changed(self, panel_str: str) -> None: + """Bring the current data panel's active recording session into view.""" + if panel_str not in ("signal", "image"): + return + self.refresh_active_session_highlight() + session = self.get_active_session(panel_str) + if session is not None and session in self.panel.history_sessions: + index = self.panel.history_sessions.index(session) + item = self.panel.tree.topLevelItem(index) + if item is not None: + self.panel.tree.scrollToItem(item) + + def current_session(self) -> HistorySession | None: + """Return the session relevant for step navigation.""" + item = self.panel.tree.currentItem() + if item is not None: + top = item + while top.parent() is not None: + top = top.parent() + index = self.panel.tree.indexOfTopLevelItem(top) + if 0 <= index < len(self.panel.history_sessions): + return self.panel.history_sessions[index] + return self.panel.history_sessions[-1] if self.panel.history_sessions else None + + def can_step_prev(self) -> bool: + """Return whether a previous action exists in the current session.""" + session = self.current_session() + action = self.current_action() + return bool( + session is not None + and session.actions + and action in session.actions + and session.actions.index(action) > 0 + ) + + def can_step_next(self) -> bool: + """Return whether a next action exists in the current session.""" + session = self.current_session() + if session is None or not session.actions: + return False + action = self.current_action() + return ( + action not in session.actions + or session.actions.index(action) < len(session.actions) - 1 + ) + + def select_action_in_tree(self, action: HistoryAction) -> None: + """Select an action in the history tree.""" + iterator = QW.QTreeWidgetItemIterator(self.panel.tree) + while iterator.value(): + item = iterator.value() + if item.data(0, QC.Qt.UserRole) == action.uuid: + self.panel.tree.clearSelection() + self.panel.tree.setCurrentItem(item) + item.setSelected(True) + return + iterator += 1 + + def step_prev(self) -> None: + """Select the previous action in the current session.""" + if not self.can_step_prev(): + return + session = self.current_session() + action = self.current_action() + self.select_action_in_tree(session.actions[session.actions.index(action) - 1]) + self.panel.ui.update_actions_state() + + def step_next(self) -> None: + """Select the next action in the current session.""" + if not self.can_step_next(): + return + session = self.current_session() + action = self.current_action() + target = ( + session.actions[0] + if action not in session.actions + else session.actions[session.actions.index(action) + 1] + ) + self.select_action_in_tree(target) + self.panel.ui.update_actions_state() + + def select_sessions(self, sessions: list[HistorySession]) -> None: + """Select top-level tree items matching sessions.""" + self.panel.tree.clearSelection() + for session in sessions: + index = self.panel.history_sessions.index(session) + item = self.panel.tree.topLevelItem(index) + item.setSelected(True) + self.panel.tree.setCurrentItem(item) diff --git a/datalab/gui/panel/history/panel.py b/datalab/gui/panel/history/panel.py index 73fd316a9..e55bdec0c 100644 --- a/datalab/gui/panel/history/panel.py +++ b/datalab/gui/panel/history/panel.py @@ -6,40 +6,40 @@ from __future__ import annotations -import functools -import logging -from contextlib import contextmanager -from typing import TYPE_CHECKING, Any, Generator +from typing import TYPE_CHECKING, Generator from guidata.configtools import get_icon -from guidata.qthelpers import add_actions, create_action from guidata.widgets.dockable import DockableWidgetMixin from qtpy import QtCore as QC -from qtpy import QtGui as QG -from qtpy import QtWidgets as QW from datalab.config import Conf, _ from datalab.env import execenv from datalab.gui import historysession_ops as hsess -from datalab.gui import historytools_ops as htools from datalab.gui.panel.base import AbstractPanel -from datalab.gui.panel.history import chain as hchain -from datalab.gui.panel.history import interactive_replay as hreplay -from datalab.gui.panel.history import recompute as hrec -from datalab.h5 import history as hio +from datalab.gui.panel.history.facade import ( + HistoryPersistenceFacadeMixin, + HistoryRecordingFacadeMixin, + HistoryReplayFacadeMixin, + HistoryRuntimeFacadeMixin, +) +from datalab.gui.panel.history.navigation import HistoryNavigation +from datalab.gui.panel.history.runtime import HistoryRuntime +from datalab.gui.panel.history.ui import HistoryPanelUI from datalab.history import HistoryAction, HistorySession from datalab.widgets.historytree import HistoryTree -from datalab.widgets.workspacestate_widget import WorkspaceStateWidget if TYPE_CHECKING: from datalab.gui.main import DLMainWindow - from datalab.gui.panel.base import BaseDataPanel - from datalab.h5.native import NativeH5Reader, NativeH5Writer -_logger = logging.getLogger(__name__) - -class HistoryPanel(AbstractPanel, DockableWidgetMixin): +class HistoryPanel( + HistoryRuntimeFacadeMixin, + HistoryReplayFacadeMixin, + HistoryRecordingFacadeMixin, + HistoryPersistenceFacadeMixin, + AbstractPanel, + DockableWidgetMixin, +): """History panel""" LOCATION = QC.Qt.RightDockWidgetArea @@ -53,730 +53,24 @@ class HistoryPanel(AbstractPanel, DockableWidgetMixin): def __init__(self, parent: DLMainWindow) -> None: super().__init__(parent) + self.mainwindow = parent self.setWindowTitle(self.PANEL_STR) self.setWindowIcon(get_icon("history.svg")) self.setOrientation(QC.Qt.Vertical) - self._record_mode = False - self.edit_mode = False - self._replaying = False - self._output_suppressed = False - self._syncing = False - self.cascade_in_progress = False - self.session_input_pending = False - self.suppress_session_prompt = False - self.edit_replay_in_progress = False - self._delete_action: QW.QAction | None = None - self._duplicate_action: QW.QAction | None = None - self.step_prev_action: QW.QAction | None = None - self.step_next_action: QW.QAction | None = None - self._record_action: QW.QAction | None = None - self._menu_actions: list[QW.QAction] = self.create_menu_actions() - - self.mainwindow = parent - self.tree = HistoryTree(self) - self.tree.customContextMenuRequested.connect(self.show_context_menu) - self.tree.itemDoubleClicked.connect(self.replay_restore_actions) - self.tree.itemSelectionChanged.connect(self.sync_panel_selection) - self.tree.itemSelectionChanged.connect(self.update_actions_state) - self.tree.itemSelectionChanged.connect(self.update_state_widget) - self.tree.itemSelectionChanged.connect(self.set_active_session_from_selection) - - self._state_widget = WorkspaceStateWidget(self) - - toolbar = QW.QToolBar(self) - add_actions(toolbar, self._menu_actions) - widget = QW.QWidget(self) - layout = QW.QVBoxLayout() - layout.addWidget(toolbar) - layout.addWidget(self.tree) - layout.addWidget(self._state_widget) - layout.setContentsMargins(0, 0, 0, 0) - widget.setLayout(layout) - - self.addWidget(widget) - self.history_sessions: list[HistorySession] = [] - self._active_session_by_panel: dict[str, HistorySession] = {} - self._session_increment = 0 - self.action_output_uuids: dict[str, list[str]] = {} - self.output_to_action: dict[str, str] = {} - self.cascade_warnings: list[str] = [] - self.broken_actions: set[str] = set() - self.reconnecting = False - self.obj_ids_snapshot: dict[str, set[str]] = {} - self.tracking_enabled = False - self.object_tracking_connections: list[tuple[Any, Any]] = [] - for panel in (self.mainwindow.signalpanel, self.mainwindow.imagepanel): - self.object_tracking_connections.extend( - ( - (panel.SIG_OBJECT_ADDED, self.refresh_compatibility_items), - (panel.SIG_OBJECT_ADDED, self.refresh_obj_ids_snapshot), - (panel.SIG_OBJECT_REMOVED, self.refresh_compatibility_items), - ( - panel.SIG_OBJECT_REMOVED, - functools.partial(self.reconnect_chain_after_removal, panel), - ), - (panel.SIG_OBJECT_REMOVED, self.prune_output_mapping), - (panel.SIG_OBJECT_MODIFIED, self.refresh_compatibility_items), - ) - ) + self.tree = HistoryTree(self) + self.runtime = HistoryRuntime(self, self.reconnect_chain_after_removal) + self.navigation = HistoryNavigation(self) + self.ui = HistoryPanelUI(self) self.set_tracking_enabled(True) - self.refresh_obj_ids_snapshot() - self.update_actions_state() + self.runtime.objects.refresh_obj_ids_snapshot() + self.ui.update_actions_state() self.refresh_compatibility_items() if not execenv.unattended and Conf.proc.history_auto_record.get(False): - self._record_action.setChecked(True) + self.ui.actions["record"].setChecked(True) self.create_new_session() - def set_tracking_enabled(self, enabled: bool) -> None: - """Enable or disable synchronization with data panel object changes. - - Args: - enabled: Whether object tracking callbacks should be connected - """ - if enabled == self.tracking_enabled: - return - for signal, callback in self.object_tracking_connections: - if enabled: - signal.connect(callback) - else: - signal.disconnect(callback) - self.tracking_enabled = enabled - - def refresh_obj_ids_snapshot(self) -> None: - """Cache the current object ids of both data panels.""" - self.obj_ids_snapshot = { - self.mainwindow.signalpanel.PANEL_STR_ID: set( - self.mainwindow.signalpanel.objmodel.get_object_ids() - ), - self.mainwindow.imagepanel.PANEL_STR_ID: set( - self.mainwindow.imagepanel.objmodel.get_object_ids() - ), - } - - def update_actions_state(self) -> None: - """Update the enabled state of menu actions depending on history content.""" - has_history = len(self) > 0 - for action in (self._delete_action, self._duplicate_action): - if action is not None: - action.setEnabled(has_history) - if self.step_prev_action is not None: - self.step_prev_action.setEnabled(self.can_step_prev()) - if self.step_next_action is not None: - self.step_next_action.setEnabled(self.can_step_next()) - - @property - def session_increment(self) -> int: - """Return the current session counter.""" - return self._session_increment - - @session_increment.setter - def session_increment(self, value: int) -> None: - """Set the current session counter.""" - self._session_increment = value - - @property - def record_mode_enabled(self) -> bool: - """Return True when record mode is enabled.""" - return self._record_mode - - def has_any_pending_edits(self) -> bool: - """Return True if any action across all sessions has a pending Edit - mode snapshot (i.e. uncommitted edits that Restore can revert).""" - return any( - action.has_pending_edits - for session in self.history_sessions - for action in session.actions - ) - - def update_state_widget(self) -> None: - """Update the workspace state widget from the currently selected action.""" - action = self.current_action() - if action is not None: - self._state_widget.update_from_state(action.state) - else: - self._state_widget.update_from_state(None) - - def create_menu_actions(self) -> list[QW.QAction]: - """Create menu actions for the history panel.""" - record_action = create_action( - self, - _("Record mode"), - toggled=self.toggle_record_mode, - icon=get_icon("record.svg"), - ) - record_action.setChecked(self._record_mode) - self._record_action = record_action - new_session_action = create_action( - self, - _("New session"), - lambda checked=False: self.create_new_session(), - icon=get_icon("libre-gui-add.svg"), - tip=_("Start a new history session"), - ) - open_action = create_action( - self, - _("Open history file..."), - triggered=lambda checked=False: self.open_dlhist_file(), - icon=get_icon("fileopen_h5.svg"), - tip=_("Open history from a standalone .dlhist file"), - ) - save_action = create_action( - self, - _("Save history file..."), - triggered=lambda checked=False: self.save_to_dlhist_file(), - icon=get_icon("filesave_h5.svg"), - tip=_("Save history to a standalone .dlhist file"), - ) - self._delete_action = create_action( - self, - _("Delete"), - self.delete_selected, - icon=get_icon("delete.svg"), - ) - self._duplicate_action = create_action( - self, - _("Duplicate"), - self.duplicate_selected_entries, - icon=get_icon("duplicate.svg"), - tip=_("Duplicate selected history action/session"), - ) - self.step_prev_action = create_action( - self, - _("Previous step"), - triggered=self.step_prev, - icon=get_icon("libre-gui-arrow-left.svg"), - tip=_("Select the previous action in the current session"), - shortcut=QG.QKeySequence("Ctrl+Left"), - ) - self.step_next_action = create_action( - self, - _("Next step"), - triggered=self.step_next, - icon=get_icon("libre-gui-arrow-right.svg"), - tip=_("Select the next action in the current session"), - shortcut=QG.QKeySequence("Ctrl+Right"), - ) - remove_incompatible_action = create_action( - self, - _("Remove incompatible"), - self.remove_incompatible_actions, - icon=get_icon("edit/delete_all.svg"), - tip=_("Remove actions incompatible with the current workspace"), - ) - replay_action = create_action( - self, - _("Replay"), - lambda: self.replay_restore_actions(restore_selection=False), - icon=get_icon("replay.svg"), - tip=_("Replay the selection silently (no parameter dialogs)"), - ) - step_by_step_action = create_action( - self, - _("Step-by-step"), - triggered=lambda checked=False: self.replay_step_by_step(), - icon=get_icon("edit_mode.svg"), - tip=_("Replay the selection step by step, editing parameters at each step"), - ) - return [ - record_action, - new_session_action, - None, - open_action, - save_action, - None, - self.step_prev_action, - self.step_next_action, - None, - replay_action, - step_by_step_action, - None, - self._duplicate_action, - None, - remove_incompatible_action, - self._delete_action, - ] - - def toggle_edit_mode(self, checked: bool) -> None: - """Toggle edit mode. - - Toggling Edit mode off is a definitive commit: all parameter - changes performed during the session become permanent. - """ - if not checked and self.has_any_pending_edits(): - reply = ( - QW.QMessageBox.Yes - if execenv.unattended - else QW.QMessageBox.question( - self.mainwindow, - _("Commit edit mode changes?"), - _( - "You are about to exit Edit mode.\n\n" - "All parameter changes made during this session will be " - "permanently kept.\n" - "This action cannot be undone — Restore will no longer " - "be available.\n\n" - "Do you want to continue?" - ), - QW.QMessageBox.Yes | QW.QMessageBox.No, - QW.QMessageBox.No, - ) - ) - if reply != QW.QMessageBox.Yes: - return - self.edit_mode = checked - if not checked: - for session in self.history_sessions: - for action in session.actions: - action.discard_snapshot() - self.update_actions_state() - - def toggle_record_mode(self, checked: bool) -> None: - """Toggle record mode.""" - self._record_mode = checked - - def is_edit_mode(self) -> bool: - """Return True when the History panel is in edit mode.""" - return self.edit_mode - - @contextmanager - def replaying(self) -> Generator[None, None, None]: - """Context manager suppressing history capture during its scope.""" - previous = self._replaying - self._replaying = True - try: - yield - finally: - self._replaying = previous - - def is_replaying(self) -> bool: - """Return True when an external replay/recompute is in progress.""" - return self._replaying - - @contextmanager - def output_suppressed(self) -> Generator[None, None, None]: - """Context manager suppressing compute outputs during its scope.""" - previous = self._output_suppressed - self._output_suppressed = True - try: - yield - finally: - self._output_suppressed = previous - - def is_output_suppressed(self) -> bool: - """Return True when compute outputs must not be added to panels.""" - return self._output_suppressed - - def show_context_menu(self, pos: QC.QPoint) -> None: - """Show the context menu.""" - self.refresh_compatibility_items() - menu = QW.QMenu() - add_actions(menu, self._menu_actions) - menu.exec_(self.tree.mapToGlobal(pos)) - - def get_action_from_uuid(self, uuid: str) -> HistoryAction: - """Get the action from its UUID.""" - for session in self.history_sessions: - for action in session.actions: - if action.uuid == uuid: - return action - raise ValueError("Action not found") - - # ------------------------------------------------------------------ - # Interactive replay delegations - # ------------------------------------------------------------------ - - def replay_restore_actions( - self, replay: bool = True, restore_selection: bool = True - ) -> None: - """Replay and/or restore selection for the selected actions.""" - return hreplay.replay_restore_actions(self, replay, restore_selection) - - def replay_step_by_step(self) -> None: - """Replay the current selection step by step, prompting for parameters. - - Dialog-driven launch mode: each replayed action opens its parameter - dialog (reusing the edit-mode machinery), then recomputes. Edits are - committed immediately -- there is no persistent edit session. - """ - previous = self.edit_mode - self.edit_mode = True - try: - self.replay_restore_actions(replay=True, restore_selection=False) - finally: - self.edit_mode = previous - # Commit step-by-step edits immediately (no persistent edit session). - for session in self.history_sessions: - for action in session.actions: - action.discard_snapshot() - self.update_actions_state() - - def prompt_edit_action_params(self, action: HistoryAction) -> bool | None: - """Open the parameter dialog for *action* according to its pattern.""" - return hreplay.prompt_edit_action_params(self, action) - - # ------------------------------------------------------------------ - # Chain delegations - # ------------------------------------------------------------------ - - def find_parent_session(self, action: HistoryAction) -> HistorySession | None: - """Return the session that contains ``action``, or None.""" - return hchain.find_parent_session(self, action) - - def resolve_panel_for_action(self, action: HistoryAction) -> BaseDataPanel | None: - """Return the data panel targeted by ``action``, or ``None``.""" - return hchain.resolve_panel_for_action(self, action) - - def find_output_object_uuid( - self, panel: BaseDataPanel, action: HistoryAction - ) -> str | None: - """Find the UUID of the output object produced by ``action``.""" - return hchain.find_output_object_uuid(self, panel, action) - - def find_action_for_output( - self, output_uuid: str, func_name: str - ) -> HistoryAction | None: - """Find the action that produced ``output_uuid``.""" - return hchain.find_action_for_output(self, output_uuid, func_name) - - def find_creation_action_for_output(self, output_uuid: str) -> HistoryAction | None: - """Find the creation action that produced ``output_uuid``.""" - return hchain.find_creation_action_for_output(self, output_uuid) - - def find_analysis_action( - self, obj_uuid: str, func_name: str - ) -> HistoryAction | None: - """Find the 1-to-0 analysis action for ``obj_uuid`` with ``func_name``.""" - return hchain.find_analysis_action(self, obj_uuid, func_name) - - def get_session_of(self, action: HistoryAction) -> HistorySession | None: - """Return the session that contains ``action``, or None.""" - return hchain.get_session_of(self, action) - - def action_output_uuid(self, action: HistoryAction) -> str | None: - """Return the UUID of the object produced by ``action``, or ``None``.""" - return hchain.action_output_uuid(self, action) - - def get_downstream_actions(self, action: HistoryAction) -> list[HistoryAction]: - """Return the actions of the current session that depend on ``action``.""" - return hchain.get_downstream_actions(self, action) - - def resolve_target_outputs( - self, panel: BaseDataPanel, action: HistoryAction - ) -> tuple[list[str], list[str]]: - """Return ``(existing, missing)`` UUIDs registered for ``action``.""" - return hchain.resolve_target_outputs(self, panel, action) - - def existing_input_uuids( - self, panel: BaseDataPanel, action: HistoryAction - ) -> list[str]: - """Return recorded input UUIDs that still exist in ``panel``.""" - return hchain.existing_input_uuids(panel, action) - - def prune_output_mapping(self) -> None: - """Drop entries of :attr:`output_to_action` whose object no longer exists.""" - return hchain.prune_output_mapping(self) - - def remove_single_action(self, action: HistoryAction) -> None: - """Remove a single action from its session (splice, not truncate).""" - return hchain.remove_single_action(self, action) - - def reconnect_chain_after_removal(self, panel: BaseDataPanel) -> None: - """Reconnect the processing chain after object(s) were deleted.""" - return hchain.reconnect_chain_after_removal(self, panel) - - # ------------------------------------------------------------------ - # Recompute delegations - # ------------------------------------------------------------------ - - def refresh_action(self, action: HistoryAction) -> None: - """Refresh the tree display for ``action`` after its kwargs were mutated.""" - return hrec.refresh_action(self, action) - - def recompute_cascade( - self, - root_action: HistoryAction, - descendants: list[HistoryAction] | None = None, - ) -> None: - """Recompute ``root_action``'s descendants in the current session.""" - return hrec.recompute_cascade(self, root_action, descendants) - - def flush_cascade_warnings(self) -> None: - """Show + clear accumulated cascade warnings (no-op when empty).""" - return hrec.flush_cascade_warnings(self) - - # ------------------------------------------------------------------ - # Sync History tree selection → Signal/Image panel - # ------------------------------------------------------------------ - - def sync_panel_selection(self) -> None: - """Sync data panel selection from the currently selected tree item.""" - if self._replaying or self._syncing: - return - item = self.tree.currentItem() - if item is None or not item.isSelected(): - return - if item.parent() is None: - index = self.tree.indexOfTopLevelItem(item) - if index < 0 or index >= len(self.history_sessions): - return - session = self.history_sessions[index] - action = next( - (a for a in session.actions if a.kind == HistoryAction.KIND_COMPUTE), - None, - ) - else: - uuid = item.data(0, QC.Qt.UserRole) - try: - action = self.tree.get_action_from_uuid(uuid, self.history_sessions) - except ValueError: - action = None - if action is None: - return - - panel = self.resolve_panel_for_action(action) - if panel is None: - return - - target_uuids: list[str] = [] - output_uuid = self.find_output_object_uuid(panel, action) - if output_uuid is not None: - target_uuids = [output_uuid] - else: - target_uuids = self.existing_input_uuids(panel, action) - - if not target_uuids: - return - - self._syncing = True - try: - with QC.QSignalBlocker(panel.objview): - panel.objview.select_objects(target_uuids) - self.mainwindow.set_current_panel(panel) - finally: - self._syncing = False - - # ------------------------------------------------------------------ - # Step-by-step navigation - # ------------------------------------------------------------------ - - def current_action(self) -> HistoryAction | None: - """Return the action currently selected in the tree, or ``None``.""" - item = self.tree.currentItem() - if item is None or item.parent() is None: - return None - uuid = item.data(0, QC.Qt.UserRole) - try: - return self.tree.get_action_from_uuid(uuid, self.history_sessions) - except ValueError: - return None - - def current_panel_str(self) -> str: - """Return the current data panel id ('signal'/'image'); default 'signal'.""" - pstr = self.mainwindow.get_current_panel() - return pstr if pstr in ("signal", "image") else "signal" - - def on_current_panel_changed(self, panel_str: str) -> None: - """React to a Signal/Image panel switch: bring this panel's active - recording session into view and refresh the active-session highlight. - """ - if panel_str not in ("signal", "image"): - return - self.refresh_active_session_highlight() - session = self.get_active_session(panel_str) - if session is not None and session in self.history_sessions: - index = self.history_sessions.index(session) - item = self.tree.topLevelItem(index) - if item is not None: - self.tree.scrollToItem(item) - - def session_panel_str(self, session: HistorySession) -> str | None: - """Return the panel a session belongs to. - - Derived from the panel_str of its first tagged action; falls back to - the active-session tracking for freshly created (empty) sessions. - """ - for action in session.actions: - if action.panel_str: - return action.panel_str - for pstr, sess in self._active_session_by_panel.items(): - if sess is session: - return pstr - return None - - def get_active_session(self, panel_str: str) -> HistorySession | None: - """Return the active recording session for ``panel_str``, if still valid.""" - session = self._active_session_by_panel.get(panel_str) - if session is not None and session in self.history_sessions: - return session - return None - - def set_active_session( - self, session: HistorySession, panel_str: str | None = None - ) -> None: - """Mark ``session`` as the active recording session for its panel.""" - pstr = panel_str or self.session_panel_str(session) - if pstr: - self._active_session_by_panel[pstr] = session - self.refresh_active_session_highlight() - - def refresh_active_session_highlight(self) -> None: - """Update the tree highlight to mark each panel's active session.""" - active: dict[int, str] = {} - for pstr, session in self._active_session_by_panel.items(): - if session in self.history_sessions: - active[session.number] = pstr - self.tree.set_active_sessions(active) - - def set_active_session_from_selection(self) -> None: - """When recording, make the selected session the active one for its panel. - - Lets the user resume recording into any session by selecting it (or one - of its actions) in the tree. - """ - if not self.record_mode_enabled: - return - item = self.tree.currentItem() - if item is None or not item.isSelected(): - return - if item.parent() is None: - index = self.tree.indexOfTopLevelItem(item) - if not 0 <= index < len(self.history_sessions): - return - session = self.history_sessions[index] - else: - action = self.current_action() - if action is None: - return - session = self.find_parent_session(action) - if session is not None: - self.set_active_session(session) - - def current_session(self) -> HistorySession | None: - """Return the session relevant for step navigation.""" - item = self.tree.currentItem() - if item is not None: - top = item - while top.parent() is not None: - top = top.parent() - index = self.tree.indexOfTopLevelItem(top) - if 0 <= index < len(self.history_sessions): - return self.history_sessions[index] - if self.history_sessions: - return self.history_sessions[-1] - return None - - def can_step_prev(self) -> bool: - """Return True if a previous action exists in the current session.""" - session = self.current_session() - if session is None or not session.actions: - return False - action = self.current_action() - if action is None or action not in session.actions: - return False - return session.actions.index(action) > 0 - - def can_step_next(self) -> bool: - """Return True if a next action exists in the current session.""" - session = self.current_session() - if session is None or not session.actions: - return False - action = self.current_action() - if action is None or action not in session.actions: - return True - return session.actions.index(action) < len(session.actions) - 1 - - def select_action_in_tree(self, action: HistoryAction) -> None: - """Select ``action`` in the tree (triggers ``sync_panel_selection``).""" - iterator = QW.QTreeWidgetItemIterator(self.tree) - while iterator.value(): - item = iterator.value() - if item.data(0, QC.Qt.UserRole) == action.uuid: - self.tree.clearSelection() - self.tree.setCurrentItem(item) - item.setSelected(True) - return - iterator += 1 - - def step_prev(self) -> None: - """Select the previous action in the current session.""" - if not self.can_step_prev(): - return - session = self.current_session() - action = self.current_action() - idx = session.actions.index(action) - self.select_action_in_tree(session.actions[idx - 1]) - self.update_actions_state() - - def step_next(self) -> None: - """Select the next action in the current session.""" - if not self.can_step_next(): - return - session = self.current_session() - action = self.current_action() - if action is None or action not in session.actions: - target = session.actions[0] - else: - target = session.actions[session.actions.index(action) + 1] - self.select_action_in_tree(target) - self.update_actions_state() - - # ------------------------------------------------------------------ - # History tools delegations - # ------------------------------------------------------------------ - - def duplicate_selected_entries(self) -> None: - """Duplicate selected entries.""" - return htools.duplicate_selected_entries(self) - - def select_sessions(self, sessions: list[HistorySession]) -> None: - """Select top-level tree items matching ``sessions``.""" - self.tree.clearSelection() - for session in sessions: - index = self.history_sessions.index(session) - item = self.tree.topLevelItem(index) - item.setSelected(True) - self.tree.setCurrentItem(item) - - def delete_selected(self) -> None: - """Delete the currently selected entries.""" - return htools.delete_selected(self) - - def remove_incompatible_actions(self) -> None: - """Remove actions incompatible with the current workspace.""" - return htools.remove_incompatible_actions(self) - - # ------------------------------------------------------------------ - # HDF5 / .dlhist I/O delegations - # ------------------------------------------------------------------ - - def save_to_dlhist_file(self, filename: str | None = None) -> bool: - """Save history to a standalone .dlhist file.""" - return hio.save_to_dlhist_file(self, filename) - - def open_dlhist_file(self, filename: str | None = None) -> bool: - """Open history from a standalone .dlhist file.""" - return hio.open_dlhist_file(self, filename) - - def import_dlhist_into_new_session(self, reader: NativeH5Reader) -> None: - """Import a .dlhist into a new session.""" - return hio.import_dlhist_into_new_session(self, reader) - - def refresh_compatibility_items(self, *args: Any) -> None: - """Refresh compatibility icons in the history tree.""" - return hio.refresh_compatibility_items(self, *args) - - def serialize_to_hdf5(self, writer: NativeH5Writer) -> None: - """Serialize the history to HDF5.""" - return hio.serialize_to_hdf5(self, writer) - - def deserialize_from_hdf5( - self, reader: NativeH5Reader, reset_all: bool = False - ) -> None: - """Deserialize the history from HDF5.""" - return hio.deserialize_from_hdf5(self, reader, reset_all) - def __len__(self) -> int: """Return number of objects.""" return sum(len(session.actions) for session in self.history_sessions) @@ -794,108 +88,6 @@ def __iter__(self) -> Generator[HistoryAction, None, None]: for session in self.history_sessions: yield from session.actions - # ------------------------------------------------------------------ - # Session operations delegations - # ------------------------------------------------------------------ - - def create_new_session(self, panel_str: str | None = None) -> HistorySession: - """Create a new history session (active for the given/current panel).""" - return hsess.create_new_session(self, panel_str=panel_str) - - def start_new_session_after_workspace_reset(self) -> None: - """Start a new history session after a workspace reset.""" - return hsess.start_new_session_after_workspace_reset(self) - - def maybe_start_session_for_input(self, *, load: bool = False) -> None: - """Offer to start a new history session before a creation/load is recorded. - - Args: - load: True when triggered by a file/workspace load, False for an - object creation. Only affects the prompt wording. - """ - return hsess.maybe_start_session_for_input(self, load=load) - - @contextmanager - def session_prompt_suppressed(self) -> Generator[None, None, None]: - """Context manager suppressing the new-session prompt during a batch load.""" - previous = self.suppress_session_prompt - self.suppress_session_prompt = True - try: - yield - finally: - self.suppress_session_prompt = previous - - def add_compute_entry( - self, - action_title: str, - panel_str: str, - func_name: str, - pattern: str, - save_state: bool = True, - output_uuids: list[str] | None = None, - plugin_origin: dict[str, Any] | None = None, - **kwargs: Any, - ) -> HistoryAction | None: - """Add a compute entry to the history.""" - return hsess.add_compute_entry( - self, - action_title, - panel_str, - func_name, - pattern, - save_state, - output_uuids, - plugin_origin, - **kwargs, - ) - - def add_compute_entry_from_pp( - self, - action_title: str, - pp: Any, - panel_str: str, - save_state: bool = True, - output_uuids: list[str] | None = None, - plugin_origin: dict[str, Any] | None = None, - **extras: Any, - ) -> HistoryAction | None: - """Add a compute entry built from a :class:`ProcessingParameters`.""" - return hsess.add_compute_entry_from_pp( - self, - action_title, - pp, - panel_str, - save_state, - output_uuids, - plugin_origin, - **extras, - ) - - def register_action_outputs( - self, action: HistoryAction, output_uuids: list[str] - ) -> None: - """Register the output UUIDs produced by ``action``.""" - return hsess.register_action_outputs(self, action, output_uuids) - - def capture_outputs( - self, action: HistoryAction | None - ) -> Generator[None, None, None]: - """Context manager capturing outputs produced by ``action``.""" - return hsess.capture_outputs(self, action) - - def add_ui_entry( - self, - action_title: str, - target: str, - method_name: str, - save_state: bool = True, - **kwargs: Any, - ) -> HistoryAction | None: - """Add a UI entry to the history.""" - return hsess.add_ui_entry( - self, action_title, target, method_name, save_state, **kwargs - ) - # ------ AbstractPanel interface --------------------------------------------------- def create_object(self) -> HistoryAction: """Create and return object.""" @@ -908,5 +100,4 @@ def add_object(self, obj: HistoryAction) -> None: def remove_all_objects(self) -> None: """Remove all objects.""" super().remove_all_objects() - self.action_output_uuids.clear() - self.output_to_action.clear() + self.runtime.objects.clear_output_mappings() diff --git a/datalab/gui/panel/history/recompute.py b/datalab/gui/panel/history/recompute.py index d612b0d7e..81eacbd45 100644 --- a/datalab/gui/panel/history/recompute.py +++ b/datalab/gui/panel/history/recompute.py @@ -12,6 +12,13 @@ from datalab.config import _ from datalab.env import execenv +from datalab.gui.creation import ( + create_image_from_param, + create_signal_from_param, + insert_creation_parameters, + prepare_signal_parameters, +) +from datalab.gui.panel.history import chain as hchain from datalab.gui.processor.base import ( FeatureNotFoundError, ProcessingParameters, @@ -101,7 +108,7 @@ def record_missing_outputs( action.uuid, name, ) - panel.cascade_warnings.append( + panel.runtime.execution.cascade_warnings.append( _( "Action %s has been edited but its target output object(s) " "no longer exist — skipping." @@ -133,7 +140,7 @@ def recompute_action_in_place(panel: HistoryPanel, action: HistoryAction) -> Non action.pattern, action.uuid, ) - panel.cascade_warnings.append( + panel.runtime.execution.cascade_warnings.append( _("Action %s uses pattern %r which is not recomputable yet.") % (action.func_name or action.uuid, action.pattern) ) @@ -149,7 +156,7 @@ def recompute_action_in_place(panel: HistoryPanel, action: HistoryAction) -> Non action.func_name, exc, ) - panel.cascade_warnings.append( + panel.runtime.execution.cascade_warnings.append( _("Recompute failed for action %s: %s") % (action.func_name or action.uuid, exc) ) @@ -160,7 +167,7 @@ def handle_missing_feature( ) -> None: """Flag ``action`` as broken (missing plugin) and queue a user warning.""" action.is_stale = True - panel.broken_actions.add(action.uuid) + panel.runtime.execution.broken_actions.add(action.uuid) plugin_origin = action.plugin_origin or exc.plugin_origin or {} directory = (plugin_origin.get("directory") if plugin_origin else None) or "?" param = action.kwargs.get("param") @@ -175,7 +182,7 @@ def handle_missing_feature( func_name, location, ) - panel.cascade_warnings.append( + panel.runtime.execution.cascade_warnings.append( _( "Action %(name)s skipped: plugin '%(loc)s' is missing.\n" "Required parameter class: %(param)s\n" @@ -191,17 +198,10 @@ def recompute_creation_in_place(panel: HistoryPanel, action: HistoryAction) -> N Rebuild the object from the edited ``param`` and copy it onto the existing output object so its UUID (and downstream references) are kept. """ - # Local import to avoid a circular dependency at module load time. - from datalab.gui.newobject import ( - create_image_gui, - create_signal_gui, - insert_creation_parameters, - ) - - panel_data = panel.resolve_panel_for_action(action) + panel_data = hchain.resolve_panel_for_action(panel, action) if panel_data is None: return - existing, missing = panel.resolve_target_outputs(panel_data, action) + existing, missing = hchain.resolve_target_outputs(panel, panel_data, action) record_missing_outputs(panel, action, missing) if not existing: return @@ -213,11 +213,12 @@ def recompute_creation_in_place(panel: HistoryPanel, action: HistoryAction) -> N if param is None: return if action.target == "signalpanel": - new_obj = create_signal_gui(param, edit=False) + prepared = prepare_signal_parameters(param, edit=False) + if prepared is None: + return + new_obj = create_signal_from_param(prepared) else: - new_obj = create_image_gui(param, edit=False) - if new_obj is None: - return + new_obj = create_image_from_param(param) update_obj_in_place(output_obj, new_obj) insert_creation_parameters(output_obj, param) refresh_target(panel_data, output_uuid) @@ -225,12 +226,12 @@ def recompute_creation_in_place(panel: HistoryPanel, action: HistoryAction) -> N def recompute_1_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> None: """Recompute a single 1-to-1 action in place.""" - panel_data = panel.resolve_panel_for_action(action) + panel_data = hchain.resolve_panel_for_action(panel, action) if panel_data is None: return - existing, missing = panel.resolve_target_outputs(panel_data, action) + existing, missing = hchain.resolve_target_outputs(panel, panel_data, action) if not existing and not missing: - legacy = panel.find_output_object_uuid(panel_data, action) + legacy = hchain.find_output_object_uuid(panel, panel_data, action) if legacy is not None: existing = [legacy] record_missing_outputs(panel, action, missing) @@ -244,7 +245,7 @@ def recompute_1_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> Non if pp is None or pp.source_uuid is None: return if not panel_data.objmodel.has_uuid(pp.source_uuid): - panel.cascade_warnings.append( + panel.runtime.execution.cascade_warnings.append( _("Action %s: source object was deleted — skipping.") % (action.func_name or action.uuid) ) @@ -274,10 +275,10 @@ def recompute_1_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> Non def recompute_1_to_n_in_place(panel: HistoryPanel, action: HistoryAction) -> None: """Recompute a 1-to-n action in place: replace each of the N outputs.""" - panel_data = panel.resolve_panel_for_action(action) + panel_data = hchain.resolve_panel_for_action(panel, action) if panel_data is None: return - existing, missing = panel.resolve_target_outputs(panel_data, action) + existing, missing = hchain.resolve_target_outputs(panel, panel_data, action) record_missing_outputs(panel, action, missing) if not existing or not panel_data.objmodel.has_uuid(existing[0]): return @@ -286,7 +287,7 @@ def recompute_1_to_n_in_place(panel: HistoryPanel, action: HistoryAction) -> Non if pp is None or pp.source_uuid is None: return if not panel_data.objmodel.has_uuid(pp.source_uuid): - panel.cascade_warnings.append( + panel.runtime.execution.cascade_warnings.append( _("Action %s: source object was deleted — skipping.") % (action.func_name or action.uuid) ) @@ -334,10 +335,10 @@ def recompute_1_to_n_in_place(panel: HistoryPanel, action: HistoryAction) -> Non def recompute_n_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> None: """Recompute an n-to-1 action in place.""" - panel_data = panel.resolve_panel_for_action(action) + panel_data = hchain.resolve_panel_for_action(panel, action) if panel_data is None: return - existing, missing = panel.resolve_target_outputs(panel_data, action) + existing, missing = hchain.resolve_target_outputs(panel, panel_data, action) record_missing_outputs(panel, action, missing) if not existing: return @@ -356,7 +357,7 @@ def recompute_n_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> Non if panel_data.objmodel.has_uuid(uuid): src_objs.append(panel_data.objmodel[uuid]) if not src_objs: - panel.cascade_warnings.append( + panel.runtime.execution.cascade_warnings.append( _("Action %s: all source objects were deleted — skipping.") % (action.func_name or action.uuid) ) @@ -386,10 +387,10 @@ def recompute_n_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> Non def recompute_2_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> None: """Recompute a 2-to-1 action in place (single or pairwise).""" - panel_data = panel.resolve_panel_for_action(action) + panel_data = hchain.resolve_panel_for_action(panel, action) if panel_data is None: return - existing, missing = panel.resolve_target_outputs(panel_data, action) + existing, missing = hchain.resolve_target_outputs(panel, panel_data, action) record_missing_outputs(panel, action, missing) if not existing: return @@ -414,7 +415,7 @@ def recompute_2_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> Non ) ) if len(src_uuids) < 2: - panel.cascade_warnings.append( + panel.runtime.execution.cascade_warnings.append( _("Action %s: missing source(s) for output #%d — skipping.") % (action.func_name or action.uuid, idx + 1) ) @@ -423,7 +424,7 @@ def recompute_2_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> Non panel_data.objmodel.has_uuid(src_uuids[0]) and panel_data.objmodel.has_uuid(src_uuids[1]) ): - panel.cascade_warnings.append( + panel.runtime.execution.cascade_warnings.append( _("Action %s: source object(s) were deleted — skipping.") % (action.func_name or action.uuid) ) @@ -455,7 +456,7 @@ def recompute_2_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> Non def recompute_1_to_0_in_place(panel: HistoryPanel, action: HistoryAction) -> None: """Recompute a 1-to-0 analysis on each source object in place.""" - panel_data = panel.resolve_panel_for_action(action) + panel_data = hchain.resolve_panel_for_action(panel, action) if panel_data is None: return sources = list(action.state.selection.get(panel_data.PANEL_STR_ID, [])) @@ -476,7 +477,7 @@ def recompute_1_to_0_in_place(panel: HistoryPanel, action: HistoryAction) -> Non ) refresh_target(panel_data, uuid) if missing: - panel.cascade_warnings.append( + panel.runtime.execution.cascade_warnings.append( _("Action %s: %d analysed object(s) were deleted — skipping.") % (action.func_name or action.uuid, len(missing)) ) @@ -489,47 +490,51 @@ def recompute_cascade( ) -> None: """Recompute ``root_action``'s descendants in the current session in place.""" if descendants is None: - descendants = panel.get_downstream_actions(root_action) + descendants = hchain.get_downstream_actions(panel, root_action) if root_action.is_stale: descendants = [root_action] + descendants - if getattr(panel, "cascade_in_progress", False): + if panel.runtime.execution.cascade_in_progress: flush_cascade_warnings(panel) return if not descendants: flush_cascade_warnings(panel) return - panel.broken_actions.clear() - panel.cascade_in_progress = True - try: + with panel.runtime.execution.recomputing_cascade() as started: + if not started: + flush_cascade_warnings(panel) + return for action in descendants: action.is_stale = True panel.tree.refresh_action_item(action) QW.QApplication.processEvents() - for action in descendants: - try: - recompute_action_in_place(panel, action) - finally: - if action.uuid not in panel.broken_actions: + try: + for action in descendants: + try: + recompute_action_in_place(panel, action) + finally: + if action.uuid not in panel.runtime.execution.broken_actions: + action.is_stale = False + panel.tree.refresh_action_item(action) + QW.QApplication.processEvents() + finally: + for action in descendants: + if ( + action.is_stale + and action.uuid not in panel.runtime.execution.broken_actions + ): action.is_stale = False - panel.tree.refresh_action_item(action) - QW.QApplication.processEvents() - finally: - for action in descendants: - if action.is_stale and action.uuid not in panel.broken_actions: - action.is_stale = False - panel.tree.refresh_action_item(action) - panel.cascade_in_progress = False + panel.tree.refresh_action_item(action) flush_cascade_warnings(panel) def flush_cascade_warnings(panel: HistoryPanel) -> None: """Show + clear accumulated cascade warnings (no-op when empty).""" - if panel.cascade_warnings and not execenv.unattended: + if panel.runtime.execution.cascade_warnings and not execenv.unattended: QW.QMessageBox.warning( panel.mainwindow, _("Cascade recompute"), _("Some downstream actions could not be recomputed:") + "\n\n• " - + "\n• ".join(panel.cascade_warnings), + + "\n• ".join(panel.runtime.execution.cascade_warnings), ) - panel.cascade_warnings = [] + panel.runtime.execution.cascade_warnings.clear() diff --git a/datalab/gui/panel/history/reconnection.py b/datalab/gui/panel/history/reconnection.py new file mode 100644 index 000000000..8bb02b356 --- /dev/null +++ b/datalab/gui/panel/history/reconnection.py @@ -0,0 +1,44 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +"""GUI-boundary orchestration for reconnecting removed history objects.""" + +from __future__ import annotations + +from typing import TYPE_CHECKING + +from datalab.gui.panel.history import chain as hchain +from datalab.gui.panel.history import recompute as hrec +from datalab.history import HistoryAction + +if TYPE_CHECKING: + from datalab.gui.panel.base import BaseDataPanel + from datalab.gui.panel.history.panel import HistoryPanel + + +def reconnect_chain_after_removal( + panel: HistoryPanel, panel_data: BaseDataPanel +) -> None: + """Reconnect the processing chain after objects are deleted from a data panel.""" + panel_str = panel_data.PANEL_STR_ID + previous = panel.runtime.objects.obj_ids_snapshot.get(panel_str, set()) + current = set(panel_data.objmodel.get_object_ids()) + removed = previous - current + if not removed: + return + with panel.runtime.objects.reconnecting_objects() as started: + if not started: + return + plans = [ + hchain.plan_reconnection(panel, panel_data, object_uuid) + for object_uuid in removed + ] + roots_to_recompute: list[HistoryAction] = [] + for plan in plans: + hchain.apply_reconnection_plan(panel, panel_data, plan, roots_to_recompute) + for action in roots_to_recompute: + hrec.recompute_action_in_place(panel, action) + hrec.recompute_cascade(panel, action) + hchain.show_reconnection_warnings( + panel, [plan.warning for plan in plans if plan.warning is not None] + ) + hchain.refresh_reconnected_history(panel) diff --git a/datalab/gui/panel/history/runtime.py b/datalab/gui/panel/history/runtime.py new file mode 100644 index 000000000..ad6d3af0e --- /dev/null +++ b/datalab/gui/panel/history/runtime.py @@ -0,0 +1,246 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +"""Runtime state and registries for the History panel.""" + +from __future__ import annotations + +import functools +from contextlib import contextmanager +from typing import TYPE_CHECKING, Any, Callable, Generator + +from qtpy import QtCore as QC + +if TYPE_CHECKING: + from datalab.gui.panel.base import BaseDataPanel + from datalab.gui.panel.history.panel import HistoryPanel + from datalab.history import HistoryAction + + +class HistoryExecutionState: + """Own transient replay modes and re-entrance guards.""" + + def __init__(self) -> None: + self.record_mode = False + self.edit_mode = False + self.session_input_pending = False + self.suppress_session_prompt = False + self.replaying_active = False + self.output_suppressed_active = False + self.cascade_in_progress = False + self.edit_replay_in_progress = False + self.cascade_warnings: list[str] = [] + self.broken_actions: set[str] = set() + + @contextmanager + def replaying(self) -> Generator[None, None, None]: + """Suppress history capture during the context scope.""" + previous = self.replaying_active + self.replaying_active = True + try: + yield + finally: + self.replaying_active = previous + + @contextmanager + def output_suppressed(self) -> Generator[None, None, None]: + """Suppress compute outputs during the context scope.""" + previous = self.output_suppressed_active + self.output_suppressed_active = True + try: + yield + finally: + self.output_suppressed_active = previous + + @contextmanager + def session_prompt_suppressed(self) -> Generator[None, None, None]: + """Suppress the new-session prompt during the context scope.""" + previous = self.suppress_session_prompt + self.suppress_session_prompt = True + try: + yield + finally: + self.suppress_session_prompt = previous + + def start_session_input_prompt(self) -> bool: + """Start the input prompt debounce window if it is not already active.""" + if self.session_input_pending: + return False + self.session_input_pending = True + QC.QTimer.singleShot(0, self.finish_session_input_prompt) + return True + + def finish_session_input_prompt(self) -> None: + """End the input prompt debounce window.""" + self.session_input_pending = False + + @contextmanager + def recomputing_cascade(self) -> Generator[bool, None, None]: + """Guard a cascade recomputation against re-entrance.""" + if self.cascade_in_progress: + yield False + return + self.broken_actions.clear() + self.cascade_in_progress = True + try: + yield True + finally: + self.cascade_in_progress = False + + @contextmanager + def replaying_edits(self) -> Generator[bool, None, None]: + """Guard an edit-mode replay against re-entrance.""" + if self.edit_replay_in_progress: + yield False + return + self.edit_replay_in_progress = True + try: + yield True + finally: + self.edit_replay_in_progress = False + + +class HistoryObjectIndex: + """Own object snapshots, output indexes, and panel tracking callbacks.""" + + def __init__( + self, + panel: HistoryPanel, + reconnect_after_removal: Callable[[BaseDataPanel], None], + ) -> None: + self.panel = panel + self.reconnect_after_removal = reconnect_after_removal + self.reconnecting = False + self.obj_ids_snapshot: dict[str, set[str]] = {} + self.action_output_uuids: dict[str, list[str]] = {} + self.output_to_action: dict[str, str] = {} + self.tracking_enabled = False + self.object_tracking_connections: list[tuple[Any, Any]] = [] + self.build_tracking_connections() + + def build_tracking_connections(self) -> None: + """Build callbacks that keep history state aligned with data panels.""" + for data_panel in ( + self.panel.mainwindow.signalpanel, + self.panel.mainwindow.imagepanel, + ): + self.object_tracking_connections.extend( + ( + ( + data_panel.SIG_OBJECT_ADDED, + self.panel.refresh_compatibility_items, + ), + (data_panel.SIG_OBJECT_ADDED, self.refresh_obj_ids_snapshot), + ( + data_panel.SIG_OBJECT_REMOVED, + self.panel.refresh_compatibility_items, + ), + ( + data_panel.SIG_OBJECT_REMOVED, + functools.partial(self.reconnect_after_removal, data_panel), + ), + (data_panel.SIG_OBJECT_REMOVED, self.prune_output_mapping), + ( + data_panel.SIG_OBJECT_MODIFIED, + self.panel.refresh_compatibility_items, + ), + ) + ) + + def set_tracking_enabled(self, enabled: bool) -> None: + """Enable or disable synchronization with data panel object changes.""" + if enabled == self.tracking_enabled: + return + for signal, callback in self.object_tracking_connections: + if enabled: + signal.connect(callback) + else: + signal.disconnect(callback) + self.tracking_enabled = enabled + + def refresh_obj_ids_snapshot(self) -> None: + """Cache the current object ids of both data panels.""" + signal_panel = self.panel.mainwindow.signalpanel + image_panel = self.panel.mainwindow.imagepanel + self.obj_ids_snapshot = { + signal_panel.PANEL_STR_ID: set(signal_panel.objmodel.get_object_ids()), + image_panel.PANEL_STR_ID: set(image_panel.objmodel.get_object_ids()), + } + + @contextmanager + def reconnecting_objects(self) -> Generator[bool, None, None]: + """Guard object reconnection and refresh snapshots when it completes.""" + if self.reconnecting: + yield False + return + self.reconnecting = True + try: + yield True + finally: + self.reconnecting = False + self.refresh_obj_ids_snapshot() + + def register_action_outputs( + self, action: HistoryAction, output_uuids: list[str] + ) -> None: + """Register outputs while maintaining both mapping directions.""" + previous = self.action_output_uuids.get(action.uuid, []) + for previous_uuid in previous: + if self.output_to_action.get(previous_uuid) == action.uuid: + self.output_to_action.pop(previous_uuid, None) + new_outputs = list(output_uuids) + for output_uuid in new_outputs: + old_action_uuid = self.output_to_action.get(output_uuid) + if old_action_uuid is not None and old_action_uuid != action.uuid: + old_outputs = self.action_output_uuids.get(old_action_uuid) + if old_outputs is not None and output_uuid in old_outputs: + old_outputs.remove(output_uuid) + if not old_outputs: + del self.action_output_uuids[old_action_uuid] + action.output_uuids = list(new_outputs) + self.action_output_uuids[action.uuid] = new_outputs + for output_uuid in new_outputs: + self.output_to_action[output_uuid] = action.uuid + + def prune_output_mapping(self) -> None: + """Drop reverse-index entries for objects that no longer exist.""" + if not self.output_to_action: + return + alive: set[str] = set() + for data_panel in ( + self.panel.mainwindow.signalpanel, + self.panel.mainwindow.imagepanel, + ): + alive.update(data_panel.objmodel.get_object_ids()) + for output_uuid in [ + uuid for uuid in self.output_to_action if uuid not in alive + ]: + action_uuid = self.output_to_action.pop(output_uuid) + outputs = self.action_output_uuids.get(action_uuid) + if outputs is not None and output_uuid in outputs: + outputs.remove(output_uuid) + if not outputs: + del self.action_output_uuids[action_uuid] + + def remove_action_outputs(self, action: HistoryAction) -> None: + """Remove all output-index entries owned by an action.""" + outputs = self.action_output_uuids.pop(action.uuid, []) + for output_uuid in outputs: + if self.output_to_action.get(output_uuid) == action.uuid: + self.output_to_action.pop(output_uuid, None) + + def clear_output_mappings(self) -> None: + """Clear both output mapping indexes.""" + self.action_output_uuids.clear() + self.output_to_action.clear() + + +class HistoryRuntime: + """Coordinate transient execution state and history object indexes.""" + + def __init__( + self, + panel: HistoryPanel, + reconnect_after_removal: Callable[[BaseDataPanel], None], + ) -> None: + self.execution = HistoryExecutionState() + self.objects = HistoryObjectIndex(panel, reconnect_after_removal) diff --git a/datalab/gui/panel/history/ui.py b/datalab/gui/panel/history/ui.py new file mode 100644 index 000000000..d47664c29 --- /dev/null +++ b/datalab/gui/panel/history/ui.py @@ -0,0 +1,182 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +"""Qt action and widget setup for the History panel.""" + +from __future__ import annotations + +from typing import TYPE_CHECKING + +from guidata.configtools import get_icon +from guidata.qthelpers import add_actions, create_action +from qtpy import QtGui as QG +from qtpy import QtWidgets as QW + +from datalab.config import _ +from datalab.gui import historytools_ops as htools +from datalab.widgets.workspacestate_widget import WorkspaceStateWidget + +if TYPE_CHECKING: + from qtpy import QtCore as QC + + from datalab.gui.panel.history.panel import HistoryPanel + + +class HistoryPanelUI: + """Build and own History panel widgets and actions.""" + + def __init__(self, panel: HistoryPanel) -> None: + self.panel = panel + self.state_widget = WorkspaceStateWidget(panel) + self.actions = self.create_actions() + self.menu_actions = self.create_menu_actions() + self.setup_connections() + self.setup_layout() + + def create_actions(self) -> dict[str, QW.QAction]: + """Create named actions used by history menus and toolbar.""" + panel = self.panel + actions = { + "record": create_action( + panel, + _("Record mode"), + toggled=panel.toggle_record_mode, + icon=get_icon("record.svg"), + ), + "new_session": create_action( + panel, + _("New session"), + lambda checked=False: panel.create_new_session(), + icon=get_icon("libre-gui-add.svg"), + tip=_("Start a new history session"), + ), + "open": create_action( + panel, + _("Open history file..."), + triggered=lambda checked=False: panel.open_dlhist_file(), + icon=get_icon("fileopen_h5.svg"), + tip=_("Open history from a standalone .dlhist file"), + ), + "save": create_action( + panel, + _("Save history file..."), + triggered=lambda checked=False: panel.save_to_dlhist_file(), + icon=get_icon("filesave_h5.svg"), + tip=_("Save history to a standalone .dlhist file"), + ), + "delete": create_action( + panel, + _("Delete"), + lambda: htools.delete_selected(panel), + icon=get_icon("delete.svg"), + ), + "duplicate": create_action( + panel, + _("Duplicate"), + lambda: htools.duplicate_selected_entries(panel), + icon=get_icon("duplicate.svg"), + tip=_("Duplicate selected history action/session"), + ), + "step_prev": create_action( + panel, + _("Previous step"), + triggered=panel.navigation.step_prev, + icon=get_icon("libre-gui-arrow-left.svg"), + tip=_("Select the previous action in the current session"), + shortcut=QG.QKeySequence("Ctrl+Left"), + ), + "step_next": create_action( + panel, + _("Next step"), + triggered=panel.navigation.step_next, + icon=get_icon("libre-gui-arrow-right.svg"), + tip=_("Select the next action in the current session"), + shortcut=QG.QKeySequence("Ctrl+Right"), + ), + "remove_incompatible": create_action( + panel, + _("Remove incompatible"), + lambda: htools.remove_incompatible_actions(panel), + icon=get_icon("edit/delete_all.svg"), + tip=_("Remove actions incompatible with the current workspace"), + ), + "replay": create_action( + panel, + _("Replay"), + lambda: panel.replay_restore_actions(restore_selection=False), + icon=get_icon("replay.svg"), + tip=_("Replay the selection silently (no parameter dialogs)"), + ), + "step_by_step": create_action( + panel, + _("Step-by-step"), + triggered=lambda checked=False: panel.replay_step_by_step(), + icon=get_icon("edit_mode.svg"), + tip=_( + "Replay the selection step by step, editing parameters at each step" + ), + ), + } + actions["record"].setChecked(panel.runtime.execution.record_mode) + return actions + + def create_menu_actions(self) -> list[QW.QAction | None]: + """Return ordered actions and separators for menus and toolbar.""" + action = self.actions + return [ + action["record"], + action["new_session"], + None, + action["open"], + action["save"], + None, + action["step_prev"], + action["step_next"], + None, + action["replay"], + action["step_by_step"], + None, + action["duplicate"], + None, + action["remove_incompatible"], + action["delete"], + ] + + def setup_connections(self) -> None: + """Connect history-tree interactions to their owning components.""" + tree = self.panel.tree + tree.customContextMenuRequested.connect(self.show_context_menu) + tree.itemDoubleClicked.connect(self.panel.replay_restore_actions) + tree.itemSelectionChanged.connect(self.panel.navigation.sync_panel_selection) + tree.itemSelectionChanged.connect(self.update_actions_state) + tree.itemSelectionChanged.connect(self.panel.navigation.update_state_widget) + tree.itemSelectionChanged.connect( + self.panel.navigation.set_active_session_from_selection + ) + + def setup_layout(self) -> None: + """Install the toolbar, history tree, and workspace-state widget.""" + toolbar = QW.QToolBar(self.panel) + add_actions(toolbar, self.menu_actions) + widget = QW.QWidget(self.panel) + layout = QW.QVBoxLayout() + layout.addWidget(toolbar) + layout.addWidget(self.panel.tree) + layout.addWidget(self.state_widget) + layout.setContentsMargins(0, 0, 0, 0) + widget.setLayout(layout) + self.panel.addWidget(widget) + + def update_actions_state(self) -> None: + """Update action availability from history and step state.""" + has_history = len(self.panel) > 0 + self.actions["delete"].setEnabled(has_history) + self.actions["duplicate"].setEnabled(has_history) + self.actions["step_prev"].setEnabled(self.panel.navigation.can_step_prev()) + self.actions["step_next"].setEnabled(self.panel.navigation.can_step_next()) + + def show_context_menu(self, pos: QC.QPoint) -> None: + """Show the history context menu at a tree position.""" + self.panel.refresh_compatibility_items() + menu = QW.QMenu() + add_actions(menu, self.menu_actions) + menu.exec_(self.panel.tree.mapToGlobal(pos)) diff --git a/datalab/h5/history.py b/datalab/h5/history.py index 0b5b39c15..23c7d20b4 100644 --- a/datalab/h5/history.py +++ b/datalab/h5/history.py @@ -5,6 +5,7 @@ from __future__ import annotations import os.path as osp +from dataclasses import dataclass from typing import TYPE_CHECKING, Any from uuid import uuid4 @@ -21,9 +22,19 @@ from datalab.utils.qthelpers import qt_try_loadsave_file, save_restore_stds if TYPE_CHECKING: + from datalab.gui.panel.base import BaseDataPanel from datalab.gui.panel.history import HistoryPanel +@dataclass +class HistoryImportRegistry: + """Imported objects and their old-to-new UUID mappings.""" + + panel_map: dict[str, BaseDataPanel] + uuid_remap: dict[str, dict[str, str]] + imported_by_pstr: dict[str, list[Any]] + + def save_to_dlhist_file(panel: HistoryPanel, filename: str | None = None) -> bool: """Save the History Panel content to a standalone ``.dlhist`` file. @@ -106,110 +117,162 @@ def open_dlhist_file(panel: HistoryPanel, filename: str | None = None) -> bool: return True -def import_dlhist_into_new_session(panel: HistoryPanel, reader: NativeH5Reader) -> None: - """Import a ``.dlhist`` file into new groups and new history sessions. - - Used when the workspace already contains objects: the file's signal and - image objects are imported into fresh groups with regenerated UUIDs, and - the history sessions are appended as new independent sessions whose action - references are remapped to the freshly imported objects. - - Args: - reader: HDF5 reader positioned on a ``.dlhist`` file. - """ +def create_import_registry(panel: HistoryPanel) -> HistoryImportRegistry: + """Create empty per-panel object and UUID registries.""" panel_map = { "signal": panel.mainwindow.signalpanel, "image": panel.mainwindow.imagepanel, } - uuid_remap: dict[str, dict[str, str]] = {} - imported_by_pstr: dict[str, list] = {} - # 1. Import objects from each panel (each panel is read by its own - # H5_PREFIX key). Read each object preserving its original UUID to - # capture the old->new mapping, then assign a fresh UUID so that the - # imported objects keep an independent identity. - for pstr, data_panel in panel_map.items(): - uuid_remap[pstr] = {} - imported: list = [] - imported_by_pstr[pstr] = imported + return HistoryImportRegistry( + panel_map=panel_map, + uuid_remap={panel_str: {} for panel_str in panel_map}, + imported_by_pstr={panel_str: [] for panel_str in panel_map}, + ) + + +def assign_imported_uuid(obj: Any) -> tuple[str, str]: + """Assign a fresh UUID to an imported object and return both UUIDs.""" + old_uuid = get_uuid(obj) + new_uuid = str(uuid4()) + try: + obj.set_metadata_option("uuid", new_uuid) + except AttributeError: + obj.uuid = new_uuid + return old_uuid, new_uuid + + +def read_imported_group( + reader: NativeH5Reader, + data_panel: BaseDataPanel, + panel_str: str, + group_name: str, + registry: HistoryImportRegistry, +) -> None: + """Read one object group and register its regenerated UUIDs.""" + with reader.group(group_name): + group = data_panel.add_group("") + with reader.group("title"): + group.title = reader.read_str() + path = f"{data_panel.H5_PREFIX}/{group_name}" + for object_name in reader.h5.get(path, []): + obj = data_panel.deserialize_object_from_hdf5( + reader, object_name, reset_all=True + ) + old_uuid, new_uuid = assign_imported_uuid(obj) + registry.uuid_remap[panel_str][old_uuid] = new_uuid + data_panel.add_object(obj, get_uuid(group), set_current=False) + registry.imported_by_pstr[panel_str].append(obj) + data_panel.selection_changed() + + +def read_imported_objects( + reader: NativeH5Reader, registry: HistoryImportRegistry +) -> None: + """Read signal and image payloads into fresh object groups.""" + for panel_str, data_panel in registry.panel_map.items(): if data_panel.H5_PREFIX not in reader.h5: continue with reader.group(data_panel.H5_PREFIX): - for name in reader.h5.get(data_panel.H5_PREFIX, []): - with reader.group(name): - group = data_panel.add_group("") - with reader.group("title"): - group.title = reader.read_str() - for obj_name in reader.h5.get(f"{data_panel.H5_PREFIX}/{name}", []): - obj = data_panel.deserialize_object_from_hdf5( - reader, obj_name, reset_all=True - ) - old_uuid = get_uuid(obj) - new_uuid = str(uuid4()) - # SignalObj/ImageObj store UUID via metadata option - try: - obj.set_metadata_option("uuid", new_uuid) - except AttributeError: - obj.uuid = new_uuid - uuid_remap[pstr][old_uuid] = new_uuid - data_panel.add_object(obj, get_uuid(group), set_current=False) - imported.append(obj) - data_panel.selection_changed() - # 2. Remap source UUIDs in imported objects' processing_parameters so - # that reprocessing in the Processing tab uses the imported sources, - # not the originals (same logic as duplicate_selected_entries). - for pstr, objs in imported_by_pstr.items(): - pmap = uuid_remap.get(pstr, {}) - if not pmap: + for group_name in reader.h5.get(data_panel.H5_PREFIX, []): + read_imported_group(reader, data_panel, panel_str, group_name, registry) + + +def remap_imported_object_sources(obj: Any, uuid_remap: dict[str, str]) -> None: + """Remap processing source UUIDs stored on one imported object.""" + try: + parameters_dict = obj.get_metadata_option(PROCESSING_PARAMETERS_OPTION) + except (AttributeError, ValueError): + return + if not parameters_dict: + return + try: + parameters = ProcessingParameters.from_dict(parameters_dict) + except (TypeError, ValueError, AttributeError): + return + changed = False + if parameters.source_uuid is not None and parameters.source_uuid in uuid_remap: + parameters.source_uuid = uuid_remap[parameters.source_uuid] + changed = True + if parameters.source_uuids is not None: + new_sources = [uuid_remap.get(uuid, uuid) for uuid in parameters.source_uuids] + if new_sources != parameters.source_uuids: + parameters.source_uuids = new_sources + changed = True + if changed: + try: + obj.set_metadata_option(PROCESSING_PARAMETERS_OPTION, parameters.to_dict()) + except (AttributeError, ValueError): + pass + + +def remap_imported_sources(registry: HistoryImportRegistry) -> None: + """Remap processing sources for all imported objects.""" + for panel_str, objects in registry.imported_by_pstr.items(): + uuid_remap = registry.uuid_remap.get(panel_str, {}) + if not uuid_remap: continue - for obj in objs: - try: - pp_dict = obj.get_metadata_option(PROCESSING_PARAMETERS_OPTION) - except (AttributeError, ValueError): - continue - if not pp_dict: - continue - try: - pp = ProcessingParameters.from_dict(pp_dict) - except (TypeError, ValueError, AttributeError): - continue - changed = False - if pp.source_uuid is not None and pp.source_uuid in pmap: - pp.source_uuid = pmap[pp.source_uuid] - changed = True - if pp.source_uuids is not None: - new_src = [pmap.get(u, u) for u in pp.source_uuids] - if new_src != pp.source_uuids: - pp.source_uuids = new_src - changed = True - if changed: - try: - obj.set_metadata_option(PROCESSING_PARAMETERS_OPTION, pp.to_dict()) - except (AttributeError, ValueError): - pass - # 3. Import history sessions as new independent sessions whose captured - # UUIDs are remapped to the imported objects. + for obj in objects: + remap_imported_object_sources(obj, uuid_remap) + + +def assemble_imported_sessions( + panel: HistoryPanel, + reader: NativeH5Reader, + registry: HistoryImportRegistry, +) -> list[HistorySession] | None: + """Read history payload and clone sessions with remapped UUIDs.""" if panel.H5_PREFIX not in reader.h5: - return + return None sessions = reader.read_object_list(panel.H5_PREFIX, HistorySession) or [] imported_suffix = _("Imported") new_sessions: list[HistorySession] = [] for session in sessions: - panel.session_increment += 1 + panel.navigation.session_increment += 1 title = f"{session.title} {imported_suffix}" - new_session = session.copy_with_uuid_remap(title=title, uuid_remap=uuid_remap) - new_session.number = panel.session_increment + new_session = session.copy_with_uuid_remap( + title=title, uuid_remap=registry.uuid_remap + ) + new_session.number = panel.navigation.session_increment new_sessions.append(new_session) - # Register output mappings for imported actions so that - # resolve_target_outputs / get_downstream_actions work. - for action in new_session.actions: + return new_sessions + + +def register_imported_outputs( + panel: HistoryPanel, sessions: list[HistorySession] +) -> None: + """Register action output mappings for imported sessions.""" + for session in sessions: + for action in session.actions: if action.output_uuids: - panel.action_output_uuids[action.uuid] = list(action.output_uuids) - for out_uuid in action.output_uuids: - panel.output_to_action[out_uuid] = action.uuid - panel.history_sessions.extend(new_sessions) + panel.runtime.objects.register_action_outputs( + action, action.output_uuids + ) + + +def update_imported_history_ui( + panel: HistoryPanel, sessions: list[HistorySession] +) -> None: + """Append imported sessions and refresh history presentation.""" + panel.history_sessions.extend(sessions) panel.tree.populate_tree(panel.history_sessions) panel.refresh_compatibility_items() - panel.update_actions_state() + panel.ui.update_actions_state() + + +def import_dlhist_into_new_session(panel: HistoryPanel, reader: NativeH5Reader) -> None: + """Import a ``.dlhist`` file into new groups and new history sessions. + + Args: + reader: HDF5 reader positioned on a ``.dlhist`` file. + """ + registry = create_import_registry(panel) + read_imported_objects(reader, registry) + remap_imported_sources(registry) + sessions = assemble_imported_sessions(panel, reader, registry) + if sessions is None: + return + register_imported_outputs(panel, sessions) + update_imported_history_ui(panel, sessions) def refresh_compatibility_items(panel: HistoryPanel, *args: Any) -> None: @@ -237,28 +300,27 @@ def deserialize_from_hdf5( reset_all: Unused (kept for compatibility with panel API) """ del reset_all # required by the polymorphic panel API; unused here + panel.runtime.objects.clear_output_mappings() if panel.H5_PREFIX not in reader.h5: panel.history_sessions = [] - panel.session_increment = 0 + panel.navigation.session_increment = 0 panel.tree.populate_tree(panel.history_sessions) - panel.update_actions_state() + panel.ui.update_actions_state() return panel.history_sessions = ( reader.read_object_list(panel.H5_PREFIX, HistorySession) or [] ) if panel.history_sessions: - panel.session_increment = panel.history_sessions[-1].number + panel.navigation.session_increment = panel.history_sessions[-1].number # Rebuild the bijective mapping from the loaded actions. Legacy # (v1) actions have empty ``output_uuids`` and contribute nothing # to the index — the heuristic fallback handles them. - panel.action_output_uuids = {} - panel.output_to_action = {} for session in panel.history_sessions: for action in session.actions: if action.output_uuids: - panel.action_output_uuids[action.uuid] = list(action.output_uuids) - for out_uuid in action.output_uuids: - panel.output_to_action[out_uuid] = action.uuid + panel.runtime.objects.register_action_outputs( + action, action.output_uuids + ) panel.tree.populate_tree(panel.history_sessions) panel.refresh_compatibility_items() - panel.update_actions_state() + panel.ui.update_actions_state() diff --git a/datalab/history/action.py b/datalab/history/action.py index ced734326..fe948c82b 100644 --- a/datalab/history/action.py +++ b/datalab/history/action.py @@ -10,7 +10,18 @@ import logging import os from contextlib import nullcontext -from typing import TYPE_CHECKING, Any, Callable, Generator +from dataclasses import dataclass +from typing import ( + TYPE_CHECKING, + Any, + Callable, + Dict, + Generator, + Generic, + Optional, + TypeVar, + overload, +) from uuid import uuid4 import sigima.proc.image @@ -36,6 +47,33 @@ _logger = logging.getLogger(__name__) +T = TypeVar("T") + + +class DescriptorField(Generic[T]): + """Typed descriptor forwarding access to an action descriptor field.""" + + def __init__(self, name: str) -> None: + self.name = name + + @overload + def __get__( + self, instance: None, owner: type[HistoryAction] + ) -> DescriptorField[T]: ... + + @overload + def __get__(self, instance: HistoryAction, owner: type[HistoryAction]) -> T: ... + + def __get__( + self, instance: HistoryAction | None, owner: type[HistoryAction] + ) -> DescriptorField[T] | T: + if instance is None: + return self + return getattr(instance.descriptors, self.name) + + def __set__(self, instance: HistoryAction, value: T) -> None: + setattr(instance.descriptors, self.name, value) + class HistoryAction(ObjItf): """Object representing an action in the history panel. @@ -63,6 +101,26 @@ class HistoryAction(ObjItf): {"remove_object", "remove_group", "delete_all_objects"} ) + @dataclass + class Descriptors: + """Operation descriptors persisted by a history action.""" + + kind: str + panel_str: str | None = None + func_name: str | None = None + pattern: str | None = None + target: str | None = None + method_name: str | None = None + plugin_origin: dict[str, Any] | None = None + + kind = DescriptorField[str]("kind") + panel_str = DescriptorField[Optional[str]]("panel_str") + func_name = DescriptorField[Optional[str]]("func_name") + pattern = DescriptorField[Optional[str]]("pattern") + target = DescriptorField[Optional[str]]("target") + method_name = DescriptorField[Optional[str]]("method_name") + plugin_origin = DescriptorField[Optional[Dict[str, Any]]]("plugin_origin") + def __init__( self, title: str = "", @@ -77,18 +135,17 @@ def __init__( # --- common -------------------------------------------------------- kwargs: dict[str, Any] | None = None, state: WorkspaceState | None = None, - plugin_origin: dict[str, Any] | None = None, ) -> None: super().__init__() self.__title = title or "" - self.kind = kind - # Compute kind: - self.panel_str = panel_str - self.func_name = func_name - self.pattern = pattern - # UI kind: - self.target = target - self.method_name = method_name + self.descriptors = self.Descriptors( + kind=kind, + panel_str=panel_str, + func_name=func_name, + pattern=pattern, + target=target, + method_name=method_name, + ) # Common: self.kwargs: dict[str, Any] = ( {} if kwargs is None else {k: v for k, v in kwargs.items() if v is not None} @@ -109,7 +166,6 @@ def __init__( # ``add_compute_entry_from_pp``. See # :func:`datalab.gui.processor.base._detect_plugin_origin` for shape. # Persisted as a JSON string in HDF5. - self.plugin_origin: dict[str, Any] | None = plugin_origin # Transient flag (NOT serialized): set during a cascade recompute to # display a "stale" visual marker in the tree. Cleared once the # action has been recomputed. @@ -120,7 +176,7 @@ def __init__( # action still works after a save/reload cycle while Edit mode is # active. Cleared by ``discard_snapshot`` (definitive commit when # toggling Edit mode off) or ``restore_kwargs`` (Restore button). - self._saved_kwargs: dict[str, Any] | None = None + self.saved_kwargs: dict[str, Any] | None = None def snapshot_kwargs(self) -> None: """Save a copy of the current kwargs as the pre-edit baseline. @@ -128,25 +184,25 @@ def snapshot_kwargs(self) -> None: No-op if a snapshot already exists (preserves the original baseline across multiple edit-mode replays). """ - if self._saved_kwargs is None: - self._saved_kwargs = { + if self.saved_kwargs is None: + self.saved_kwargs = { key: copy_history_value(value) for key, value in self.kwargs.items() } def restore_kwargs(self) -> None: """Restore kwargs from the saved snapshot and clear the snapshot.""" - if self._saved_kwargs is not None: - self.kwargs = self._saved_kwargs - self._saved_kwargs = None + if self.saved_kwargs is not None: + self.kwargs = self.saved_kwargs + self.saved_kwargs = None def discard_snapshot(self) -> None: """Discard the saved snapshot (accept current kwargs as definitive).""" - self._saved_kwargs = None + self.saved_kwargs = None @property def has_pending_edits(self) -> bool: """Return True if this action has unsaved edit-mode changes.""" - return self._saved_kwargs is not None + return self.saved_kwargs is not None def copy(self, title_suffix: str | None = None) -> HistoryAction: """Return an independent copy of this history action.""" @@ -167,8 +223,9 @@ def copy(self, title_suffix: str | None = None) -> HistoryAction: }, state=state, ) + new_action.plugin_origin = copy_history_value(self.plugin_origin) new_action.output_uuids = list(self.output_uuids) - # Note: _saved_kwargs is intentionally NOT propagated to the copy. + # Note: saved_kwargs is intentionally NOT propagated to the copy. # Copying an action acts as an implicit commit (no pending edits). return new_action @@ -626,8 +683,8 @@ def serialize(self, writer: NativeH5Writer) -> None: # ``saved_kwargs``: persisted Edit mode snapshot so the Restore button # keeps working after save/reload. Group omitted when there are no # pending edits. - if self._saved_kwargs is not None: - encoded_saved = encode_kwargs(self._saved_kwargs) + if self.saved_kwargs is not None: + encoded_saved = encode_kwargs(self.saved_kwargs) # Write the group unconditionally (even when empty) so that the # round-trip preserves the distinction between None (no pending # edits) and {} (degenerate empty snapshot, keeps has_pending_edits). @@ -663,66 +720,87 @@ def deserialize(self, reader: NativeH5Reader) -> None: current = reader.h5 for option in reader.option: current = current.require_group(option) - # ``uuid`` is present only in files written after UUID persistence was - # added; keep the freshly generated ``self.uuid`` for older files. - if "uuid" in current.attrs or "uuid" in current: - with reader.group("uuid"): - loaded_uuid = reader.read_any() - if loaded_uuid: - self.uuid = str(loaded_uuid) - for attr in ("panel_str", "func_name", "pattern", "target", "method_name"): - if attr in current.attrs or attr in current: - with reader.group(attr): - setattr(self, attr, reader.read_any()) - else: - setattr(self, attr, None) - if "kwargs" in current.attrs or "kwargs" in current: - with reader.group("kwargs"): - raw = reader.read_dict() - self.kwargs = decode_kwargs(raw) - else: - self.kwargs = {} - # ``saved_kwargs`` group is present only when an Edit mode snapshot - # exists; otherwise leave it as ``None``. - if "saved_kwargs" in current.attrs or "saved_kwargs" in current: - with reader.group("saved_kwargs"): - raw_saved = reader.read_dict() - self._saved_kwargs = decode_kwargs(raw_saved) - else: - self._saved_kwargs = None - # ``output_uuids`` is present only when the action produced outputs; - # otherwise leave it empty and consumers fall back to the heuristic - # matcher. - if "output_uuids" in current.attrs or "output_uuids" in current: - with reader.group("output_uuids"): - raw_outputs = reader.read_any() - if raw_outputs is None: - self.output_uuids = [] - else: - self.output_uuids = [str(u) for u in raw_outputs] - else: - self.output_uuids = [] - # ``plugin_origin`` is present only for plugin-originated compute - # actions; otherwise leave it as ``None`` (a replay of a missing plugin - # function then surfaces a generic ``FeatureNotFoundError``). - if "plugin_origin" in current.attrs or "plugin_origin" in current: - with reader.group("plugin_origin"): - raw_origin = reader.read_any() - if raw_origin in (None, ""): - self.plugin_origin = None - else: - try: - self.plugin_origin = json.loads(raw_origin) - except (TypeError, ValueError): - _logger.warning( - "Failed to decode plugin_origin for action %s; " - "falling back to None.", - self.uuid, - ) - self.plugin_origin = None - else: - self.plugin_origin = None + deserialize_descriptors(self, reader, current) + deserialize_kwargs_snapshot(self, reader, current) + deserialize_outputs_plugin_origin(self, reader, current) with reader.group("state"): self.state.deserialize(reader) with reader.group("dtstr"): self.dtstr = reader.read_any() + + +def deserialize_descriptors( + action: HistoryAction, reader: NativeH5Reader, current: Any +) -> None: + """Deserialize optional identity and operation descriptors.""" + # ``uuid`` is present only in files written after UUID persistence was + # added; keep the freshly generated ``action.uuid`` for older files. + if "uuid" in current.attrs or "uuid" in current: + with reader.group("uuid"): + loaded_uuid = reader.read_any() + if loaded_uuid: + action.uuid = str(loaded_uuid) + for attr in ("panel_str", "func_name", "pattern", "target", "method_name"): + if attr in current.attrs or attr in current: + with reader.group(attr): + setattr(action, attr, reader.read_any()) + else: + setattr(action, attr, None) + + +def deserialize_kwargs_snapshot( + action: HistoryAction, reader: NativeH5Reader, current: Any +) -> None: + """Deserialize call arguments and the optional edit snapshot.""" + if "kwargs" in current.attrs or "kwargs" in current: + with reader.group("kwargs"): + raw = reader.read_dict() + action.kwargs = decode_kwargs(raw) + else: + action.kwargs = {} + # ``saved_kwargs`` group is present only when an Edit mode snapshot + # exists; otherwise leave it as ``None``. + if "saved_kwargs" in current.attrs or "saved_kwargs" in current: + with reader.group("saved_kwargs"): + raw_saved = reader.read_dict() + action.saved_kwargs = decode_kwargs(raw_saved) + else: + action.saved_kwargs = None + + +def deserialize_outputs_plugin_origin( + action: HistoryAction, reader: NativeH5Reader, current: Any +) -> None: + """Deserialize optional outputs and plugin provenance.""" + # ``output_uuids`` is present only when the action produced outputs; + # otherwise leave it empty and consumers fall back to the heuristic + # matcher. + if "output_uuids" in current.attrs or "output_uuids" in current: + with reader.group("output_uuids"): + raw_outputs = reader.read_any() + if raw_outputs is None: + action.output_uuids = [] + else: + action.output_uuids = [str(u) for u in raw_outputs] + else: + action.output_uuids = [] + # ``plugin_origin`` is present only for plugin-originated compute + # actions; otherwise leave it as ``None`` (a replay of a missing plugin + # function then surfaces a generic ``FeatureNotFoundError``). + if "plugin_origin" in current.attrs or "plugin_origin" in current: + with reader.group("plugin_origin"): + raw_origin = reader.read_any() + if raw_origin in (None, ""): + action.plugin_origin = None + else: + try: + action.plugin_origin = json.loads(raw_origin) + except (TypeError, ValueError): + _logger.warning( + "Failed to decode plugin_origin for action %s; " + "falling back to None.", + action.uuid, + ) + action.plugin_origin = None + else: + action.plugin_origin = None diff --git a/datalab/history/replaymap.py b/datalab/history/replaymap.py new file mode 100644 index 000000000..7d908d4ee --- /dev/null +++ b/datalab/history/replaymap.py @@ -0,0 +1,234 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +"""UUID reconciliation for history session replay.""" + +from __future__ import annotations + +from typing import TYPE_CHECKING + +from datalab.history.action import HistoryAction + +if TYPE_CHECKING: + from datalab.gui.panel.base import BaseDataPanel + + +class ReplayUuidMap: + """Reconcile recorded object UUIDs with objects created during replay. + + Args: + panels: Data panels participating in the replay + """ + + def __init__(self, panels: tuple[BaseDataPanel, ...]) -> None: + """Initialize an empty per-panel UUID reconciliation map.""" + self.panels = {panel.PANEL_STR_ID: panel for panel in panels} + self.mapping: dict[str, dict[str, str]] = { + panel_str: {} for panel_str in self.panels + } + self.unclaimed: dict[str, list[str]] = { + panel_str: [] for panel_str in self.panels + } + + def translate_uuid(self, panel_str: str, uuid: str) -> str: + """Translate a recorded UUID to its replay UUID.""" + return self.mapping.get(panel_str, {}).get(uuid, uuid) + + def snapshot_object_ids(self) -> dict[str, set[str]]: + """Return the current object UUIDs for every replay panel.""" + return { + panel_str: set(panel.objmodel.get_object_ids()) + for panel_str, panel in self.panels.items() + } + + def claim_action_inputs(self, action: HistoryAction) -> None: + """Claim replay objects corresponding to a compute action's inputs.""" + if action.kind != HistoryAction.KIND_COMPUTE: + return + panel_str = action.panel_str or "" + recorded_uuids = list(action.state.selection.get(panel_str, [])) + if action.pattern == "2_to_1": + second_uuids = action.kwargs.get("obj2_uuids") or [] + if isinstance(second_uuids, str): + second_uuids = [second_uuids] + recorded_uuids = list(second_uuids) + recorded_uuids + self.claim_inputs(panel_str, recorded_uuids, action) + + def claim_inputs( + self, panel_str: str, recorded_uuids: list[str], action: HistoryAction + ) -> None: + """Claim unassigned replay UUIDs for recorded input UUIDs.""" + unmapped = self.get_unmapped(panel_str, recorded_uuids) + if not unmapped: + return + panel_order = list(action.state.object_metadata.get(panel_str, {})) + if panel_order and all(uuid in panel_order for uuid in unmapped): + unmapped.sort(key=panel_order.index) + queue = self.unclaimed.get(panel_str, []) + if not queue: + return + assigned = self.match_exact_uuids(panel_str, unmapped, queue) + assigned.update(self.match_titles(panel_str, unmapped, queue, action)) + assigned.update(self.match_positions(panel_str, unmapped, queue, panel_order)) + self.unclaimed[panel_str] = [uuid for uuid in queue if uuid not in assigned] + + def get_unmapped(self, panel_str: str, recorded_uuids: list[str]) -> list[str]: + """Return distinct recorded UUIDs that have no replay mapping.""" + panel_mapping = self.mapping.get(panel_str, {}) + unmapped: list[str] = [] + for uuid in recorded_uuids: + if uuid not in unmapped and uuid not in panel_mapping: + unmapped.append(uuid) + return unmapped + + def match_exact_uuids( + self, panel_str: str, recorded_uuids: list[str], queue: list[str] + ) -> set[str]: + """Match recorded inputs whose UUID is present unchanged in the queue.""" + assigned = set(recorded_uuids).intersection(queue) + panel_mapping = self.mapping.setdefault(panel_str, {}) + panel_mapping.update({uuid: uuid for uuid in assigned}) + return assigned + + def match_titles( + self, + panel_str: str, + recorded_uuids: list[str], + queue: list[str], + action: HistoryAction, + ) -> set[str]: + """Match remaining inputs with the unique replay object of the same title.""" + old_titles = self.get_recorded_titles(panel_str, recorded_uuids, action) + new_titles = self.get_replay_titles(panel_str, queue) + panel_mapping = self.mapping.setdefault(panel_str, {}) + assigned = set(panel_mapping.values()).intersection(queue) + for old_uuid in recorded_uuids: + if old_uuid in panel_mapping or old_uuid not in old_titles: + continue + candidates = [ + new_uuid + for new_uuid in queue + if new_uuid not in assigned + and new_titles.get(new_uuid) == old_titles[old_uuid] + ] + if len(candidates) == 1: + panel_mapping[old_uuid] = candidates[0] + assigned.add(candidates[0]) + return assigned + + def get_recorded_titles( + self, panel_str: str, recorded_uuids: list[str], action: HistoryAction + ) -> dict[str, str]: + """Return recorded object titles indexed by UUID.""" + selected = action.state.selection.get(panel_str, []) + titles = action.state.titles.get(panel_str, []) + old_titles = { + uuid: title + for uuid, title in zip(selected, titles) + if uuid in recorded_uuids + } + metadata = action.state.object_metadata.get(panel_str, {}) + for uuid in recorded_uuids: + signature = metadata.get(uuid) + if uuid not in old_titles and isinstance(signature, dict): + title = signature.get("title") + if isinstance(title, str): + old_titles[uuid] = title + return old_titles + + def get_replay_titles( + self, panel_str: str, replay_uuids: list[str] + ) -> dict[str, str]: + """Return titles of queued replay objects that still exist.""" + panel = self.panels.get(panel_str) + if panel is None: + return {} + titles: dict[str, str] = {} + for uuid in replay_uuids: + try: + titles[uuid] = panel.objmodel[uuid].title + except KeyError: + continue + return titles + + def match_positions( + self, + panel_str: str, + recorded_uuids: list[str], + queue: list[str], + panel_order: list[str], + ) -> set[str]: + """Match remaining inputs by absolute or relative recorded position.""" + panel_mapping = self.mapping.setdefault(panel_str, {}) + old_remaining = [uuid for uuid in recorded_uuids if uuid not in panel_mapping] + assigned = set(panel_mapping.values()).intersection(queue) + new_remaining = [uuid for uuid in queue if uuid not in assigned] + if not old_remaining: + return assigned + free_indices = [ + index for index, uuid in enumerate(panel_order) if uuid not in panel_mapping + ] + if panel_order and len(new_remaining) == len(free_indices): + self.match_absolute_positions( + panel_mapping, old_remaining, new_remaining, panel_order, free_indices + ) + else: + panel_mapping.update(dict(zip(old_remaining, new_remaining))) + return set(panel_mapping.values()).intersection(queue) + + @staticmethod + def match_absolute_positions( + panel_mapping: dict[str, str], + old_uuids: list[str], + new_uuids: list[str], + panel_order: list[str], + free_indices: list[int], + ) -> None: + """Match remaining UUIDs using their absolute recorded panel positions.""" + new_by_index = dict(zip(free_indices, new_uuids)) + for old_uuid in old_uuids: + if old_uuid in panel_order: + index = panel_order.index(old_uuid) + if index in new_by_index: + panel_mapping[old_uuid] = new_by_index[index] + + def capture_changes( + self, action: HistoryAction, before: dict[str, set[str]] + ) -> None: + """Capture objects created and removed by a replayed action.""" + for panel_str, panel in self.panels.items(): + object_ids = panel.objmodel.get_object_ids() + current = set(object_ids) + self.discard_removed(panel_str, before[panel_str] - current) + created = [uuid for uuid in object_ids if uuid not in before[panel_str]] + self.capture_created(panel_str, created, action) + + def discard_removed(self, panel_str: str, removed_uuids: set[str]) -> None: + """Discard queued objects and mappings whose replay objects were removed.""" + if not removed_uuids: + return + self.unclaimed[panel_str] = [ + uuid + for uuid in self.unclaimed.get(panel_str, []) + if uuid not in removed_uuids + ] + panel_mapping = self.mapping.get(panel_str, {}) + for old_uuid in [ + uuid + for uuid, new_uuid in panel_mapping.items() + if new_uuid in removed_uuids + ]: + panel_mapping.pop(old_uuid) + + def capture_created( + self, panel_str: str, created_uuids: list[str], action: HistoryAction + ) -> None: + """Map or queue objects created by a replayed action.""" + if not created_uuids: + return + captured = action.state.selection.get(panel_str, []) + if action.kind == HistoryAction.KIND_UI and captured: + self.mapping.setdefault(panel_str, {}).update( + dict(zip(captured, created_uuids)) + ) + created_uuids = created_uuids[len(captured) :] + self.unclaimed.setdefault(panel_str, []).extend(created_uuids) diff --git a/datalab/history/session.py b/datalab/history/session.py index 7566ed9e6..3e1f0b63f 100644 --- a/datalab/history/session.py +++ b/datalab/history/session.py @@ -9,6 +9,7 @@ from datalab.config import _ from datalab.history.action import HistoryAction from datalab.history.core import HISTORY_SCHEMA_VERSION, get_datetime_str +from datalab.history.replaymap import ReplayUuidMap if TYPE_CHECKING: from datalab.gui.main import DLMainWindow @@ -113,222 +114,23 @@ def replay( edit: if True, always open the dialog boxes to edit parameters, if False, use the parameters passed when creating the action """ - # Per-panel ``{old_uuid: new_uuid}`` mapping, populated as UI actions - # create new objects. Used by compute actions to translate their - # captured selection (and ``obj2_uuids``) into the freshly-created - # UUIDs of the current replay, so chained ``n_to_1`` / ``2_to_1`` / - # ``1_to_n`` actions operate on the correct inputs. Keys are - # ``panel.PANEL_STR_ID`` (matches ``WorkspaceState.selection`` keys). panels = (mainwindow.signalpanel, mainwindow.imagepanel) - uuid_remap: dict[str, dict[str, str]] = {p.PANEL_STR_ID: {} for p in panels} - # FIFO of newly-created UUIDs not yet claimed by a remap entry -- - # required because most creation UI actions (e.g. ``new_signal``) - # are recorded with ``save_state=False`` (empty captured selection), - # so we cannot pair captured-vs-new UUIDs by position at UI time. - # Subsequent compute actions claim from this queue on demand. - unclaimed: dict[str, list[str]] = {p.PANEL_STR_ID: [] for p in panels} - - def _claim_unmapped( - pstr: str, - old_uuids: list[str], - action: HistoryAction, - ) -> None: - """Claim unclaimed new UUIDs for *old_uuids* not yet in uuid_remap. - - Uses title matching (scanning the full unclaimed queue) followed by - panel-order index alignment to deterministically pair old UUIDs - to the correct new UUIDs, regardless of creation order. - """ - # Collect unmapped UUIDs (deduplicated, preserving first-seen order). - all_unmapped: list[str] = [] - seen: set[str] = set() - for u in old_uuids: - if u not in seen and u not in uuid_remap.get(pstr, {}): - all_unmapped.append(u) - seen.add(u) - if not all_unmapped: - return - # Re-sort by recorded panel position when available. - panel_order = list(action.state.object_metadata.get(pstr, {}).keys()) - if panel_order and all(u in panel_order for u in all_unmapped): - all_unmapped.sort(key=panel_order.index) - queue = unclaimed.get(pstr) or [] - if not queue: - return - # Build old UUID → title from captured state and object_metadata. - sel_uuids = action.state.selection.get(pstr, []) - sel_titles = action.state.titles.get(pstr, []) - old_titles: dict[str, str] = {} - for _u, _t in zip(sel_uuids, sel_titles): - if _u in seen: - old_titles[_u] = _t - obj_meta = action.state.object_metadata.get(pstr, {}) - for _u in all_unmapped: - if _u not in old_titles and _u in obj_meta: - meta = obj_meta[_u] - if isinstance(meta, dict) and "title" in meta: - old_titles[_u] = meta["title"] - # Build new UUID → title from the live panel (full queue). - new_titles: dict[str, str] = {} - panel_obj = None - for p in panels: - if p.PANEL_STR_ID == pstr: - panel_obj = p - break - if panel_obj is not None: - for nu in queue: - try: - new_titles[nu] = panel_obj.objmodel[nu].title - except KeyError: - pass - # Phase 1: title matching against the FULL queue. - assigned_old: set[str] = set() - assigned_new: set[str] = set() - for ou in all_unmapped: - if ou not in old_titles: - continue - title = old_titles[ou] - candidates = [ - nu - for nu in queue - if nu not in assigned_new and new_titles.get(nu) == title - ] - if len(candidates) == 1: - uuid_remap.setdefault(pstr, {})[ou] = candidates[0] - assigned_old.add(ou) - assigned_new.add(candidates[0]) - # Phase 2: positional fallback using panel-order alignment. - # Two modes depending on whether the remaining queue covers all - # free recorded panel slots: - # - # A) Absolute index alignment (len(rem_queue) == len(free_indices)): - # Each free panel_order index maps 1-to-1 to a queue slot. - # This ensures e.g. the second-created object maps to the - # second queue entry even when only a subset of old UUIDs - # needs claiming. - # - # B) Relative order fallback (queue is a strict subset): - # The queue only contains later compute-created objects while - # earlier full-panel entries are absent. Absolute alignment - # would leave non-first old UUIDs unmapped. Instead, zip - # rem_old (already sorted by panel order) with rem_queue - # sequentially. - rem_old = [u for u in all_unmapped if u not in assigned_old] - if rem_old and panel_order: - rem_queue = [u for u in queue if u not in assigned_new] - # Find which panel_order indices are "free" (unclaimed). - free_indices: list[int] = [] - for idx, po_uuid in enumerate(panel_order): - if po_uuid not in uuid_remap.get(pstr, {}): - if po_uuid not in assigned_old: - free_indices.append(idx) - if len(rem_queue) == len(free_indices): - # Mode A: absolute index alignment. - idx_to_new: dict[int, str] = {} - for qi, fi in enumerate(free_indices): - if qi < len(rem_queue): - idx_to_new[fi] = rem_queue[qi] - for ou in rem_old: - if ou in panel_order: - idx = panel_order.index(ou) - if idx in idx_to_new: - nu = idx_to_new[idx] - uuid_remap.setdefault(pstr, {})[ou] = nu - assigned_new.add(nu) - else: - # Mode B: relative order fallback. - for ou, nu in zip(rem_old, rem_queue): - uuid_remap.setdefault(pstr, {})[ou] = nu - assigned_new.add(nu) - elif rem_old: - # No panel_order available: sequential fallback. - rem_queue = [u for u in queue if u not in assigned_new] - for ou, nu in zip(rem_old, rem_queue): - uuid_remap.setdefault(pstr, {})[ou] = nu - assigned_new.add(nu) - # Remove all assigned new UUIDs from the unclaimed queue. - if assigned_new: - unclaimed[pstr] = [u for u in queue if u not in assigned_new] - + replay_map = ReplayUuidMap(panels) for action in self.actions[:]: - before = {p.PANEL_STR_ID: set(p.objmodel.get_object_ids()) for p in panels} - if action.kind == HistoryAction.KIND_COMPUTE: - # Lazy-resolve any captured UUIDs missing from the remap by - # claiming from ``unclaimed`` (deterministic: title + panel-order). - pstr = action.panel_str or "" - captured = action.state.selection.get(pstr, []) - if action.pattern == "2_to_1": - # For 2_to_1: collect ALL unmapped old UUIDs from both - # captured selection and obj2_uuids in one batch so - # operand order is preserved by the helper. - obj2 = action.kwargs.get("obj2_uuids") or [] - if isinstance(obj2, str): - obj2 = [obj2] - _claim_unmapped(pstr, list(obj2) + list(captured), action) - else: - # For all other compute patterns (1_to_1, n_to_1, etc.): - # use the same deterministic helper. - _claim_unmapped(pstr, list(captured), action) + before = replay_map.snapshot_object_ids() + replay_map.claim_action_inputs(action) action.replay( mainwindow, restore_selection=restore_selection, edit=edit, - uuid_remap=uuid_remap, + uuid_remap=replay_map.mapping, ) - # Post-action bookkeeping: track new/removed UUIDs for *every* - # action kind so that later actions consuming compute-created - # outputs can resolve them through ``uuid_remap`` / ``unclaimed``. - for panel in panels: - pstr = panel.PANEL_STR_ID - current_ids = set(panel.objmodel.get_object_ids()) - new_uuids = [ - u for u in panel.objmodel.get_object_ids() if u not in before[pstr] - ] - # Drop vanished UUIDs from the unclaimed queue and the - # reverse remap entries (e.g. ``Remove selected objects``): - # this keeps the FIFO claim in sync with the live panel - # contents during chained creation/removal replays. - removed_uuids = before[pstr] - current_ids - if removed_uuids: - unclaimed[pstr] = [ - u for u in unclaimed.get(pstr, []) if u not in removed_uuids - ] - panel_map = uuid_remap.get(pstr, {}) - for old_key in [ - k for k, v in panel_map.items() if v in removed_uuids - ]: - panel_map.pop(old_key, None) - if not new_uuids: - continue - if action.kind == HistoryAction.KIND_UI: - captured = action.state.selection.get(pstr, []) - if captured: - # Captured post-action selection available: pair - # captured UUIDs with new UUIDs by position. - for old_uuid, new_uuid in zip(captured, new_uuids): - uuid_remap.setdefault(pstr, {})[old_uuid] = new_uuid - # Any extra newly-created UUIDs go to the queue. - unclaimed.setdefault(pstr, []).extend( - new_uuids[len(captured) :] - ) - else: - # No captured selection (typical of ``new_signal``): - # queue all new UUIDs for lazy claiming. - unclaimed.setdefault(pstr, []).extend(new_uuids) - else: - # Compute actions: queue all newly-created UUIDs so - # later actions can lazily claim them. Do NOT map - # captured input UUIDs to output UUIDs — compute - # inputs and outputs are semantically different. - unclaimed.setdefault(pstr, []).extend(new_uuids) - - # Visually close the replay: select the output of the last compute - # action so the user sees the final result highlighted in the panel. - # Without this, the very last action's output is never selected - # (intermediate actions are implicitly "closed" by the next - # iteration's input restore). + replay_map.capture_changes(action, before) + if self.actions: - select_last_compute_output(mainwindow, panels, uuid_remap, self.actions[-1]) + select_last_compute_output( + mainwindow, panels, replay_map.mapping, self.actions[-1] + ) def serialize(self, writer: NativeH5Writer) -> None: """Serialize this history session diff --git a/datalab/tests/features/common/history_app_test.py b/datalab/tests/features/common/history_app_test.py deleted file mode 100644 index 21eb83b56..000000000 --- a/datalab/tests/features/common/history_app_test.py +++ /dev/null @@ -1,196 +0,0 @@ -# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. - -""" -History application test - -Exercises the History panel's full feature set: - -* Record-mode toggle gating -* Entry recording for object creation, 1-to-1, 1-to-0, n-to-1 and 2-to-1 - processing patterns (covering ``BaseProcessor.compute_*`` and - ``BaseDataPanel`` history-emitting methods) -* Workspace state attached to processing entries -* Session creation and session-aware indexing -* Replay of a recorded action -* Action deletion (cascade within a session) -""" - -# pylint: disable=invalid-name # Allows short reference names like x, y, ... -# guitest: show - -import sigima.objects -import sigima.params -import sigima.proc.signal as sips -from qtpy import QtCore as QC -from sigima.tests.data import create_paracetamol_signal - -from datalab.config import _ -from datalab.env import execenv -from datalab.gui.panel.history import HistoryAction, HistorySession, WorkspaceState -from datalab.objectmodel import get_uuid -from datalab.tests import datalab_test_app_context - - -def _entry_titles(history) -> list[str]: - """Return the list of recorded entry titles, in chronological order.""" - return [action.title for action in history] - - -def _session_action_counts(history) -> list[int]: - """Return the number of recorded actions in each history session.""" - return [len(session.actions) for session in history.history_sessions] - - -def test_history_app(): - """Run history application test scenario""" - with datalab_test_app_context(history=True) as win: - history = win.historypanel - dock = win.docks[history] - win.addDockWidget(QC.Qt.LeftDockWidgetArea, dock) - win.resize(int(win.width() * 1.7), win.height()) - win.move(50, 50) - execenv.print("History application test:") - - panel = win.signalpanel - - # --- Record mode is OFF by default: nothing should be recorded --------- - assert len(history) == 0 - panel.add_object(create_paracetamol_signal()) - panel.processor.run_feature(sips.derivative) - assert len(history) == 0, ( - "Record mode is disabled: no entry should have been recorded" - ) - - # Reset workspace before starting the recorded scenario. - # No history exists yet, so this must not create an empty session. - win.reset_all() - assert len(history) == 0 - assert _session_action_counts(history) == [] - - # --- Enable record mode and start recording ---------------------------- - history.toggle_record_mode(True) - - # Pre-populate two real signals (``add_object`` does not record entries). - panel.add_object(create_paracetamol_signal()) - panel.add_object(create_paracetamol_signal()) - assert len(history) == 0 - - # 1) Object creation through the GUI path (BaseDataPanel.new_object): - # save_state=False, no workspace state is captured. - panel.new_object() - assert len(history) == 1 - creation_entry = history[1] - assert isinstance(creation_entry, HistoryAction) - assert creation_entry.title == _("New signal") - assert creation_entry.state.selection == {} - assert creation_entry.state.states == {} - - # 2) 1-to-1 processing (compute_1_to_1) on signal #1: save_state=True - panel.objview.select_objects([1]) - obj1_uuid = get_uuid(panel.objmodel.get_object_from_number(1)) - panel.processor.run_feature(sips.derivative) - assert len(history) == 2 - deriv_entry = history[2] - assert deriv_entry.title # title must be non-empty - # Workspace state must remember the single-object selection (by UUID) - assert deriv_entry.state.selection.get(panel.PANEL_STR_ID) == [obj1_uuid] - assert len(deriv_entry.state.states.get(panel.PANEL_STR_ID, [])) == 1 - - # 3) 1-to-1 with parameters (compute_1_to_1 + DataSet param) - norm_param = sigima.params.NormalizeParam.create(method="maximum") - panel.objview.select_objects([1]) - panel.processor.run_feature(sips.normalize, norm_param) - assert len(history) == 3 - norm_entry = history[3] - # The recorded kwargs must include the parameter (used in description) - assert any(k.endswith("param") for k in norm_entry.kwargs) - assert norm_entry.description # description is built from the param - - # 4) 1-to-0 analysis (compute_1_to_0) - panel.objview.select_objects([1]) - panel.processor.run_feature(sips.fwhm, sigima.params.FWHMParam()) - assert len(history) == 4 - fwhm_entry = history[4] - assert fwhm_entry.state.selection.get(panel.PANEL_STR_ID) == [obj1_uuid] - - # 5) n-to-1 aggregation (compute_n_to_1) on signals #1 and #2 - obj2 = panel.objmodel.get_object_from_number(2) - obj2_uuid = get_uuid(obj2) - panel.objview.select_objects([1, 2]) - panel.processor.run_feature(sips.average) - assert len(history) == 5 - avg_entry = history[5] - assert sorted(avg_entry.state.selection.get(panel.PANEL_STR_ID, [])) == sorted( - [obj1_uuid, obj2_uuid] - ) - - # 6) 2-to-1 binary operation (compute_2_to_1) - panel.objview.select_objects([1]) - panel.processor.run_feature(sips.difference, obj2) - assert len(history) == 6 - diff_entry = history[6] - assert diff_entry.state.selection.get(panel.PANEL_STR_ID) == [obj1_uuid] - - # --- Iteration / indexing API ------------------------------------------ - all_titles = _entry_titles(history) - assert len(all_titles) == 6 - assert all_titles[0] == _("New signal") - # Indexing is 1-based; iteration order matches index order - assert history[1] is creation_entry - assert history[6] is diff_entry - - # --- Sessions ---------------------------------------------------------- - history.create_new_session() - # New session does not change the action count - assert len(history) == 6 - before = len(history) - panel.objview.select_objects([1]) - panel.processor.run_feature(sips.absolute) - after = len(history) - assert after == before + 1 - new_session_entry = history[after] - assert new_session_entry.title - - # --- Replay ------------------------------------------------------------ - # Replaying the derivative entry must produce a new object without raising. - n_objects_before_replay = len(panel.objmodel) - deriv_entry.replay(win, restore_selection=True, edit=False) - assert len(panel.objmodel) > n_objects_before_replay - - # --- Record mode OFF stops further recording --------------------------- - count_before_off = len(history) - history.toggle_record_mode(False) - panel.objview.select_objects([1]) - panel.processor.run_feature(sips.absolute) - assert len(history) == count_before_off, ( - "Record mode disabled: subsequent operations must not be recorded" - ) - - # --- Workspace state types are well-formed ----------------------------- - for action in history: - assert isinstance(action, HistoryAction) - assert isinstance(action.state, WorkspaceState) - assert isinstance(action.title, str) - assert isinstance(action.dtstr, str) and action.dtstr - - # --- Delete cascade within a session ----------------------------------- - # ``delete_selected`` itself opens a confirmation dialog; we exercise the - # underlying ``HistorySession.remove_action`` path used by it. - target = new_session_entry - target_session: HistorySession | None = None - - for session in history.history_sessions: - if target in session.actions: - target_session = session - break - assert target_session is not None - - n_before = len(history) - target_session.remove_action(target) - assert len(history) < n_before - - execenv.print("==> OK") - - -if __name__ == "__main__": - test_history_app() diff --git a/datalab/tests/features/common/history_model_unit_test.py b/datalab/tests/features/common/history_model_unit_test.py new file mode 100644 index 000000000..348108336 --- /dev/null +++ b/datalab/tests/features/common/history_model_unit_test.py @@ -0,0 +1,145 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +"""Pure unit contracts for history persistence, copying and replay mapping.""" + +from __future__ import annotations + +import os +import tempfile + +from datalab.h5.native import NativeH5Writer +from datalab.history.action import HistoryAction +from datalab.history.core import HISTORY_ACTION_SCHEMA_VERSION, HISTORY_SCHEMA_VERSION +from datalab.history.session import HistorySession +from datalab.tests.features.common.history_test_helpers import ( + build_history_action, + build_replay_map, + build_workspace_state, + delete_hdf5_items_by_name, + read_history_sessions, +) + + +def test_action_hdf5_current_and_legacy_contract() -> None: + """Round-trip current fields and apply all legacy defaults.""" + action = build_history_action() + action.plugin_origin = { + "module": "example.plugin", + "metadata": {"entry_points": ["difference"]}, + } + action.snapshot_kwargs() + action.kwargs["pairwise"] = True + session = HistorySession(number=1) + session.add_action(action) + with tempfile.TemporaryDirectory() as tmpdir: + path = os.path.join(tmpdir, "history.dlhist") + with NativeH5Writer(path) as writer: + writer.write_object_list([session], "history_session") + current = read_history_sessions(path)[0].actions[0] + for attribute in ("selection", "states", "titles"): + values = getattr(action.state, attribute) + setattr(action.state, attribute, {"Signal Panel": values["signal"]}) + with NativeH5Writer(path) as writer: + writer.write_object_list([session], "history_session") + for field in ("schema_version", "uuid", "saved_kwargs", "output_uuids"): + delete_hdf5_items_by_name(writer.h5, field) + delete_hdf5_items_by_name(writer.h5, "object_metadata") + legacy = read_history_sessions(path)[0].actions[0] + assert current.uuid == action.uuid + assert current.schema_version == HISTORY_ACTION_SCHEMA_VERSION + assert current.output_uuids == ["output-uuid"] + assert current.plugin_origin == action.plugin_origin + assert current.has_pending_edits and bool(current.kwargs["pairwise"]) + assert legacy.schema_version == HISTORY_SCHEMA_VERSION + assert legacy.uuid != action.uuid and legacy.output_uuids == [] + assert not legacy.has_pending_edits and legacy.state.object_metadata == {} + assert legacy.state.selection == {"signal": ["source-uuid"]} + assert legacy.state.states == {"signal": ["(10,)"]} + assert legacy.state.titles == {"signal": ["Source"]} + + +def test_action_copy_remaps_all_uuid_references() -> None: + """Copy an action independently and rewrite every captured UUID field.""" + action = build_history_action() + action.plugin_origin = { + "module": "example.plugin", + "metadata": {"entry_points": ["difference"]}, + } + copied = action.copy_with_uuid_remap( + { + "signal": { + "source-uuid": "new-source", + "second-uuid": "new-second", + "output-uuid": "new-output", + } + } + ) + assert copied is not action and copied.uuid != action.uuid + assert copied.state.selection == {"signal": ["new-source"]} + assert copied.state.object_metadata == { + "signal": {"new-source": {"shape": [10], "ndim": 1, "title": "Source"}} + } + assert copied.kwargs["obj2_uuids"] == "new-second" + assert copied.output_uuids == ["new-output"] + assert copied.plugin_origin == action.plugin_origin + copied.state.object_metadata["signal"]["new-source"]["shape"] = [20] + copied.plugin_origin["metadata"]["entry_points"].append("average") + assert action.state.object_metadata["signal"]["source-uuid"]["shape"] == [10] + assert action.plugin_origin["metadata"]["entry_points"] == ["difference"] + + +def test_replay_uuid_map_matches_exact_title_and_position() -> None: + """Match replay inputs by exact UUID, unique title, then panel position.""" + replay_map, _signal_model, _image_model = build_replay_map( + [("same", "Exact"), ("new-position", "Other"), ("new-title", "Named")] + ) + replay_map.unclaimed["signal"] = ["same", "new-position", "new-title"] + state = build_workspace_state( + ["same", "old-title", "old-position"], ["Exact", "Named", "Recorded"] + ) + action = HistoryAction( + kind=HistoryAction.KIND_COMPUTE, panel_str="signal", state=state + ) + replay_map.claim_action_inputs(action) + assert replay_map.mapping["signal"] == { + "same": "same", + "old-title": "new-title", + "old-position": "new-position", + } + assert replay_map.unclaimed["signal"] == [] + + +def test_replay_uuid_map_preserves_operands_and_tracks_changes() -> None: + """Claim obj2 before primary inputs and track panel-local object changes.""" + replay_map, signal_model, image_model = build_replay_map( + [("new-second", "Second"), ("new-primary", "Primary")], + [("image-old", "Image")], + ) + replay_map.unclaimed["signal"] = ["new-second", "new-primary"] + action = HistoryAction( + kind=HistoryAction.KIND_COMPUTE, + panel_str="signal", + pattern="2_to_1", + kwargs={"obj2_uuids": ["old-second"]}, + state=build_workspace_state(["old-primary"], ["Primary"]), + ) + replay_map.claim_action_inputs(action) + assert replay_map.mapping["signal"] == { + "old-second": "new-second", + "old-primary": "new-primary", + } + before = replay_map.snapshot_object_ids() + signal_model.add("signal-new", "Created") + replay_map.capture_changes( + HistoryAction( + kind=HistoryAction.KIND_UI, + state=build_workspace_state(["old-new"]), + ), + before, + ) + assert replay_map.mapping["signal"]["old-new"] == "signal-new" + before = replay_map.snapshot_object_ids() + signal_model.remove("signal-new") + replay_map.capture_changes(HistoryAction(), before) + assert "old-new" not in replay_map.mapping["signal"] + assert image_model.get_object_ids() == ["image-old"] diff --git a/datalab/tests/features/common/history_panel_test.py b/datalab/tests/features/common/history_panel_test.py new file mode 100644 index 000000000..0644cc830 --- /dev/null +++ b/datalab/tests/features/common/history_panel_test.py @@ -0,0 +1,158 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +"""History panel replay and cross-panel navigation contracts.""" + +from __future__ import annotations + +import sigima.proc.image as sipi +import sigima.proc.signal as sips +from qtpy import QtCore as QC +from qtpy import QtWidgets as QW +from sigima.tests.data import create_paracetamol_signal, create_sincos_image + +from datalab.gui.panel.history import HistoryTree +from datalab.objectmodel import get_uuid +from datalab.tests import datalab_test_app_context +from datalab.tests.features.common.history_test_helpers import ( + build_signal_chain, + get_tree_item, + is_session_bold, + select_tree_entry, +) + + +def test_panel_replay_restores_selection_without_outputs() -> None: + """Use panel replay to restore selection without recording or new output.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + panel.add_object(create_paracetamol_signal()) + source_uuid = get_uuid(panel.objmodel.get_object_from_number(1)) + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.derivative) + action = history[len(history)] + output_uuid = action.output_uuids[0] + select_tree_entry(history, action.uuid) + assert panel.objview.get_sel_object_uuids() == [output_uuid] + object_count, action_count = len(panel.objmodel), len(history) + history.replay_restore_actions(replay=True, restore_selection=True) + assert ( + len(panel.objmodel), + len(history), + panel.objview.get_sel_object_uuids(), + ) == (object_count, action_count, [source_uuid]) + assert action in history.history_sessions[-1].actions and ( + history.runtime.objects.action_output_uuids[action.uuid] == [output_uuid] + ) + assert ( + output_uuid in panel.objmodel.get_object_ids() + and history.runtime.objects.output_to_action[output_uuid] == action.uuid + ) + panel.objview.select_objects([output_uuid]) + panel.remove_object(force=True) + assert ( + action in history.history_sessions[-1].actions + and output_uuid not in panel.objmodel.get_object_ids() + and action.uuid not in history.runtime.objects.action_output_uuids + and output_uuid not in history.runtime.objects.output_to_action + ) + select_tree_entry(history, action.uuid) + history.replay_restore_actions(replay=False, restore_selection=True) + assert panel.objview.get_sel_object_uuids() == [source_uuid] + + +def test_cross_panel_sessions_navigation_and_tree_state() -> None: + """Coordinate active sessions, navigation, tree state and selection fallback.""" + with datalab_test_app_context(history=True) as win: + history = win.historypanel + signal_panel, image_panel = win.signalpanel, win.imagepanel + history.toggle_record_mode(True) + signal_chain = build_signal_chain(signal_panel, history) + first_signal_action, middle_signal_action, last_signal_action = ( + signal_chain.actions + ) + signal_uuid = first_signal_action.state.selection["signal"][0] + signal_session = next( + session + for session in history.history_sessions + if first_signal_action in session.actions + ) + assert all(action in signal_session.actions for action in signal_chain.actions) + navigation_states = [] + select_tree_entry(history, first_signal_action.uuid) + navigation_states.append( + ( + history.ui.actions["step_prev"].isEnabled(), + history.ui.actions["step_next"].isEnabled(), + ) + ) + select_tree_entry(history, middle_signal_action.uuid) + navigation_states.append( + ( + history.ui.actions["step_prev"].isEnabled(), + history.ui.actions["step_next"].isEnabled(), + ) + ) + select_tree_entry(history, last_signal_action.uuid) + navigation_states.append( + ( + history.ui.actions["step_prev"].isEnabled(), + history.ui.actions["step_next"].isEnabled(), + ) + ) + assert navigation_states == [(False, True), (True, True), (True, False)] + image_panel.add_object(create_sincos_image()) + image_panel.objview.select_objects([1]) + image_panel.processor.run_feature(sipi.inverse) + image_action = history[len(history)] + image_session = history.navigation.get_active_session("image") + assert ( + history.navigation.get_active_session("signal") is signal_session + and image_session is not None + and signal_session is not image_session + ) + bold_before = ( + is_session_bold(history, signal_session), + is_session_bold(history, image_session), + ) + history.tree.populate_tree(history.history_sessions) + assert bold_before == (True, True) and ( + is_session_bold(history, signal_session), + is_session_bold(history, image_session), + ) == (True, True) + output_uuid = first_signal_action.output_uuids[0] + select_tree_entry(history, first_signal_action.uuid) + assert signal_panel.objview.get_sel_object_uuids() == [output_uuid] + signal_panel.objview.select_objects([output_uuid]) + signal_panel.remove_object(force=True) + history.toggle_record_mode(False) + image_panel.objview.select_objects([1]) + image_panel.remove_object(force=True) + history.refresh_compatibility_items() + tree_action_uuids = set() + iterator = QW.QTreeWidgetItemIterator(history.tree) + while iterator.value(): + uuid = iterator.value().data(0, QC.Qt.UserRole) + if uuid is not None: + tree_action_uuids.add(uuid) + iterator += 1 + image_item = get_tree_item(history, image_action.uuid) + assert ( + all( + first_signal_action not in session.actions + for session in history.history_sessions + ) + and middle_signal_action in signal_session.actions + and last_signal_action in signal_session.actions + and middle_signal_action.state.selection["signal"] == [signal_uuid] + and first_signal_action.uuid + not in history.runtime.objects.action_output_uuids + and output_uuid not in history.runtime.objects.output_to_action + and first_signal_action.uuid not in tree_action_uuids + and {middle_signal_action.uuid, last_signal_action.uuid}.issubset( + tree_action_uuids + ) + and image_item.data(0, HistoryTree.COMPATIBILITY_ROLE) is False + and image_item.foreground(0).color().isValid() + and image_item.data(0, QC.Qt.UserRole) == image_action.uuid + ) diff --git a/datalab/tests/features/common/history_test.py b/datalab/tests/features/common/history_test.py deleted file mode 100644 index 7acc8ce02..000000000 --- a/datalab/tests/features/common/history_test.py +++ /dev/null @@ -1,2122 +0,0 @@ -# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. - -""" -History panel — grouped exhaustive tests. - -The History-panel behaviour is exercised by exactly five grouped tests, each -bundling many closely-related scenarios that previously lived in dedicated -per-behaviour tests: - -* ``test_history_persistence`` — schema versioning, HDF5/.dlhist round-trips - and ``HistoryAction`` compatibility (UUID/shape/legacy fallback). -* ``test_history_recording_and_replay`` — recording of compute + UI actions, - per-pattern replay (1_to_1, 1_to_n, n_to_1, 2_to_1), session replay, - interactive-fit replay and ``capture_outputs`` funnel behaviour. -* ``test_history_duplication`` — action/session duplication, UUID remapping - and the creation-root vs synthetic-head duplication cases. -* ``test_history_editing_and_cascade`` — processing-tab edit propagation, - step-by-step launch, cascade recompute and recompute invariants. -* ``test_history_navigation_and_chains`` — stepping/selection sync, chain - reconnection/grouping/splitting, new-session prompt and active-session - routing/highlight. - -Each scenario is delimited by a ``# --- scenario: <name> ---`` comment. -Scenarios sharing GUI state run inside a single ``datalab_test_app_context`` -block; truly independent pure-Python scenarios (HDF5 round-trip, -``NotImplementedError`` smoke) run outside or in a nested block. - -Two GUI smoke tests are intentionally kept in their own modules: -``history_app_test.py::test_history_app`` and -``history_panel_app_test.py::test_history_panel``. -""" - -# guitest: skip - -import os -import shutil -import tempfile - -import numpy as np -import pytest -import sigima.objects -import sigima.params -import sigima.proc.image as sipi -import sigima.proc.signal as sips -from qtpy import QtCore as QC -from qtpy import QtWidgets as QW -from sigima.objects import create_signal_roi -from sigima.objects.base import BaseROI -from sigima.objects.signal.creation import NewSignalParam -from sigima.tests import helpers -from sigima.tests.data import create_paracetamol_signal, create_sincos_image - -from datalab.config import _ -from datalab.env import execenv -from datalab.gui.panel.base import AddMetadataParam, BaseDataPanel -from datalab.gui.panel.history import ( - HISTORY_ACTION_SCHEMA_VERSION, - HISTORY_SCHEMA_VERSION, - HistoryAction, - HistorySession, - HistoryTree, - WorkspaceState, -) -from datalab.gui.panel.history.chainmodel import ( - ProcessingChain, - build_processing_chains, - build_session_chains, -) -from datalab.gui.processor.base import extract_processing_parameters -from datalab.h5.native import NativeH5Reader, NativeH5Writer -from datalab.objectmodel import get_uuid -from datalab.tests import datalab_test_app_context - -# --------------------------------------------------------------------------- -# Helpers -# --------------------------------------------------------------------------- - - -def _delete_hdf5_items_by_name(group, item_name: str) -> None: - """Delete HDF5 attributes/groups named ``item_name`` recursively.""" - if item_name in group.attrs: - del group.attrs[item_name] - if not hasattr(group, "keys"): - return - for key in list(group.keys()): - if key == item_name: - del group[key] - else: - _delete_hdf5_items_by_name(group[key], item_name) - - -def _create_serializable_history_session() -> HistorySession: - """Create a history session requiring no application startup.""" - state = WorkspaceState() - state.selection = {"signal": ["source-uuid"]} - state.states = {"signal": ["(10,)"]} - state.titles = {"signal": ["source"]} - state.object_metadata = {"signal": {"source-uuid": {"shape": [10], "ndim": 1}}} - action = HistoryAction( - title="Rename", - kind=HistoryAction.KIND_UI, - target="signalpanel", - method_name="set_current_object_title", - kwargs={"title": "renamed"}, - state=state, - ) - session = HistorySession(number=1) - session.add_action(action) - return session - - -def _session_action_counts(history) -> list[int]: - """Return the number of recorded actions in each history session.""" - return [len(session.actions) for session in history.history_sessions] - - -def _get_tree_item_for(history, entry: HistoryAction): - """Return the tree item matching ``entry`` in the history tree.""" - tree = history.tree - iterator = QW.QTreeWidgetItemIterator(tree) - while iterator.value(): - item = iterator.value() - if item.data(0, QC.Qt.UserRole) == entry.uuid: - return item - iterator += 1 - raise AssertionError(f"No tree item found for entry {entry.uuid}") - - -def _select_tree_item_for(history, entry: HistoryAction) -> None: - """Select the tree item matching ``entry`` in the history tree.""" - child = _get_tree_item_for(history, entry) - history.tree.clearSelection() - history.tree.setCurrentItem(child) - child.setSelected(True) - - -def _select_tree_session(history, session) -> None: - """Select the tree item matching ``session`` in the history tree.""" - sessions = history.history_sessions - index = sessions.index(session) - item = history.tree.topLevelItem(index) - history.tree.clearSelection() - history.tree.setCurrentItem(item) - item.setSelected(True) - - -def _record_three_action_session(win): - """Helper: record [add_signal + normalize + derivative] in one session.""" - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - panel.add_object(create_paracetamol_signal()) - panel.objview.select_objects([1]) - panel.processor.run_feature( - sips.normalize, sigima.params.NormalizeParam.create(method="maximum") - ) - panel.objview.select_objects([2]) - panel.processor.run_feature(sips.derivative) - return panel, history - - -def _build_cascade_chain(panel, history): - """Build chain s001 -> gaussian -> s002 -> derivative -> s003 -> mavg -> s004. - - Returns ``(action_a, action_b, action_c, output_b, output_c)``. - """ - panel.add_object(create_paracetamol_signal()) - panel.objview.select_objects([1]) - panel.processor.run_feature( - sips.gaussian_filter, sigima.params.GaussianParam.create(sigma=1.5) - ) - action_a = history[len(history)] - - panel.objview.select_objects([2]) - panel.processor.run_feature(sips.derivative) - action_b = history[len(history)] - output_b = panel.objmodel.get_object_from_number(3) - - panel.objview.select_objects([3]) - mavg = sigima.params.MovingAverageParam() - mavg.n = 3 - panel.processor.run_feature(sips.moving_average, mavg) - action_c = history[len(history)] - output_c = panel.objmodel.get_object_from_number(4) - return action_a, action_b, action_c, output_b, output_c - - -# --------------------------------------------------------------------------- -# 1) Persistence: schema, HDF5/.dlhist round-trips, compatibility -# --------------------------------------------------------------------------- - - -def test_history_persistence(): - """Schema, HDF5/.dlhist round-trips and ``HistoryAction`` compatibility.""" - # --- scenario: schema_version is persisted --- - session = _create_serializable_history_session() - with tempfile.TemporaryDirectory() as tmpdir: - path = os.path.join(tmpdir, "history_schema.dlhist") - with NativeH5Writer(path) as writer: - writer.write_object_list([session], "history_session") - with NativeH5Reader(path) as reader: - restored_sessions = reader.read_object_list( - "history_session", HistorySession - ) - assert len(restored_sessions) == 1 - restored = restored_sessions[0] - assert restored.schema_version == HISTORY_SCHEMA_VERSION - assert restored.actions[0].schema_version == HISTORY_ACTION_SCHEMA_VERSION - assert restored.actions[0].kwargs == {"title": "renamed"} - assert restored.actions[0].state.object_metadata == { - "signal": {"source-uuid": {"shape": [10], "ndim": 1}} - } - - # --- scenario: missing schema_version defaults to current --- - session = _create_serializable_history_session() - with tempfile.TemporaryDirectory() as tmpdir: - path = os.path.join(tmpdir, "history_schema_missing.dlhist") - with NativeH5Writer(path) as writer: - writer.write_object_list([session], "history_session") - _delete_hdf5_items_by_name(writer.h5, "schema_version") - with NativeH5Reader(path) as reader: - restored_sessions = reader.read_object_list( - "history_session", HistorySession - ) - restored_action = restored_sessions[0].actions[0] - assert restored_sessions[0].schema_version == HISTORY_SCHEMA_VERSION - assert restored_action.schema_version == HISTORY_SCHEMA_VERSION - assert restored_action.title == "Rename" - - # --- scenario: ROI kwargs survive HDF5 round-trip --- - roi = create_signal_roi([[26, 41]], indices=True) - state = WorkspaceState() - state.selection = {"signal": ["dst-uuid"]} - state.states = {"signal": ["(100,)"]} - state.titles = {"signal": ["dst"]} - state.object_metadata = {"signal": {"dst-uuid": {"shape": [100], "ndim": 1}}} - action = HistoryAction( - title="Paste ROI", - kind=HistoryAction.KIND_UI, - target="signalpanel", - method_name="paste_roi", - kwargs={"roi_data": roi}, - state=state, - ) - session = HistorySession(number=1) - session.add_action(action) - with tempfile.TemporaryDirectory() as tmpdir: - path = os.path.join(tmpdir, "roi_roundtrip.dlhist") - with NativeH5Writer(path) as writer: - writer.write_object_list([session], "history_session") - with NativeH5Reader(path) as reader: - restored_sessions = reader.read_object_list( - "history_session", HistorySession - ) - restored_roi = restored_sessions[0].actions[0].kwargs.get("roi_data") - assert restored_roi is not None - assert isinstance(restored_roi, BaseROI) - assert restored_roi.get_single_roi(0).coords.tolist() == [26, 41] - - # --- scenario: legacy translated panel keys are normalized --- - state = WorkspaceState() - state.selection = {"Signal Panel": ["uuid-1"]} - state.states = {"Signal Panel": ["(10,)"]} - state.titles = {"Signal Panel": ["obj1"]} - state.object_metadata = {"Signal Panel": {"uuid-1": {"shape": [10], "ndim": 1}}} - legacy_action = HistoryAction( - title="Legacy", - kind=HistoryAction.KIND_UI, - target="signalpanel", - method_name="set_current_object_title", - kwargs={"title": "renamed"}, - state=state, - ) - legacy_session = HistorySession(number=1) - legacy_session.add_action(legacy_action) - with tempfile.TemporaryDirectory() as tmpdir: - path = os.path.join(tmpdir, "legacy_keys.dlhist") - with NativeH5Writer(path) as writer: - writer.write_object_list([legacy_session], "history_session") - with NativeH5Reader(path) as reader: - restored_sessions = reader.read_object_list( - "history_session", HistorySession - ) - rstate = restored_sessions[0].actions[0].state - assert "signal" in rstate.selection and "Signal Panel" not in rstate.selection - assert rstate.selection["signal"] == ["uuid-1"] - assert rstate.states["signal"] == ["(10,)"] - assert rstate.titles["signal"] == ["obj1"] - assert rstate.object_metadata["signal"] == {"uuid-1": {"shape": [10], "ndim": 1}} - - # GUI-bound HDF5 scenarios run inside one app context. - with datalab_test_app_context(history=True) as win: - history = win.historypanel - panel = win.signalpanel - - # --- scenario: deserialize from .h5 without history group does not raise --- - with tempfile.TemporaryDirectory() as tmpdir: - path = os.path.join(tmpdir, "no_history.h5") - with NativeH5Writer(path) as writer: - panel.serialize_to_hdf5(writer) - with NativeH5Reader(path) as reader: - history.deserialize_from_hdf5(reader) - assert len(history) == 0 - - # --- scenario: HistoryAction HDF5 round-trip without pickle, then replay --- - history.toggle_record_mode(True) - panel.add_object(create_paracetamol_signal()) - src_uuid = get_uuid(panel.objmodel.get_object_from_number(1)) - norm_param = sigima.params.NormalizeParam.create(method="maximum") - panel.objview.select_objects([1]) - panel.processor.run_feature(sips.normalize, norm_param) - original = history[len(history)] - ser_session = HistorySession(number=1) - ser_session.actions.append(original) - with tempfile.TemporaryDirectory() as tmpdir: - path = os.path.join(tmpdir, "history.dlhist") - with NativeH5Writer(path) as writer: - writer.write_object_list([ser_session], "history_session") - with NativeH5Reader(path) as reader: - restored_sessions = reader.read_object_list( - "history_session", HistorySession - ) - restored = restored_sessions[0].actions[0] - assert restored.uuid == original.uuid - assert not hasattr(restored, "func") - assert restored.kind == HistoryAction.KIND_COMPUTE - assert restored.func_name == "normalize" - assert restored.pattern == "1_to_1" - assert restored.panel_str == panel.PANEL_STR_ID - restored_param = restored.kwargs.get("param") - assert restored_param is not None - assert type(restored_param).__name__ == type(norm_param).__name__ - n_before = len(panel.objmodel) - restored.replay(win, restore_selection=True, edit=False) - assert len(panel.objmodel) == n_before + 1 - new_obj = panel.objmodel.get_object_from_number(len(panel.objmodel)) - new_pp = extract_processing_parameters(new_obj) - assert new_pp is not None - assert new_pp.source_uuid == src_uuid - assert new_pp.func_name == "normalize" - - # --- scenario: workspace .h5 round-trip embeds history --- - recorded_titles = [a.title for a in history] - recorded_func_names = [a.func_name for a in history] - recorded_kinds = [a.kind for a in history] - assert len(history) >= 1 - with helpers.WorkdirRestoringTempDir() as tmpdir: - path = os.path.join(tmpdir, "workspace.h5") - win.save_h5_workspace(path) - win.reset_all() - assert len(panel.objmodel) == 0 - win.load_h5_workspace([path], reset_all=True) - reloaded = win.historypanel - reloaded_titles = [a.title for a in reloaded] - for title in recorded_titles: - assert title in reloaded_titles - for func_name in recorded_func_names: - if func_name is not None: - assert func_name in [a.func_name for a in reloaded] - for kind in recorded_kinds: - assert kind in [a.kind for a in reloaded] - - # --- scenario: standalone .dlhist round-trip (import path on non-empty WS) --- - win.reset_all() - history = win.historypanel - panel = win.signalpanel - history.toggle_record_mode(True) - panel.add_object(create_paracetamol_signal()) - panel.objview.select_objects([1]) - panel.processor.run_feature(sips.derivative) - panel.objview.select_objects([1]) - panel.processor.run_feature( - sips.normalize, sigima.params.NormalizeParam.create(method="maximum") - ) - original_titles = [a.title for a in history] - original_func_names = [a.func_name for a in history] - assert len(original_titles) >= 2 - n_actions_before = len(history) - n_signals_before = len(panel.objmodel) - n_sessions_before = len(history.history_sessions) - with helpers.WorkdirRestoringTempDir() as tmpdir: - path = os.path.join(tmpdir, "history_panel.dlhist") - assert history.save_to_dlhist_file(path) - assert history.open_dlhist_file(path) - reloaded_titles = [a.title for a in history] - reloaded_func_names = [a.func_name for a in history] - for title in original_titles: - assert title in reloaded_titles - for func_name in original_func_names: - if func_name is not None: - assert func_name in reloaded_func_names - assert len(history.history_sessions) > n_sessions_before - assert len(panel.objmodel) > n_signals_before - assert len(history) > n_actions_before - - # --- scenario: .dlhist self-contained — direct-load into fresh empty workspace --- - tmpdir = tempfile.mkdtemp() - try: - path = os.path.join(tmpdir, "test.dlhist") - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - panel.add_object(create_paracetamol_signal()) - panel.objview.select_objects([1]) - panel.processor.run_feature(sips.derivative) - original_titles = [a.title for a in history] - original_func_names = [a.func_name for a in history] - assert len(original_titles) >= 1 - assert history.save_to_dlhist_file(path) - with datalab_test_app_context(history=True) as win2: - history2 = win2.historypanel - panel2 = win2.signalpanel - assert len(panel2.objmodel) == 0 - assert len(history2.history_sessions) == 0 - assert history2.open_dlhist_file(path) - reloaded_titles = [a.title for a in history2] - reloaded_func_names = [a.func_name for a in history2] - assert reloaded_titles == original_titles - for func_name in original_func_names: - if func_name is not None: - assert func_name in reloaded_func_names - assert len(panel2.objmodel) >= 1 - finally: - shutil.rmtree(tmpdir, ignore_errors=True) - - # --- scenario: incompatible when selected UUID disappears --- - with datalab_test_app_context(history=True) as win: - panel = win.signalpanel - panel.add_object(create_paracetamol_signal()) - obj = panel.objmodel.get_object_from_number(1) - panel.objview.set_current_object(obj) - state = WorkspaceState() - state.save(win) - action = HistoryAction(title="Dummy", state=state) - assert action.is_current_state_compatible(win, restore_selection=False) - panel.remove_object(force=True) - assert not action.is_current_state_compatible(win, restore_selection=False) - - # --- scenario: incompatible when selected object shape changes --- - win.reset_all() - panel.add_object(create_paracetamol_signal()) - obj = panel.objmodel.get_object_from_number(1) - panel.objview.set_current_object(obj) - state = WorkspaceState() - state.save(win) - action = HistoryAction(title="Dummy", state=state) - assert action.is_current_state_compatible(win, restore_selection=False) - obj.set_xydata(obj.x[:-1], obj.y[:-1]) - assert not action.is_current_state_compatible(win, restore_selection=False) - - # --- scenario: histories without object_metadata fall back to UUID check --- - win.reset_all() - panel.add_object(create_paracetamol_signal()) - obj = panel.objmodel.get_object_from_number(1) - panel.objview.set_current_object(obj) - state = WorkspaceState() - state.save(win) - action = HistoryAction(title="Dummy", state=state) - session = HistorySession(number=1) - session.add_action(action) - with tempfile.TemporaryDirectory() as tmpdir: - path = os.path.join(tmpdir, "history_without_gate2_metadata.dlhist") - with NativeH5Writer(path) as writer: - writer.write_object_list([session], "history_session") - _delete_hdf5_items_by_name(writer.h5, "object_metadata") - with NativeH5Reader(path) as reader: - restored_sessions = reader.read_object_list( - "history_session", HistorySession - ) - restored_action = restored_sessions[0].actions[0] - assert restored_action.state.object_metadata == {} - assert restored_action.is_current_state_compatible(win, restore_selection=False) - - # --- scenario: tree marks incompatible action after source deletion --- - win.reset_all() - history = win.historypanel - history.toggle_record_mode(True) - panel.add_object(create_paracetamol_signal()) - panel.objview.select_objects([1]) - panel.processor.run_feature(sips.derivative) - deriv_entry = history[len(history)] - item = _get_tree_item_for(history, deriv_entry) - assert item.data(0, HistoryTree.COMPATIBILITY_ROLE) is True - history.toggle_record_mode(False) - panel.objview.select_objects([1]) - panel.remove_object(force=True) - history.refresh_compatibility_items() - item = _get_tree_item_for(history, deriv_entry) - assert item.data(0, HistoryTree.COMPATIBILITY_ROLE) is False - assert item.foreground(0).color().isValid() - - # --- scenario: action WorkspaceState is panel-scoped --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - spanel, ipanel = win.signalpanel, win.imagepanel - - # Create a signal and keep it selected in the signal panel. - spanel.add_object(create_paracetamol_signal()) - sig_uuid = get_uuid(spanel.objmodel.get_object_from_number(1)) - spanel.objview.select_objects([1]) - - # Create an image and run a 1_to_1 image compute action. - ipanel.add_object(create_sincos_image()) - ima_uuid = get_uuid(ipanel.objmodel.get_object_from_number(1)) - ipanel.objview.select_objects([1]) - ipanel.processor.run_feature(sipi.inverse) - - # The recorded image action must NOT embed the signal-panel selection. - entry = history[len(history)] - assert entry.kind == HistoryAction.KIND_COMPUTE - assert entry.panel_str == ipanel.PANEL_STR_ID - assert entry.state.selection.get("signal", []) == [] - assert entry.state.selection.get("image") == [ima_uuid] - - # Deleting the unrelated signal must keep the image action compatible. - history.toggle_record_mode(False) - spanel.objview.select_objects([1]) - spanel.remove_object(force=True) - assert sig_uuid not in spanel.objmodel.get_object_ids() - assert entry.is_current_state_compatible(win, restore_selection=False) is True - - -# --------------------------------------------------------------------------- -# 2) Recording, replay patterns & session replay -# --------------------------------------------------------------------------- - - -def test_history_recording_and_replay(monkeypatch): - """Recording, per-pattern replay, session replay, fit replay & capture.""" - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - panel.add_object(create_paracetamol_signal()) - src_uuid = get_uuid(panel.objmodel.get_object_from_number(1)) - - # --- scenario: compute_1_to_1 history matches ProcessingParameters --- - panel.objview.select_objects([1]) - panel.processor.run_feature(sips.derivative) - result_obj = panel.objmodel.get_object_from_number(2) - pp = extract_processing_parameters(result_obj) - assert pp is not None - assert pp.func_name == "derivative" - assert pp.source_uuid == src_uuid - entry = history[len(history)] - assert entry.kind == HistoryAction.KIND_COMPUTE - assert entry.func_name == "derivative" - assert entry.pattern == "1_to_1" - assert entry.state.selection.get(panel.PANEL_STR_ID) == [src_uuid] - - # --- scenario: recompute_processing does not add a history entry --- - n_before = len(history) - derived = panel.objmodel.get_object_from_number(2) - panel.objview.set_current_object(derived) - panel.recompute_processing() - assert len(history) == n_before - - # --- scenario: replay finds target by UUID after panel reorder --- - deriv_entry = history[len(history)] - panel.add_object(create_paracetamol_signal()) - assert get_uuid(panel.objmodel[src_uuid]) == src_uuid - n_before_replay = len(panel.objmodel) - deriv_entry.replay(win, restore_selection=True, edit=False) - assert len(panel.objmodel) == n_before_replay + 1 - new_obj = panel.objmodel.get_object_from_number(len(panel.objmodel)) - new_pp = extract_processing_parameters(new_obj) - assert new_pp is not None - assert new_pp.source_uuid == src_uuid - - # --- scenario: UI rename capture + replay --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - panel.add_object(create_paracetamol_signal()) - obj = panel.objmodel.get_object_from_number(1) - original_title = obj.title - new_title = "renamed-by-test" - panel.objview.set_current_object(obj) - panel.set_current_object_title(new_title) - assert obj.title == new_title - rename_entry = history[len(history)] - assert rename_entry.kind == HistoryAction.KIND_UI - assert rename_entry.target == "signalpanel" - assert rename_entry.method_name == "set_current_object_title" - assert rename_entry.kwargs.get("title") == new_title - panel.set_current_object_title("transient-title") - assert obj.title == "transient-title" - rename_entry.replay(win, restore_selection=False, edit=False) - assert obj.title == new_title and obj.title != original_title - assert isinstance(rename_entry.state, WorkspaceState) - - # --- scenario: add_metadata capture --- - obj_uuid = get_uuid(obj) - panel.objview.select_objects([1]) - param = AddMetadataParam([obj]) - param.metadata_key = "history_gate6" - param.value_pattern = "value_{index}" - param.conversion = "string" - panel.add_metadata(param) - entry = history[len(history)] - assert entry.kind == HistoryAction.KIND_UI - assert entry.target == "signalpanel" - assert entry.method_name == "add_metadata" - captured = entry.kwargs.get("param") - assert captured is not None and captured is not param - assert captured.metadata_key == param.metadata_key - assert captured.value_pattern == param.value_pattern - assert captured.conversion == param.conversion - assert entry.state.selection.get(panel.PANEL_STR_ID) == [obj_uuid] - - # --- scenario: add_metadata replay --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - panel.add_object(create_paracetamol_signal()) - obj = panel.objmodel.get_object_from_number(1) - panel.objview.select_objects([1]) - param = AddMetadataParam([obj]) - param.metadata_key = "replay_test_key" - param.value_pattern = "replay_value_{index}" - param.conversion = "string" - panel.add_metadata(param) - assert obj.metadata.get("replay_test_key") == "replay_value_1" - entry = history[len(history)] - del obj.metadata["replay_test_key"] - assert "replay_test_key" not in obj.metadata - entry.replay(win, restore_selection=False, edit=False) - assert obj.metadata.get("replay_test_key") == "replay_value_1" - - # --- scenario: ROI copy/paste capture + deterministic replay --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - src = create_paracetamol_signal() - src.roi = create_signal_roi([[26, 41]], indices=True) - panel.add_object(src) - dst = create_paracetamol_signal() - panel.add_object(dst) - src_uuid = get_uuid(src) - dst_uuid = get_uuid(dst) - panel.objview.set_current_item_id(src_uuid) - panel.copy_roi() - copy_entry = history[len(history)] - panel.objview.set_current_item_id(dst_uuid) - panel.paste_roi() - paste_entry = history[len(history)] - assert copy_entry.kind == HistoryAction.KIND_UI - assert copy_entry.target == "signalpanel" - assert copy_entry.method_name == "copy_roi" - assert "roi_data" in copy_entry.kwargs - assert copy_entry.state.selection.get(panel.PANEL_STR_ID) == [src_uuid] - assert paste_entry.kind == HistoryAction.KIND_UI - assert paste_entry.target == "signalpanel" - assert paste_entry.method_name == "paste_roi" - assert "roi_data" in paste_entry.kwargs - assert paste_entry.state.selection.get(panel.PANEL_STR_ID) == [dst_uuid] - # Deterministic replay: change source ROI then replay paste. - dst_obj = panel.objmodel.get_object_from_number(2) - assert dst_obj.roi is not None - src.roi = create_signal_roi([[100, 200]], indices=True) - dst_obj.roi = None - paste_entry.replay(win, restore_selection=False, edit=False) - assert dst_obj.roi is not None - assert dst_obj.roi.get_single_roi(0).coords.tolist() == [26, 41] - - # --- scenario: save_to_directory capture + replay --- - saved_paths: list[str] = [] - - def fake_save_to_file(_self, _obj, filename): - saved_paths.append(filename) - - monkeypatch.setattr( - BaseDataPanel, "_BaseDataPanel__save_to_file", fake_save_to_file - ) - with datalab_test_app_context(history=True) as win: - with helpers.WorkdirRestoringTempDir() as tmpdir: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - panel.add_object(create_paracetamol_signal()) - obj = panel.objmodel.get_object_from_number(1) - obj_uuid = get_uuid(obj) - panel.objview.select_objects([1]) - param = sigima.params.SaveToDirectoryParam.create( - directory=tmpdir, - basename="history_gate6_{index}", - extension=".csv", - overwrite=True, - ) - panel.save_to_directory(param) - entry = history[len(history)] - assert entry.kind == HistoryAction.KIND_UI - assert entry.target == "signalpanel" - assert entry.method_name == "save_to_directory" - captured = entry.kwargs.get("param") - assert captured is not None and captured is not param - assert captured.directory == param.directory - assert captured.basename == param.basename - assert captured.extension == param.extension - assert captured.overwrite == param.overwrite - assert entry.state.selection.get(panel.PANEL_STR_ID) == [obj_uuid] - assert saved_paths == [os.path.join(tmpdir, "history_gate6_1.csv")] - # Replay: must call save again with same parameters. - n_before = len(saved_paths) - entry.replay(win, restore_selection=False, edit=False) - assert len(saved_paths) == n_before + 1 - assert saved_paths[-1] == saved_paths[-2] - - # --- scenario: multiple_1_to_1 replay raises NotImplementedError --- - with datalab_test_app_context(history=True) as win: - action = HistoryAction( - title="dummy multiple_1_to_1", - kind=HistoryAction.KIND_COMPUTE, - panel_str="signal", - func_name="some_compound_op", - pattern="multiple_1_to_1", - state=WorkspaceState(), - ) - with pytest.raises(NotImplementedError): - action.replay(win, restore_selection=False, edit=False) - - # --- scenario: normal processing outside replay still adds objects --- - panel = win.signalpanel - panel.add_object(create_paracetamol_signal()) - panel.objview.select_objects([1]) - n_before = len(panel.objmodel) - panel.processor.run_feature(sips.derivative) - assert len(panel.objmodel) == n_before + 1 - - # --- scenario: 1_to_n extract_roi replay (persistent direct replay) --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - sig = create_paracetamol_signal() - sig.roi = sigima.objects.create_signal_roi([[26, 41], [125, 146]], indices=True) - panel.add_object(sig) - src_uuid = get_uuid(panel.objmodel.get_object_from_number(1)) - n_objects_before = len(panel.objmodel) - panel.objview.select_objects([1]) - panel.processor.run_feature("extract_roi", params=sig.roi.to_params(sig)) - n_added_first = len(panel.objmodel) - n_objects_before - assert n_added_first >= 1 - entry = history[len(history)] - assert entry.kind == HistoryAction.KIND_COMPUTE - assert entry.pattern == "1_to_n" - assert entry.func_name == "extract_roi" - assert entry.state.selection.get(panel.PANEL_STR_ID) == [src_uuid] - n_before_replay = len(panel.objmodel) - entry.replay(win, restore_selection=True, edit=False) - assert len(panel.objmodel) - n_before_replay == n_added_first - - # --- scenario: n_to_1 forces captured selection --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - panel.add_object(create_paracetamol_signal()) - panel.add_object(create_paracetamol_signal()) - panel.add_object(create_paracetamol_signal()) - panel.objview.select_objects([1, 2, 3]) - panel.processor.run_feature(sips.average) - avg_entry = history[len(history)] - assert avg_entry.pattern == "n_to_1" - panel.objview.select_objects([1]) - assert len(panel.objview.get_sel_object_uuids()) == 1 - n_before = len(panel.objmodel) - avg_entry.replay(win, restore_selection=False, edit=False) - assert len(panel.objmodel) == n_before + 1 - - # --- scenario: n_to_1 falls back when captured UUIDs are gone --- - win.reset_all() - panel.add_object(create_paracetamol_signal()) - panel.add_object(create_paracetamol_signal()) - panel.add_object(create_paracetamol_signal()) - panel.objview.select_objects([1, 2, 3]) - assert not avg_entry.state.is_current_state_compatible(win, False) - n_before = len(panel.objmodel) - avg_entry.replay(win, restore_selection=False, edit=False) - assert len(panel.objmodel) == n_before + 1 - - # --- scenario: n_to_1 passes recorded pairwise flag --- - with datalab_test_app_context(history=True) as win: - panel = win.signalpanel - captured: dict = {} - - def capture_compute_n_to_1(*_args, **kwargs): - captured.update(kwargs) - - monkeypatch.setattr(panel.processor, "compute_n_to_1", capture_compute_n_to_1) - action = HistoryAction( - title="average pairwise", - kind=HistoryAction.KIND_COMPUTE, - panel_str=panel.PANEL_STR_ID, - func_name="average", - pattern="n_to_1", - kwargs={"pairwise": True}, - state=WorkspaceState(), - ) - action.replay_compute(win, edit=False) - assert captured["pairwise"] is True - - # --- scenario: 2_to_1 with vanished obj2 raises ValueError --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - panel.add_object(create_paracetamol_signal()) - panel.add_object(create_paracetamol_signal()) - obj2 = panel.objmodel.get_object_from_number(2) - panel.objview.select_objects([1]) - panel.processor.run_feature(sips.difference, obj2) - diff_entry = history[len(history)] - assert diff_entry.pattern == "2_to_1" - panel.objview.set_current_object(obj2) - panel.remove_object(force=True) - with pytest.raises(ValueError): - diff_entry.replay(win, restore_selection=False, edit=False) - - # --- scenario: 2_to_1 replay translates obj2 UUIDs and passes pairwise --- - with datalab_test_app_context(history=True) as win: - panel = win.signalpanel - panel.add_object(create_paracetamol_signal()) - obj2 = panel.objmodel.get_object_from_number(1) - obj2_uuid = get_uuid(obj2) - captured = {} - - def capture_compute_2_to_1(obj2_arg, *_args, **kwargs): - captured["obj2"] = obj2_arg - captured.update(kwargs) - - monkeypatch.setattr(panel.processor, "compute_2_to_1", capture_compute_2_to_1) - action = HistoryAction( - title="difference pairwise", - kind=HistoryAction.KIND_COMPUTE, - panel_str=panel.PANEL_STR_ID, - func_name="difference", - pattern="2_to_1", - kwargs={"obj2_uuids": ["recorded-obj2"], "pairwise": True}, - state=WorkspaceState(), - ) - action.replay_compute( - win, - edit=False, - uuid_remap={panel.PANEL_STR_ID: {"recorded-obj2": obj2_uuid}}, - ) - assert captured["obj2"] is obj2 - assert captured["pairwise"] is True - - # scenario: replay_restore_actions(replay=True) on 1_to_1 does NOT add output - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - panel.add_object(create_paracetamol_signal()) - panel.objview.select_objects([1]) - panel.processor.run_feature(sips.derivative) - deriv_entry = history[len(history)] - _select_tree_item_for(history, deriv_entry) - n_signal_before = len(panel.objmodel) - n_history_before = len(history) - history.replay_restore_actions(replay=True, restore_selection=True) - assert len(panel.objmodel) == n_signal_before - assert len(history) == n_history_before - - # --- scenario: reset_all starts a new session and preserves history --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - panel = win.signalpanel - win.reset_all() - assert len(history) == 0 - assert _session_action_counts(history) == [] - history.toggle_record_mode(True) - panel.new_object(param=sigima.objects.GaussParam(), edit=False) - assert len(history) == 1 - assert _session_action_counts(history) == [1] - first_title = history[1].title - history.toggle_record_mode(False) - win.reset_all() - assert len(history) == 1 - assert _session_action_counts(history) == [1, 0] - assert history[1].title == first_title - history.toggle_record_mode(True) - panel.new_object(param=sigima.objects.LorentzParam(), edit=False) - assert len(history) == 2 - assert _session_action_counts(history) == [1, 1] - assert history[1].title == first_title - assert history[2].title == _("New signal") - - # --- scenario: full session replay on existing data --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - panel.add_object(create_paracetamol_signal()) - panel.add_object(create_paracetamol_signal()) - panel.add_object(create_paracetamol_signal()) - assert len(panel.objmodel) == 3 - panel.objview.select_objects([1, 2, 3]) - panel.processor.run_feature(sips.average) - assert len(panel.objmodel) == 4 - session = history.history_sessions[-1] - n_before = len(panel.objmodel) - session.replay(win, restore_selection=False, edit=False) - assert len(panel.objmodel) == n_before + 1 - - # --- scenario: chained compute session replay (output queue remap) --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - panel.add_object(create_paracetamol_signal()) - panel.add_object(create_paracetamol_signal()) - panel.objview.select_objects([1]) - panel.processor.run_feature(sips.derivative) - panel.objview.select_objects([2]) - panel.processor.run_feature(sips.derivative) - panel.objview.select_objects([3, 4]) - panel.processor.run_feature(sips.average) - assert len(panel.objmodel) == 5 - session = history.history_sessions[-1] - n_before = len(panel.objmodel) - session.replay(win, restore_selection=False, edit=False) - assert len(panel.objmodel) == n_before + 3 - - # --- scenario: direct HistoryAction.replay() does NOT record new entries --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - panel = win.signalpanel - history.toggle_record_mode(True) - panel.new_object(param=NewSignalParam(), edit=False) - panel.objview.select_objects([1]) - panel.processor.run_feature(sips.derivative) - assert len(panel.objmodel) == 2 - session = history.history_sessions[-1] - compute_action = [ - a for a in session.actions if a.kind == HistoryAction.KIND_COMPUTE - ][0] - n_before = sum(len(s.actions) for s in history.history_sessions) - panel.objview.select_objects([1]) - compute_action.replay(win, restore_selection=True, edit=False) - assert sum(len(s.actions) for s in history.history_sessions) == n_before - - # --- scenario: direct HistorySession.replay() does NOT record entries --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - panel = win.signalpanel - history.toggle_record_mode(True) - panel.add_object(create_paracetamol_signal()) - panel.add_object(create_paracetamol_signal()) - panel.objview.select_objects([1, 2]) - panel.processor.run_feature(sips.average) - assert len(panel.objmodel) == 3 - session = history.history_sessions[-1] - n_before = sum(len(s.actions) for s in history.history_sessions) - panel.objview.select_objects([1, 2]) - session.replay(win, restore_selection=False, edit=False) - assert sum(len(s.actions) for s in history.history_sessions) == n_before - - # --- scenario: panel API session replay skips UI-creation, no output --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - panel.new_object(param=NewSignalParam(), edit=False) - panel.objview.select_objects([1]) - panel.processor.run_feature(sips.derivative) - session = history.history_sessions[-1] - _select_tree_session(history, session) - n_signal_before = len(panel.objmodel) - n_history_before = len(history) - history.replay_restore_actions(replay=True, restore_selection=True) - assert len(panel.objmodel) == n_signal_before - assert len(history) == n_history_before - - # --- scenario: replay whole session when no tree selection --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - panel.add_object(create_paracetamol_signal()) - panel.objview.select_objects([1]) - panel.processor.run_feature(sips.derivative) - history.tree.clearSelection() - n_before = len(panel.objmodel) - n_history_before = len(history) - history.replay_restore_actions(replay=True, restore_selection=False) - assert len(panel.objmodel) == n_before - assert len(history) == n_history_before - - # --- scenario: 2_to_1 with primary = #1, obj2 = #2 --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - panel.add_object(create_paracetamol_signal()) - panel.add_object(create_paracetamol_signal()) - obj2_for_diff = panel.objmodel.get_object_from_number(2) - panel.objview.select_objects([1]) - panel.processor.run_feature(sips.difference, obj2_for_diff) - assert len(panel.objmodel) == 3 - original_title = panel.objmodel.get_object_from_number(3).title - assert "s001" in original_title and "s002" in original_title - assert original_title.index("s001") < original_title.index("s002") - diff_entry = history[len(history)] - _select_tree_item_for(history, diff_entry) - n_before = len(panel.objmodel) - history.replay_restore_actions(replay=True, restore_selection=True) - assert len(panel.objmodel) == n_before - - # --- scenario: duplicate_object registers duplicated outputs --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - panel = win.signalpanel - history.toggle_record_mode(True) - panel.add_object(create_paracetamol_signal()) - panel.objview.select_objects([1]) - panel.duplicate_object() - session = history.history_sessions[-1] - dup_action = next( - action - for action in session.actions - if action.method_name == "duplicate_object" - ) - assert dup_action.output_uuids - first_output = dup_action.output_uuids[0] - assert history.output_to_action[first_output] == dup_action.uuid - - # --- interactive curve-fit record + .dlhist round-trip + replay --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - panel = win.signalpanel - - # --- scenario: record a polynomial interactive fit as a UI action --- - history.toggle_record_mode(True) - panel.add_object(create_paracetamol_signal()) - src = panel.objmodel.get_object_from_number(1) - src_uuid = get_uuid(src) - panel.objview.select_objects([1]) - - degree = 3 - coeffs = np.polyfit(src.x, src.y, degree) # highest-first == polyval order - fit_values = [float(c) for c in coeffs] - expected_y = np.polyval(coeffs, src.x) - name = _("Polynomial fit") - - result = sigima.objects.create_signal(f"{name}({src.title})", src.x, expected_y) - action = history.add_ui_entry( - name, - target="signalprocessor", - method_name="recompute_fit", - save_state=True, - fit_type="polynomial", - fit_values=fit_values, - fit_name=name, - source_uuid=src_uuid, - ) - assert action is not None - with history.capture_outputs(action): - panel.add_object(result) - assert action.output_uuids == [get_uuid(result)] - assert action.target == "signalprocessor" - assert action.panel_str == panel.PANEL_STR_ID - - # --- scenario: .dlhist round-trip preserves uuid + fit kwargs --- - ser_session = HistorySession(number=1) - ser_session.actions.append(action) - with tempfile.TemporaryDirectory() as tmpdir: - path = os.path.join(tmpdir, "fit.dlhist") - with NativeH5Writer(path) as writer: - writer.write_object_list([ser_session], "history_session") - with NativeH5Reader(path) as reader: - restored_sessions = reader.read_object_list( - "history_session", HistorySession - ) - restored = restored_sessions[0].actions[0] - assert restored.uuid == action.uuid - assert restored.kind == HistoryAction.KIND_UI - assert restored.target == "signalprocessor" - assert restored.method_name == "recompute_fit" - assert restored.kwargs.get("fit_type") == "polynomial" - assert restored.kwargs.get("source_uuid") == src_uuid - assert restored.kwargs.get("fit_values") == pytest.approx(fit_values) - - # --- scenario: deterministic replay reconstructs the fit curve --- - n_before = len(panel.objmodel) - restored.replay(win, restore_selection=True, edit=False) - assert len(panel.objmodel) == n_before + 1 - new_obj = panel.objmodel.get_object_from_number(len(panel.objmodel)) - assert np.allclose(new_obj.x, src.x) - assert np.allclose(new_obj.y, expected_y) - - # --- capture_outputs funnel: drop failed producing computes --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - - panel.add_object(create_paracetamol_signal()) - panel.objview.select_objects([1]) - - # --- scenario: producing compute with no output is dropped --- - action = history.add_compute_entry( - "Failing op", - panel_str="signal", - func_name="gaussian_filter", - pattern="1_to_1", - save_state=True, - ) - assert action is not None - len_before = len(history) - with history.capture_outputs(action): - pass # simulate a failed compute: no object created - assert action not in list(history) - assert len(history) == len_before - 1 - assert action.uuid not in history.action_output_uuids - - # --- control: a UI action producing no object is preserved --- - ui_action = history.add_ui_entry( - "Some UI", - target="signalpanel", - method_name="copy_metadata", - save_state=False, - ) - assert ui_action is not None - ui_len_before = len(history) - with history.capture_outputs(ui_action): - pass - assert ui_action in list(history) - assert len(history) == ui_len_before - - # --- control: a 1_to_0 analysis compute producing no object is kept --- - analysis_action = history.add_compute_entry( - "Analysis op", - panel_str="signal", - func_name="stats", - pattern="1_to_0", - save_state=True, - ) - assert analysis_action is not None - analysis_len_before = len(history) - with history.capture_outputs(analysis_action): - pass - assert analysis_action in list(history) - assert len(history) == analysis_len_before - - -# --------------------------------------------------------------------------- -# 3) Duplication -# --------------------------------------------------------------------------- - - -def test_history_duplication(): - """Action/session duplication, UUID remap, ordering + creation-root cases.""" - # --- scenario: duplicating an action creates an independent copy --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - panel.add_object(create_paracetamol_signal()) - param = sigima.params.MovingAverageParam() - param.n = 3 - panel.objview.select_objects([1]) - panel.processor.run_feature(sips.moving_average, param) - original = history[len(history)] - _select_tree_item_for(history, original) - n_before = len(panel.objmodel) - history.duplicate_selected_entries() - sessions = history.history_sessions - duplicate_session = sessions[-1] - # Operation-rooted chain (Cas B): a synthetic creation head is - # prepended, so the compute duplicate is no longer at index 0. - assert duplicate_session.actions[0].method_name == "new_object" - duplicate = next( - a for a in duplicate_session.actions if a.kind == HistoryAction.KIND_COMPUTE - ) - assert duplicate_session.title.endswith(_("Copy")) - assert duplicate is not original - assert duplicate.uuid != original.uuid - assert duplicate.kwargs["param"] is not original.kwargs["param"] - duplicate.kwargs["param"].n = 7 - assert original.kwargs["param"].n == 3 - assert duplicate.kwargs["param"].n == 7 - assert len(panel.objmodel) > n_before - - # --- scenario: duplicating a session copies all actions independently --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - panel.add_object(create_paracetamol_signal()) - param = sigima.params.MovingAverageParam() - param.n = 3 - panel.objview.select_objects([1]) - panel.processor.run_feature(sips.moving_average, param) - original_session = history.history_sessions[-1] - _select_tree_session(history, original_session) - history.duplicate_selected_entries() - sessions = history.history_sessions - duplicate_session = sessions[-1] - assert duplicate_session is not original_session - # One synthetic creation head is prepended (Cas B). - assert len(duplicate_session.actions) == len(original_session.actions) + 1 - assert duplicate_session.title.endswith(_("Copy")) - orig_a = original_session.actions[-1] - dup_a = duplicate_session.actions[-1] - assert dup_a is not orig_a - assert dup_a.kwargs["param"] is not orig_a.kwargs["param"] - - # --- scenario: duplicate clones data AND remaps UUIDs --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - panel.add_object(create_paracetamol_signal()) - panel.objview.select_objects([1]) - panel.processor.run_feature(sips.derivative) - original_session = history.history_sessions[-1] - _select_tree_session(history, original_session) - n_obj_before = len(panel.objmodel) - n_sessions_before = len(history.history_sessions) - history.duplicate_selected_entries() - sessions = history.history_sessions - assert len(sessions) == n_sessions_before + 1 - dup_session = sessions[-1] - assert dup_session is not original_session - assert dup_session.title.endswith(_("Copy")) - assert len(panel.objmodel) > n_obj_before - # The duplicate has an extra leading synthetic head (Cas B); compare - # only the compute actions against the originals. - dup_compute = [ - a for a in dup_session.actions if a.kind == HistoryAction.KIND_COMPUTE - ] - for orig_action, dup_action in zip(original_session.actions, dup_compute): - for pstr in orig_action.state.selection: - orig_uuids = set(orig_action.state.selection.get(pstr, [])) - dup_uuids = set(dup_action.state.selection.get(pstr, [])) - if orig_uuids and dup_uuids: - assert orig_uuids.isdisjoint(dup_uuids) - - # --- scenario: replay of duplicated session does NOT add output --- - _select_tree_session(history, dup_session) - n_before = len(panel.objmodel) - n_history_before = len(history) - history.replay_restore_actions(replay=True, restore_selection=False) - assert len(panel.objmodel) == n_before - assert len(history) == n_history_before - - # --- scenario: duplicated session preserves topological object order --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - _build_cascade_chain(panel, history) - # Extra step so the moving_average output is captured in metadata. - panel.objview.select_objects([4]) - panel.processor.run_feature(sips.derivative) - original_ids = panel.objmodel.get_object_ids() - original_titles = [panel.objmodel[uid].title for uid in original_ids] - assert len(original_titles) >= 3 - sessions = history.history_sessions - _select_tree_session(history, sessions[0]) - history.duplicate_selected_entries() - groups = panel.objmodel.get_groups() - assert len(groups) >= 2 - dup_group_id = get_uuid(groups[-1]) - dup_ids = [ - uid - for uid in panel.objmodel.get_object_ids() - if panel.objmodel.get_object_group_id(panel.objmodel[uid]) == dup_group_id - ] - dup_titles = [panel.objmodel[uid].title for uid in dup_ids] - - def _suffix(title: str) -> str: - parts = title.split("|", 1) - return parts[1].strip() if len(parts) > 1 else title.strip() - - orig_suffixes = [_suffix(t) for t in original_titles] - dup_suffixes = [_suffix(t) for t in dup_titles] - clonable = orig_suffixes[: len(dup_suffixes)] - assert clonable == dup_suffixes - - # --- scenario: cas A — creation-rooted chain copies creation (no head) --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - win.add_object(create_paracetamol_signal()) # records new_object creation - panel.objview.select_objects([1]) - panel.processor.run_feature(sips.derivative) - original_session = history.history_sessions[-1] - assert original_session.actions[0].method_name == "new_object" - _select_tree_session(history, original_session) - n_obj_before = len(panel.objmodel) - history.duplicate_selected_entries() - dup_session = history.history_sessions[-1] - assert dup_session is not original_session - # Cas A: same number of actions (creation duplicated, NO synthetic head). - assert len(dup_session.actions) == len(original_session.actions) - dup_root = dup_session.actions[0] - orig_root = original_session.actions[0] - assert dup_root.method_name == "new_object" - assert dup_root is not orig_root - assert dup_root.uuid != orig_root.uuid - # Objects were cloned. - assert len(panel.objmodel) > n_obj_before - # UUID remap: duplicated actions share no object uuid with originals. - for orig_a, dup_a in zip(original_session.actions, dup_session.actions): - for pstr in orig_a.state.selection: - o = set(orig_a.state.selection.get(pstr, [])) - d = set(dup_a.state.selection.get(pstr, [])) - if o and d: - assert o.isdisjoint(d) - - # --- scenario: cas B — operation-rooted chain synthesizes head --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - panel.add_object(create_paracetamol_signal()) # NO creation recorded - panel.objview.select_objects([1]) - panel.processor.run_feature(sips.derivative) - original_session = history.history_sessions[-1] - # Operation-rooted: no creation action at the head. - assert original_session.actions[0].method_name != "new_object" - _select_tree_session(history, original_session) - history.duplicate_selected_entries() - dup_session = history.history_sessions[-1] - assert dup_session is not original_session - # Cas B: exactly one synthetic head prepended. - assert len(dup_session.actions) == len(original_session.actions) + 1 - head = dup_session.actions[0] - assert head.kind == HistoryAction.KIND_UI - assert head.method_name == "new_object" - assert head.kwargs == {} - assert head.state.selection == {} # empty state (always compatible) - assert len(head.output_uuids) == 1 - clone_uuid = head.output_uuids[0] - # Head output registered in the panel mappings. - assert history.action_output_uuids.get(head.uuid) == [clone_uuid] - assert history.output_to_action.get(clone_uuid) == head.uuid - # Clone materialized in the panel. - assert clone_uuid in panel.objmodel.get_object_ids() - # Head + ops re-link into a SINGLE chain on the duplicate. - dup_chains = build_session_chains(history, dup_session) - assert len(dup_chains) == 1 - assert dup_chains[0].root is head - assert sum(len(c.actions) for c in dup_chains) == len(dup_session.actions) - # Replay of the duplicate adds no new object (creations skipped under - # suppression). - _select_tree_session(history, dup_session) - n_obj = len(panel.objmodel) - n_hist = len(history) - history.replay_restore_actions(replay=True, restore_selection=False) - assert len(panel.objmodel) == n_obj - assert len(history) == n_hist - - -# --------------------------------------------------------------------------- -# 4) Editing: processing-tab edits, cascade recompute & invariants -# --------------------------------------------------------------------------- - - -def test_history_editing_and_cascade(): - """Processing-tab edit propagation, step-by-step, cascade & invariants.""" - # --- scenario: edit updates current session action and refreshes html --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - history.toggle_edit_mode(True) - panel = win.signalpanel - panel.add_object(create_paracetamol_signal()) - param = sigima.params.GaussianParam.create(sigma=1.5) - panel.objview.select_objects([1]) - panel.processor.run_feature(sips.gaussian_filter, param) - result_obj = panel.objmodel.get_object_from_number(2) - action = history[len(history)] - assert action.func_name == "gaussian_filter" - assert action.kwargs["param"].sigma == 1.5 - html_before = action.description_html - panel.objview.select_objects([2]) - assert panel.objprop.setup_processing_tab(result_obj, reset_params=False) - editor = panel.objprop.processing_param_editor - assert editor is not None - editor.dataset.sigma = 3.5 - report = panel.objprop.apply_processing_parameters( - result_obj, interactive=False - ) - assert report.success - assert action.kwargs["param"].sigma == 3.5 - html_after = action.description_html - assert html_before != html_after - assert "3.5" in html_after - win.historypanel.refresh_action(action) - editor.dataset.sigma = 7.0 - assert action.kwargs["param"].sigma == 3.5 - - # --- scenario: edit does NOT touch a past session --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - history.toggle_edit_mode(True) - panel = win.signalpanel - panel.add_object(create_paracetamol_signal()) - panel.objview.select_objects([1]) - panel.processor.run_feature( - sips.gaussian_filter, sigima.params.GaussianParam.create(sigma=1.0) - ) - past_action = history[len(history)] - assert past_action.kwargs["param"].sigma == 1.0 - win.reset_all() - panel.add_object(create_paracetamol_signal()) - panel.objview.select_objects([1]) - panel.processor.run_feature( - sips.gaussian_filter, sigima.params.GaussianParam.create(sigma=2.0) - ) - new_obj = panel.objmodel.get_object_from_number(2) - new_action = history[len(history)] - assert new_action is not past_action - found = history.find_action_for_output(get_uuid(new_obj), "gaussian_filter") - assert found is new_action and found is not past_action - panel.objview.select_objects([2]) - assert panel.objprop.setup_processing_tab(new_obj, reset_params=False) - editor = panel.objprop.processing_param_editor - assert editor is not None - editor.dataset.sigma = 4.0 - report = panel.objprop.apply_processing_parameters(new_obj, interactive=False) - assert report.success - assert new_action.kwargs["param"].sigma == 4.0 - assert past_action.kwargs["param"].sigma == 1.0 - - # --- scenario: restore selection only (replay=False) --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - panel.add_object(create_paracetamol_signal()) - src_uuid = get_uuid(panel.objmodel.get_object_from_number(1)) - panel.objview.select_objects([1]) - panel.processor.run_feature(sips.derivative) - deriv_entry = history[len(history)] - derived = panel.objmodel.get_object_from_number(2) - panel.objview.set_current_object(derived) - derived_uuid = get_uuid(derived) - assert panel.objview.get_sel_object_uuids() == [derived_uuid] - _select_tree_item_for(history, deriv_entry) - n_before = len(panel.objmodel) - history.replay_restore_actions(replay=False, restore_selection=True) - assert len(panel.objmodel) == n_before - assert panel.objview.get_sel_object_uuids() == [src_uuid] - - # --- scenario: step-by-step launch commits edits immediately --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - panel.add_object(create_paracetamol_signal()) - panel.objview.select_objects([1]) - panel.processor.run_feature( - sips.normalize, sigima.params.NormalizeParam.create(method="maximum") - ) - norm_entry = history[len(history)] - assert norm_entry.func_name == "normalize" - previous_edit_mode = history.edit_mode - _select_tree_item_for(history, norm_entry) - # Step-by-step launch: parameter dialogs auto-accept in unattended mode. - history.replay_step_by_step() - assert history.edit_mode is previous_edit_mode - assert history.has_any_pending_edits() is False - - # --- scenario: downstream detection --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - action_a, action_b, action_c, _ob, _oc = _build_cascade_chain(panel, history) - downstream = history.get_downstream_actions(action_a) - assert downstream == [action_b, action_c] - assert not history.get_downstream_actions(action_c) - assert history.get_downstream_actions(action_b) == [action_c] - - # --- scenario: cascade recompute updates downstream outputs in place --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - history.toggle_edit_mode(True) - panel = win.signalpanel - action_a, action_b, action_c, output_b, output_c = _build_cascade_chain( - panel, history - ) - uuid_b = get_uuid(output_b) - uuid_c = get_uuid(output_c) - data_b_before = output_b.xydata.copy() - data_c_before = output_c.xydata.copy() - n_objects_before = len(panel.objmodel) - result_obj_a = panel.objmodel.get_object_from_number(2) - panel.objview.select_objects([2]) - assert panel.objprop.setup_processing_tab(result_obj_a, reset_params=False) - editor = panel.objprop.processing_param_editor - assert editor is not None - editor.dataset.sigma = 6.0 - report = panel.objprop.apply_processing_parameters( - result_obj_a, interactive=False - ) - assert report.success - assert action_a.kwargs["param"].sigma == 6.0 - assert len(panel.objmodel) == n_objects_before - assert get_uuid(panel.objmodel[uuid_b]) == uuid_b - assert get_uuid(panel.objmodel[uuid_c]) == uuid_c - assert not np.array_equal(panel.objmodel[uuid_b].xydata, data_b_before) - assert not np.array_equal(panel.objmodel[uuid_c].xydata, data_c_before) - for a in (action_a, action_b, action_c): - assert a.is_stale is False - - # --- scenario: play on stale action triggers cascade --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - action_a, action_b, _ac, output_b, _oc = _build_cascade_chain(panel, history) - uuid_b = get_uuid(output_b) - output_b.xydata = output_b.xydata * 0.0 - tampered = output_b.xydata.copy() - action_a.is_stale = True - _select_tree_item_for(history, action_a) - history.replay_restore_actions(replay=True, restore_selection=False) - assert action_a.is_stale is False - assert action_b.is_stale is False - assert not np.array_equal(panel.objmodel[uuid_b].xydata, tampered) - - # --- scenario: cascade in a duplicated session that is NOT [-1] --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - history.toggle_edit_mode(True) - panel = win.signalpanel - action_a, _ab, _ac, _ob, output_c = _build_cascade_chain(panel, history) - uuid_c_orig = get_uuid(output_c) - data_c_orig = output_c.xydata.copy() - panel.objview.select_objects([4]) - panel.processor.run_feature(sips.derivative) - sessions = history.history_sessions - s1 = sessions[0] - history.create_new_session() - panel.add_object(create_paracetamol_signal()) - panel.objview.select_objects([6]) - panel.processor.run_feature(sips.derivative) - assert len(sessions) == 2 - _select_tree_session(history, s1) - history.duplicate_selected_entries() - assert len(sessions) == 3 - dup_session = sessions[1] - assert sessions[-1] is not dup_session - dup_action_a = next( - a for a in dup_session.actions if a.func_name == action_a.func_name - ) - dup_action_c = next( - a for a in dup_session.actions if a.func_name == "moving_average" - ) - dup_output_c_uuid = history.action_output_uuid(dup_action_c) - assert dup_output_c_uuid is not None - data_dup_c_before = panel.objmodel[dup_output_c_uuid].xydata.copy() - dup_result_obj_a_uuid = history.action_output_uuid(dup_action_a) - assert dup_result_obj_a_uuid is not None - dup_result_obj_a = panel.objmodel[dup_result_obj_a_uuid] - panel.objview.select_objects([dup_result_obj_a_uuid]) - assert panel.objprop.setup_processing_tab(dup_result_obj_a, reset_params=False) - editor = panel.objprop.processing_param_editor - assert editor is not None - editor.dataset.sigma = 10.0 - report = panel.objprop.apply_processing_parameters( - dup_result_obj_a, interactive=False - ) - assert report.success - assert not np.array_equal( - panel.objmodel[dup_output_c_uuid].xydata, data_dup_c_before - ) - assert np.array_equal(panel.objmodel[uuid_c_orig].xydata, data_c_orig) - - # --- creation-action editing (params, cascade, restore) --- - from datalab.gui.panel.history import recompute as hrec - - # --- scenario: editing a created Gauss signal cascades to downstream --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - history.toggle_edit_mode(True) - panel = win.signalpanel - gparam = sigima.objects.create_signal_parameters( - sigima.objects.SignalTypes.GAUSS, size=200, sigma=20.0 - ) - signal = panel.new_object(gparam, edit=False) - assert signal is not None - creation = history[len(history)] - assert creation.kind == HistoryAction.KIND_UI - assert creation.method_name == "new_object" - creation_uuid = get_uuid(signal) - assert history.action_output_uuid(creation) == creation_uuid - - panel.objview.select_objects([1]) - panel.processor.run_feature( - sips.gaussian_filter, sigima.params.GaussianParam.create(sigma=1.5) - ) - filter_action = history[len(history)] - output_filter = panel.objmodel.get_object_from_number(2) - uuid_filter = get_uuid(output_filter) - - assert history.get_downstream_actions(creation) == [filter_action] - - creation_data_before = signal.xydata.copy() - filter_data_before = output_filter.xydata.copy() - desc_before = creation.description - - creation.snapshot_kwargs() - creation.kwargs["param"].sigma = 60.0 - hrec.recompute_action_in_place(history, creation) - hrec.recompute_cascade(history, creation, descendants=[filter_action]) - - assert creation.has_pending_edits - assert "60" in creation.description - assert creation.description != desc_before - assert not np.array_equal(signal.xydata, creation_data_before) - assert not np.array_equal( - panel.objmodel[uuid_filter].xydata, filter_data_before - ) - - creation.restore_kwargs() - hrec.recompute_action_in_place(history, creation) - hrec.recompute_cascade(history, creation, descendants=[filter_action]) - assert not creation.has_pending_edits - assert creation.kwargs["param"].sigma == 20.0 - assert np.allclose(signal.xydata, creation_data_before) - - # --- scenario: edited snapshot survives HDF5 round-trip --- - gparam = sigima.objects.create_signal_parameters( - sigima.objects.SignalTypes.GAUSS, size=64, sigma=20.0 - ) - action = HistoryAction( - title="New signal", - kind=HistoryAction.KIND_UI, - target="signalpanel", - method_name="new_object", - kwargs={"param": gparam}, - state=WorkspaceState(), - ) - action.snapshot_kwargs() - action.kwargs["param"].sigma = 50.0 - session = HistorySession(number=1) - session.add_action(action) - with tempfile.TemporaryDirectory() as tmpdir: - path = os.path.join(tmpdir, "creation_roundtrip.dlhist") - with NativeH5Writer(path) as writer: - writer.write_object_list([session], "history_session") - with NativeH5Reader(path) as reader: - restored_sessions = reader.read_object_list( - "history_session", HistorySession - ) - restored_action = restored_sessions[0].actions[0] - assert restored_action.has_pending_edits - assert restored_action.kwargs["param"].sigma == 50.0 - - # --- cascade-recompute characterization invariants (pre-P3 slimming) --- - # --- scenario: cascade recompute call-count is bounded (no infinite loop) --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - history.toggle_edit_mode(True) - panel = win.signalpanel - action_a, action_b, action_c, output_b, output_c = _build_cascade_chain( - panel, history - ) - output_a = panel.objmodel.get_object_from_number(2) - src_obj = panel.objmodel.get_object_from_number(1) - src_data_before = src_obj.xydata.copy() - number_b = panel.objmodel.get_number(output_b) - number_c = panel.objmodel.get_number(output_c) - - # Spy on the single shared signal processor recompute entry point. - calls = {"n": 0} - original_recompute = panel.processor.recompute_1_to_1 - - def _counting_recompute(*args, **kwargs): - calls["n"] += 1 - return original_recompute(*args, **kwargs) - - panel.processor.recompute_1_to_1 = _counting_recompute - try: - panel.objview.select_objects([2]) - assert panel.objprop.setup_processing_tab(output_a, reset_params=False) - editor = panel.objprop.processing_param_editor - assert editor is not None - editor.dataset.sigma = 7.0 - report = panel.objprop.apply_processing_parameters( - output_a, interactive=False - ) - assert report.success - finally: - panel.processor.recompute_1_to_1 = original_recompute - - # Editing the root re-runs: the root itself (via apply) + the two - # downstream 1-to-1 actions (via cascade). Exactly one call per - # affected action -- a bound that fails if a replay loop reappears. - assert calls["n"] == 3 # root apply + 2 downstream cascade recomputes - - # Identity invariants: outputs keep their UUID *and* their __number. - assert get_uuid(panel.objmodel[get_uuid(output_b)]) == get_uuid(output_b) - assert panel.objmodel.get_number(panel.objmodel[get_uuid(output_b)]) == number_b - assert panel.objmodel.get_number(panel.objmodel[get_uuid(output_c)]) == number_c - - # Source object is never mutated by a downstream edit. - assert np.array_equal(src_obj.xydata, src_data_before) - - # --- scenario: cascade recompute preserves output metadata --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - history.toggle_edit_mode(True) - panel = win.signalpanel - action_a, _action_b, _action_c, _output_b, output_c = _build_cascade_chain( - panel, history - ) - uuid_c = get_uuid(output_c) - # Add a user metadata sentinel on the deepest output. - panel.objmodel[uuid_c].metadata["sentinel_p3a"] = 123 - output_a = panel.objmodel.get_object_from_number(2) - panel.objview.select_objects([2]) - assert panel.objprop.setup_processing_tab(output_a, reset_params=False) - editor = panel.objprop.processing_param_editor - assert editor is not None - editor.dataset.sigma = 9.0 - report = panel.objprop.apply_processing_parameters(output_a, interactive=False) - assert report.success - # P3b: the cascade now routes through the shared pre-history primitive - # (``apply_recomputed_object_in_place``), which PRESERVES the object's - # metadata instead of clearing it. The user sentinel survives. - assert panel.objmodel[uuid_c].metadata.get("sentinel_p3a") == 123 - - -# --------------------------------------------------------------------------- -# 5) Navigation, stepping & processing chains -# --------------------------------------------------------------------------- - - -def test_history_navigation_and_chains(monkeypatch): - """Stepping/selection sync, chain reconnect/grouping/split & sessions.""" - # --- scenario: step_next walks forward through current session --- - with datalab_test_app_context(history=True) as win: - _panel, history = _record_three_action_session(win) - sessions = history.history_sessions - actions = sessions[-1].actions - assert len(actions) >= 2 - history.tree.clearSelection() - for action in actions: - history.step_next() - current = history.tree.currentItem() - assert current is not None - assert current.data(0, QC.Qt.UserRole) == action.uuid - # End -> no-op. - last_uuid = history.tree.currentItem().data(0, QC.Qt.UserRole) - history.step_next() - assert history.tree.currentItem().data(0, QC.Qt.UserRole) == last_uuid - - # --- scenario: step_prev walks backward through current session --- - _select_tree_item_for(history, actions[-1]) - for expected in reversed(actions[:-1]): - history.step_prev() - current = history.tree.currentItem() - assert current.data(0, QC.Qt.UserRole) == expected.uuid - first_uuid = history.tree.currentItem().data(0, QC.Qt.UserRole) - history.step_prev() - assert history.tree.currentItem().data(0, QC.Qt.UserRole) == first_uuid - - # --- scenario: step button enabled state reflects position --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - prev_btn = history.step_prev_action - next_btn = history.step_next_action - history.update_actions_state() - assert not prev_btn.isEnabled() - assert not next_btn.isEnabled() - _panel, history = _record_three_action_session(win) - sessions = history.history_sessions - actions = sessions[-1].actions - prev_btn = history.step_prev_action - next_btn = history.step_next_action - _select_tree_item_for(history, actions[0]) - assert not prev_btn.isEnabled() - assert next_btn.isEnabled() - if len(actions) >= 3: - _select_tree_item_for(history, actions[1]) - assert prev_btn.isEnabled() - assert next_btn.isEnabled() - _select_tree_item_for(history, actions[-1]) - assert prev_btn.isEnabled() - assert not next_btn.isEnabled() - - # --- scenario: selecting a compute action selects its output --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - panel.add_object(create_paracetamol_signal()) - src_uuid = get_uuid(panel.objmodel.get_object_from_number(1)) - panel.objview.select_objects([1]) - panel.processor.run_feature( - sips.normalize, sigima.params.NormalizeParam.create(method="maximum") - ) - out_uuid = get_uuid(panel.objmodel.get_object_from_number(2)) - norm_entry = history[len(history)] - assert norm_entry.func_name == "normalize" - assert src_uuid in norm_entry.state.selection.get("signal", []) - panel.objview.select_objects([src_uuid]) - _select_tree_item_for(history, norm_entry) - assert panel.objview.get_sel_object_uuids() == [out_uuid] - - # --- scenario: deleted output -> selection falls back to input --- - panel.objview.select_objects([2]) - panel.remove_object(force=True) - assert len(panel.objmodel) == 1 - panel.objview.select_groups([1]) - _select_tree_item_for(history, norm_entry) - assert panel.objview.get_sel_object_uuids() == [src_uuid] - - # --- scenario: deleting intermediate result rewires downstream to source --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - panel.add_object(create_paracetamol_signal()) - src_uuid = get_uuid(panel.objmodel.get_object_from_number(1)) - - panel.objview.select_objects([1]) - panel.processor.run_feature( - sips.gaussian_filter, sigima.params.GaussianParam.create(sigma=1.5) - ) - s002_uuid = get_uuid(panel.objmodel.get_object_from_number(2)) - action_gaussian = history[len(history)] - assert action_gaussian.func_name == "gaussian_filter" - - panel.objview.select_objects([2]) - panel.processor.run_feature(sips.derivative) - action_deriv = history[len(history)] - assert action_deriv.func_name == "derivative" - assert s002_uuid in action_deriv.state.selection.get("signal", []) - - panel.objview.select_objects([2]) - panel.remove_object(force=True) - assert len(panel.objmodel) == 2 - - reconnected_uuids = action_deriv.state.selection.get("signal", []) - assert s002_uuid not in reconnected_uuids - assert src_uuid in reconnected_uuids - - # --- scenario: chain read-model groups actions into ordered chains --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - - # Creation via the main-window proxy records a ``new_object`` action and - # registers its output UUID. ``panel.add_object`` deliberately does not - # record, so it is used below to exercise an externally-rooted chain. - win.add_object(create_paracetamol_signal()) - panel.objview.select_objects([1]) - panel.processor.run_feature( - sips.normalize, sigima.params.NormalizeParam.create(method="maximum") - ) - panel.objview.select_objects([2]) - panel.processor.run_feature(sips.derivative) - - # --- invariant: grouping drops no action, per session --- - grouped = build_processing_chains(history) - assert len(grouped) == len(history.history_sessions) - for sess, sess_chains in grouped: - assert isinstance(sess, HistorySession) - assert sum(len(c.actions) for c in sess_chains) == len(sess.actions) - - # --- creation-rooted chain: creation -> normalize -> derivative --- - all_chains = [c for _sess, chains in grouped for c in chains] - creation_chains = [ - c - for c in all_chains - if c.root.kind == HistoryAction.KIND_UI - and c.root.method_name in HistoryAction.UI_CREATION_METHODS - ] - assert len(creation_chains) == 1 - chain = creation_chains[0] - assert isinstance(chain, ProcessingChain) - assert chain.actions[0] is chain.root - assert [a.func_name for a in chain.actions] == [None, "normalize", "derivative"] - assert all(a in chain.session.actions for a in chain.actions) - - # --- externally-rooted chain: a fresh session started on a - # non-recorded object (panel.add_object records no creation) roots its - # own (compute) chain, since a session's root is its first action --- - history.create_new_session(panel_str="signal") - panel.add_object(create_paracetamol_signal()) - panel.objview.select_objects([len(panel.objmodel)]) - panel.processor.run_feature(sips.derivative) - grouped2 = build_processing_chains(history) - for sess, sess_chains in grouped2: - assert sum(len(c.actions) for c in sess_chains) == len(sess.actions) - external_chains = [ - c - for _sess, chains in grouped2 - for c in chains - if c.root.kind == HistoryAction.KIND_COMPUTE - ] - assert external_chains - - # Keep build_session_chains imported — it is public API under test - assert callable(build_session_chains) - - # --- scenario: deleting an intermediate action splits its chain --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - panel = win.signalpanel - - # Creation via the main window records a ``new_object`` creation action; - # ``panel.add_object`` deliberately does not, so ``win.add_object`` is - # required to obtain a creation-rooted chain. - win.add_object(create_paracetamol_signal()) - panel.objview.select_objects([1]) - panel.processor.run_feature( - sips.normalize, sigima.params.NormalizeParam.create(method="maximum") - ) - panel.objview.select_objects([2]) - panel.processor.run_feature(sips.derivative) - - session = history.history_sessions[-1] - assert [a.func_name for a in session.actions] == [ - None, - "normalize", - "derivative", - ] - normalize_action = session.actions[1] - derivative_action = session.actions[2] - s002_uuid = get_uuid(panel.objmodel.get_object_from_number(2)) - assert s002_uuid in derivative_action.state.selection.get("signal", []) - n_objects_before = len(panel.objmodel) - - # Delete the MIDDLE action (normalize). Unattended mode auto-confirms and - # skips the associated-object removal prompt. - _select_tree_item_for(history, normalize_action) - history.delete_selected() - - # ``normalize`` is spliced out; creation and ``derivative`` remain. - assert normalize_action not in session.actions - assert session.actions[0].method_name in HistoryAction.UI_CREATION_METHODS - assert derivative_action in session.actions - - # A copy of ``normalize``'s output was added as a new parentless root. - assert len(panel.objmodel) == n_objects_before + 1 - - # The session remains a single linear chain (the history model does not - # split a session on delete) and drops no action. - chains = build_session_chains(history, session) - assert len(chains) == 1 - assert sum(len(c.actions) for c in chains) == len(session.actions) - - # The observable "split" is a data-level rewire: ``derivative`` no longer - # consumes ``normalize``'s original output (s002) but the parentless COPY - # added by the delete. - deriv_inputs = derivative_action.state.selection.get("signal", []) - assert s002_uuid not in deriv_inputs - - # --- new-session prompt when creating on a non-empty session --- - # --- scenario: user accepts the prompt -> a new session is opened --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - - # First creation reuses the (empty) current session: no prompt expected. - win.add_object(create_paracetamol_signal()) - assert len(history.history_sessions) == 1 - assert len(history.history_sessions[-1].actions) == 1 - - # Headless "accept": accept_dialogs drives the prompt to "Yes". - monkeypatch.setattr(execenv, "accept_dialogs", True) - n_sessions = len(history.history_sessions) - win.add_object(create_paracetamol_signal()) - assert len(history.history_sessions) == n_sessions + 1 - new_session = history.history_sessions[-1] - assert new_session.actions - assert new_session.actions[0].method_name == "new_object" - - # --- scenario: user declines the prompt -> no new session is created --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - win.add_object(create_paracetamol_signal()) - assert len(history.history_sessions) == 1 - - # Headless "decline": accept_dialogs stays False -> prompt answered "No". - monkeypatch.setattr(execenv, "accept_dialogs", False) - n_sessions = len(history.history_sessions) - win.add_object(create_paracetamol_signal()) - assert len(history.history_sessions) == n_sessions - - # --- scenario: recording routes per-panel into separate active sessions --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - spanel, ipanel = win.signalpanel, win.imagepanel - - # --- signal pipeline: one signal session --- - spanel.add_object(create_paracetamol_signal()) - spanel.objview.select_objects([1]) - spanel.processor.run_feature(sips.derivative) - assert len(history.history_sessions) == 1 - signal_session = history.get_active_session("signal") - assert signal_session is not None - assert len(signal_session.actions) == 1 - - # --- image pipeline: lands in a SEPARATE session --- - ipanel.add_object(create_sincos_image()) - ipanel.objview.select_objects([1]) - ipanel.processor.run_feature(sipi.inverse) - image_session = history.get_active_session("image") - assert image_session is not None - assert image_session is not signal_session - assert len(history.history_sessions) == 2 - assert len(image_session.actions) == 1 - # The image action did not leak into the signal session. - assert len(signal_session.actions) == 1 - - # --- back to signal: continue in the SAME signal session (no new one) --- - spanel.objview.select_objects([2]) - spanel.processor.run_feature(sips.derivative) - assert len(history.history_sessions) == 2 # no new session created - assert len(signal_session.actions) == 2 - assert len(image_session.actions) == 1 - - # --- resume into a SELECTED session --- - # Create a fresh (empty) signal session, then select the ORIGINAL signal - # session: a subsequent signal action must resume into the selected - # session, not the newly created empty one. - empty_session = history.create_new_session(panel_str="signal") - assert len(history.history_sessions) == 3 - n_before = len(signal_session.actions) - _select_tree_session(history, signal_session) - spanel.objview.select_objects([1]) - spanel.processor.run_feature( - sips.normalize, sigima.params.NormalizeParam.create(method="maximum") - ) - assert len(signal_session.actions) == n_before + 1 # resumed here - assert len(empty_session.actions) == 0 # NOT the empty session - assert len(image_session.actions) == 1 # image untouched - - # --- scenario: each panel's active session is highlighted (bold) --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - spanel, ipanel = win.signalpanel, win.imagepanel - - spanel.add_object(create_paracetamol_signal()) - spanel.objview.select_objects([1]) - spanel.processor.run_feature(sips.derivative) - signal_session = history.get_active_session("signal") - assert signal_session is not None - - ipanel.add_object(create_sincos_image()) - ipanel.objview.select_objects([1]) - ipanel.processor.run_feature(sipi.inverse) - image_session = history.get_active_session("image") - assert image_session is not None - - def _is_bold(session): - idx = history.history_sessions.index(session) - item = history.tree.topLevelItem(idx) - return item is not None and item.font(0).bold() - - # Both panels' active sessions are highlighted. - assert _is_bold(signal_session) - assert _is_bold(image_session) - - # Highlight survives a full repopulate. - history.tree.populate_tree(history.history_sessions) - assert _is_bold(signal_session) - assert _is_bold(image_session) - - # Creating a new signal session moves the signal highlight to it. - new_signal = history.create_new_session(panel_str="signal") - assert _is_bold(new_signal) - assert not _is_bold(signal_session) # previous signal session no longer active - assert _is_bold(image_session) # image highlight unchanged - - # Switching panels does not crash and keeps the highlight. - win.set_current_panel("image") - win.set_current_panel("signal") - assert _is_bold(new_signal) - assert _is_bold(image_session) - - # --- scenario: compatibility refresh tolerates a stale tree (regression) --- - with datalab_test_app_context(history=True) as win: - history = win.historypanel - history.toggle_record_mode(True) - spanel = win.signalpanel - spanel.add_object(create_paracetamol_signal()) - spanel.objview.select_objects([1]) - spanel.processor.run_feature(sips.derivative) - spanel.objview.select_objects([2]) - spanel.processor.run_feature(sips.derivative) - # Tree is populated and in sync here. - session = history.history_sessions[-1] - assert session.actions - # Simulate a transient desync: drop the last action from the model - # WITHOUT repopulating the tree (as happens mid-cascade). - removed = session.actions.pop() - # The tree still has an item for ``removed``; a compatibility refresh - # must skip it gracefully instead of raising ValueError. - history.tree.update_compatibility_states( - history.history_sessions, history.mainwindow - ) - # Restore invariant for a clean teardown. - session.actions.append(removed) diff --git a/datalab/tests/features/common/history_test_helpers.py b/datalab/tests/features/common/history_test_helpers.py new file mode 100644 index 000000000..d486a607d --- /dev/null +++ b/datalab/tests/features/common/history_test_helpers.py @@ -0,0 +1,186 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +"""Typed builders and selectors for History panel tests.""" + +from __future__ import annotations + +from dataclasses import dataclass +from types import SimpleNamespace +from typing import TYPE_CHECKING, Any, cast + +import sigima.params +import sigima.proc.signal as sips +from qtpy import QtCore as QC +from qtpy import QtWidgets as QW +from sigima.tests.data import create_paracetamol_signal + +from datalab.h5.native import NativeH5Reader +from datalab.history.action import HistoryAction +from datalab.history.replaymap import ReplayUuidMap +from datalab.history.session import HistorySession +from datalab.history.workspace_state import WorkspaceState + +if TYPE_CHECKING: + from datalab.gui.panel.history import HistoryPanel + from datalab.gui.panel.signal import SignalPanel + + +@dataclass(frozen=True) +class SignalChain: + """Objects and actions produced by a three-step signal chain.""" + + actions: tuple[HistoryAction, HistoryAction, HistoryAction] + outputs: tuple[Any, Any, Any] + + +class ReplayObjectModel: + """Minimal ordered object model used by replay-map tests.""" + + def __init__(self, objects: list[tuple[str, str]]) -> None: + self.objects = {uuid: SimpleNamespace(title=title) for uuid, title in objects} + + def __getitem__(self, uuid: str) -> SimpleNamespace: + """Return an object by UUID.""" + return self.objects[uuid] + + def get_object_ids(self) -> list[str]: + """Return object UUIDs in panel order.""" + return list(self.objects) + + def add(self, uuid: str, title: str) -> None: + """Add an object to the model.""" + self.objects[uuid] = SimpleNamespace(title=title) + + def remove(self, uuid: str) -> None: + """Remove an object from the model.""" + self.objects.pop(uuid) + + +def build_replay_map( + signal_objects: list[tuple[str, str]], + image_objects: list[tuple[str, str]] | None = None, +) -> tuple[ReplayUuidMap, ReplayObjectModel, ReplayObjectModel]: + """Build a replay map backed by minimal signal and image panels.""" + signal_model = ReplayObjectModel(signal_objects) + image_model = ReplayObjectModel(image_objects or []) + signal_panel = SimpleNamespace(PANEL_STR_ID="signal", objmodel=signal_model) + image_panel = SimpleNamespace(PANEL_STR_ID="image", objmodel=image_model) + panels = cast(Any, (signal_panel, image_panel)) + return ReplayUuidMap(panels), signal_model, image_model + + +def build_workspace_state( + selection: list[str], titles: list[str] | None = None +) -> WorkspaceState: + """Build a signal workspace state with stable object metadata.""" + state = WorkspaceState() + state.selection = {"signal": selection} + state.states = {"signal": ["(10,)"] * len(selection)} + state.titles = {"signal": titles or [f"Object {index}" for index in selection]} + state.object_metadata = { + "signal": { + uuid: {"shape": [10], "ndim": 1, "title": title} + for uuid, title in zip(selection, state.titles["signal"]) + } + } + return state + + +def build_history_action() -> HistoryAction: + """Build a serializable compute action containing every UUID reference.""" + action = HistoryAction( + title="Difference", + kind=HistoryAction.KIND_COMPUTE, + panel_str="signal", + func_name="difference", + pattern="2_to_1", + kwargs={"obj2_uuids": ["second-uuid"], "pairwise": False}, + state=build_workspace_state(["source-uuid"], ["Source"]), + ) + action.output_uuids = ["output-uuid"] + return action + + +def add_paracetamol_signals(panel: SignalPanel, count: int) -> list[str]: + """Add paracetamol signals and return their UUIDs in panel order.""" + for _index in range(count): + panel.add_object(create_paracetamol_signal()) + return panel.objmodel.get_object_ids()[-count:] + + +def build_signal_chain(panel: SignalPanel, history: HistoryPanel) -> SignalChain: + """Build Gaussian, derivative and moving-average processing outputs.""" + add_paracetamol_signals(panel, 1) + panel.objview.select_objects([1]) + panel.processor.run_feature( + sips.gaussian_filter, sigima.params.GaussianParam.create(sigma=1.5) + ) + first_action = history[len(history)] + first_output = panel.objmodel.get_object_from_number(2) + panel.objview.select_objects([2]) + panel.processor.run_feature(sips.derivative) + second_action = history[len(history)] + second_output = panel.objmodel.get_object_from_number(3) + panel.objview.select_objects([3]) + parameter = sigima.params.MovingAverageParam.create(n=3) + panel.processor.run_feature(sips.moving_average, parameter) + third_action = history[len(history)] + third_output = panel.objmodel.get_object_from_number(4) + return SignalChain( + (first_action, second_action, third_action), + (first_output, second_output, third_output), + ) + + +def read_history_sessions( + path: str, section: str = "history_session" +) -> list[HistorySession]: + """Read serialized history sessions from a file.""" + with NativeH5Reader(path) as reader: + return reader.read_object_list(section, HistorySession) + + +def delete_hdf5_items_by_name(group: Any, item_name: str) -> None: + """Delete HDF5 attributes and groups with a name recursively.""" + if item_name in group.attrs: + del group.attrs[item_name] + if not hasattr(group, "keys"): + return + for key in list(group.keys()): + if key == item_name: + del group[key] + else: + delete_hdf5_items_by_name(group[key], item_name) + + +def get_tree_item(history: HistoryPanel, uuid: str) -> QW.QTreeWidgetItem: + """Return the tree item identified by an entry UUID.""" + iterator = QW.QTreeWidgetItemIterator(history.tree) + while iterator.value(): + item = iterator.value() + if item.data(0, QC.Qt.UserRole) == uuid: + return item + iterator += 1 + raise LookupError(uuid) + + +def select_tree_entry(history: HistoryPanel, uuid: str) -> None: + """Select the tree item identified by an entry UUID.""" + item = get_tree_item(history, uuid) + history.tree.clearSelection() + history.tree.setCurrentItem(item) + item.setSelected(True) + + +def select_tree_session(history: HistoryPanel, session: HistorySession) -> None: + """Select a session's top-level tree item.""" + item = history.tree.topLevelItem(history.history_sessions.index(session)) + history.tree.clearSelection() + history.tree.setCurrentItem(item) + item.setSelected(True) + + +def is_session_bold(history: HistoryPanel, session: HistorySession) -> bool: + """Return whether a session's tree item uses a bold font.""" + item = history.tree.topLevelItem(history.history_sessions.index(session)) + return item is not None and item.font(0).bold() diff --git a/datalab/tests/features/common/history_workflow_test.py b/datalab/tests/features/common/history_workflow_test.py new file mode 100644 index 000000000..7cdbe2a40 --- /dev/null +++ b/datalab/tests/features/common/history_workflow_test.py @@ -0,0 +1,324 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +"""Application workflow contracts for the History panel.""" + +from __future__ import annotations + +import os +import tempfile + +import numpy as np +import sigima.params +import sigima.proc.signal as sips +from sigima.tests.data import create_paracetamol_signal + +from datalab.gui import historytools_ops as htools +from datalab.gui.panel.history import HistoryAction +from datalab.gui.panel.history.chainmodel import build_session_chains +from datalab.gui.processor.base import extract_processing_parameters +from datalab.h5.native import NativeH5Reader, NativeH5Writer +from datalab.objectmodel import get_uuid +from datalab.tests import datalab_test_app_context +from datalab.tests.features.common.history_test_helpers import ( + add_paracetamol_signals, + build_signal_chain, + read_history_sessions, + select_tree_entry, + select_tree_session, +) + + +def assert_compute_action( + action: HistoryAction, pattern: str, selection: list[str] +) -> None: + """Check the reusable recording invariant for a compute action.""" + assert action.kind == HistoryAction.KIND_COMPUTE + assert action.pattern == pattern + assert action.state.selection["signal"] == selection + assert action.output_uuids + + +def assert_duplicate_head(history, panel, session) -> None: + """Check the synthetic head of an operation-rooted duplicate.""" + head = session.actions[0] + assert head.kind == HistoryAction.KIND_UI + assert head.method_name == "new_object" + assert not head.kwargs and not head.state.selection + assert len(head.output_uuids) == 1 + clone_uuid = head.output_uuids[0] + assert history.runtime.objects.action_output_uuids[head.uuid] == [clone_uuid] + assert history.runtime.objects.output_to_action[clone_uuid] == head.uuid + assert clone_uuid in panel.objmodel.get_object_ids() + + +def test_history_recording_contract_and_output_index() -> None: + """Record producing patterns and index every output without replay entries.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + source_uuids = add_paracetamol_signals(panel, 2) + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.derivative) + derivative = history[len(history)] + panel.objview.select_objects([1, 2]) + panel.processor.run_feature(sips.average) + average = history[len(history)] + panel.objview.select_objects([1]) + panel.processor.run_feature( + sips.difference, panel.objmodel.get_object_from_number(2) + ) + difference = history[len(history)] + assert_compute_action(derivative, "1_to_1", [source_uuids[0]]) + assert_compute_action(average, "n_to_1", source_uuids) + assert_compute_action(difference, "2_to_1", [source_uuids[0]]) + assert difference.kwargs["obj2_uuids"] == [source_uuids[1]] + for action in (derivative, average, difference): + for output_uuid in action.output_uuids: + assert ( + history.runtime.objects.output_to_action[output_uuid] == action.uuid + ) + count_before = len(history) + derivative.replay(win, restore_selection=True, edit=False) + assert len(history) == count_before + + +def test_session_replay_remaps_distinct_processing_patterns() -> None: + """Replay chained 1-to-1, n-to-1 and ordered 2-to-1 computations.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + add_paracetamol_signals(panel, 2) + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.derivative) + panel.objview.select_objects([2]) + panel.processor.run_feature(sips.derivative) + panel.objview.select_objects([3, 4]) + panel.processor.run_feature(sips.average) + panel.objview.select_objects([3]) + panel.processor.run_feature( + sips.difference, panel.objmodel.get_object_from_number(4) + ) + session = history.history_sessions[-1] + difference = session.actions[-1] + original_title = panel.objmodel[difference.output_uuids[0]].title + assert original_title.index("s003") < original_title.index("s004") + object_count = len(panel.objmodel) + action_count = len(history) + session.replay(win, restore_selection=False, edit=False) + assert len(panel.objmodel) == object_count + 4 + assert len(history) == action_count + replayed = panel.objmodel.get_object_from_number(len(panel.objmodel)) + assert "s" in replayed.title and "-" in replayed.title + + +def test_history_hdf5_pristine_load_and_nonempty_import() -> None: + """Distinguish pristine loading, non-empty import and missing history.""" + with tempfile.TemporaryDirectory() as tmpdir: + history_path = os.path.join(tmpdir, "session.dlhist") + empty_path = os.path.join(tmpdir, "without_history.h5") + with datalab_test_app_context(history=True) as source: + history, panel = source.historypanel, source.signalpanel + history.toggle_record_mode(True) + add_paracetamol_signals(panel, 1) + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.derivative) + titles = [action.title for action in history] + assert history.save_to_dlhist_file(history_path) + with NativeH5Writer(empty_path) as writer: + panel.serialize_to_hdf5(writer) + with datalab_test_app_context(history=True) as target: + history, panel = target.historypanel, target.signalpanel + with NativeH5Reader(empty_path) as reader: + history.deserialize_from_hdf5(reader) + assert len(history) == 0 + assert history.open_dlhist_file(history_path) + assert [action.title for action in history] == titles + assert history.runtime.objects.action_output_uuids + assert history.runtime.objects.output_to_action + with NativeH5Reader(empty_path) as reader: + history.deserialize_from_hdf5(reader) + assert not history.history_sessions + assert not history.runtime.objects.action_output_uuids + assert not history.runtime.objects.output_to_action + pristine_counts = (len(history.history_sessions), len(panel.objmodel)) + panel.add_object(create_paracetamol_signal()) + assert history.open_dlhist_file(history_path) + assert len(history.history_sessions) > pristine_counts[0] + assert len(panel.objmodel) > pristine_counts[1] + 1 + + +def test_duplicate_creation_and_operation_rooted_chains() -> None: + """Duplicate both root kinds and synthesize a head only when required.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + win.add_object(create_paracetamol_signal()) + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.derivative) + first_source = history.history_sessions[-1] + first_source.actions[-1].plugin_origin = { + "module": "example.plugin", + "metadata": {"entry_points": ["derivative"]}, + } + history.create_new_session(panel_str="signal") + win.add_object(create_paracetamol_signal()) + panel.objview.select_objects([3]) + panel.processor.run_feature(sips.derivative) + second_source = history.history_sessions[-1] + history.tree.clearSelection() + for source in (first_source, second_source): + source_item = history.tree.topLevelItem( + history.history_sessions.index(source) + ) + source_item.setSelected(True) + htools.duplicate_selected_entries(history) + first_duplicate = history.history_sessions[1] + second_duplicate = history.history_sessions[3] + assert history.history_sessions == [ + first_source, + first_duplicate, + second_source, + second_duplicate, + ] + duplicate = first_duplicate + assert len(duplicate.actions) == len(first_source.actions) + assert duplicate.actions[0].method_name == "new_object" + assert duplicate.actions[0].uuid != first_source.actions[0].uuid + assert set(duplicate.actions[0].output_uuids).isdisjoint( + first_source.actions[0].output_uuids + ) + duplicate_compute = duplicate.actions[-1] + assert duplicate_compute.plugin_origin == first_source.actions[-1].plugin_origin + duplicate_compute.plugin_origin["metadata"]["entry_points"].append("average") + assert first_source.actions[-1].plugin_origin["metadata"]["entry_points"] == [ + "derivative" + ] + duplicate_output = panel.objmodel[duplicate_compute.output_uuids[0]] + processing = extract_processing_parameters(duplicate_output) + assert processing is not None + assert processing.source_uuid == duplicate.actions[0].output_uuids[0] + assert history.runtime.objects.output_to_action[get_uuid(duplicate_output)] == ( + duplicate_compute.uuid + ) + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + add_paracetamol_signals(panel, 1) + panel.objview.select_objects([1]) + panel.processor.run_feature(sips.derivative) + original = history.history_sessions[-1] + select_tree_session(history, original) + htools.duplicate_selected_entries(history) + duplicate = history.history_sessions[-1] + assert len(duplicate.actions) == len(original.actions) + 1 + assert_duplicate_head(history, panel, duplicate) + chains = build_session_chains(duplicate) + assert len(chains) == 1 and chains[0].root is duplicate.actions[0] + + +def test_edit_cascade_preserves_identity_and_action_state() -> None: + """Cascade in place while preserving identities, metadata and edit baseline.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + history.toggle_edit_mode(True) + chain = build_signal_chain(panel, history) + root_action, _middle_action, leaf_action = chain.actions + root_output, _middle_output, leaf_output = chain.outputs + leaf_uuid = get_uuid(leaf_output) + leaf_number = panel.objmodel.get_number(leaf_output) + leaf_data = leaf_output.xydata.copy() + leaf_output.metadata["user_marker"] = 123 + panel.objview.select_objects([2]) + assert panel.objprop.setup_processing_tab(root_output, reset_params=False) + editor = panel.objprop.processing_param_editor + assert editor is not None + editor.dataset.sigma = 7.0 + report = panel.objprop.apply_processing_parameters( + root_output, interactive=False + ) + assert report.success and root_action.has_pending_edits + assert root_action.kwargs["param"].sigma == 7.0 + assert get_uuid(panel.objmodel[leaf_uuid]) == leaf_uuid + assert panel.objmodel.get_number(panel.objmodel[leaf_uuid]) == leaf_number + assert panel.objmodel[leaf_uuid].metadata["user_marker"] == 123 + assert not np.array_equal(panel.objmodel[leaf_uuid].xydata, leaf_data) + with tempfile.TemporaryDirectory() as tmpdir: + path = os.path.join(tmpdir, "edited.dlhist") + assert history.save_to_dlhist_file(path) + sessions = read_history_sessions(path, history.H5_PREFIX) + restored = next( + action + for session in sessions + for action in session.actions + if action.uuid == root_action.uuid + ) + assert restored.has_pending_edits and restored.kwargs["param"].sigma == 7.0 + restored.restore_kwargs() + assert restored.kwargs["param"].sigma == 1.5 + assert leaf_action.is_stale is False + + +def test_deletion_reconnects_and_splices_chain() -> None: + """Reconnect after data deletion, then splice the producing action.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + win.add_object(create_paracetamol_signal()) + source_uuid = get_uuid(panel.objmodel.get_object_from_number(1)) + panel.objview.select_objects([1]) + panel.processor.run_feature( + sips.normalize, sigima.params.NormalizeParam.create(method="maximum") + ) + normalize = history[len(history)] + intermediate_uuid = normalize.output_uuids[0] + panel.objview.select_objects([2]) + panel.processor.run_feature(sips.derivative) + derivative = history[len(history)] + panel.objview.select_objects([2]) + panel.remove_object(force=True) + assert intermediate_uuid not in derivative.state.selection["signal"] + assert source_uuid in derivative.state.selection["signal"] + panel.objview.select_objects([source_uuid]) + panel.processor.run_feature( + sips.normalize, sigima.params.NormalizeParam.create(method="maximum") + ) + action_to_delete = history[len(history)] + panel.objview.select_objects([action_to_delete.output_uuids[0]]) + panel.processor.run_feature(sips.derivative) + downstream_action = history[len(history)] + session = history.history_sessions[-1] + object_count = len(panel.objmodel) + select_tree_entry(history, action_to_delete.uuid) + htools.delete_selected(history) + assert action_to_delete not in session.actions + assert action_to_delete.uuid not in history.runtime.objects.action_output_uuids + assert ( + action_to_delete.output_uuids[0] + not in history.runtime.objects.output_to_action + ) + assert derivative in session.actions and downstream_action in session.actions + assert len(panel.objmodel) == object_count + 1 + assert ( + action_to_delete.output_uuids[0] + not in downstream_action.state.selection["signal"] + ) + chains = build_session_chains(session) + assert sum(len(chain.actions) for chain in chains) == len(session.actions) + removed_action_uuids = [action.uuid for action in session.actions] + removed_output_uuids = [ + output_uuid + for action in session.actions + for output_uuid in action.output_uuids + ] + select_tree_session(history, session) + htools.delete_selected(history) + assert session not in history.history_sessions + assert all( + action_uuid not in history.runtime.objects.action_output_uuids + for action_uuid in removed_action_uuids + ) + assert all( + output_uuid not in history.runtime.objects.output_to_action + for output_uuid in removed_output_uuids + ) diff --git a/datalab/widgets/historytree.py b/datalab/widgets/historytree.py index 8e071737f..928516882 100644 --- a/datalab/widgets/historytree.py +++ b/datalab/widgets/historytree.py @@ -183,7 +183,7 @@ def build_session_children( session: History session whose actions are grouped into chains. """ session_item.takeChildren() - chains = build_session_chains(self._panel, session) + chains = build_session_chains(session) for chain in chains: chain_item = QW.QTreeWidgetItem([chain.root.title, ""]) chain_item.setData(0, self.ITEM_KIND_ROLE, self.ITEM_CHAIN) @@ -235,18 +235,12 @@ def rearrange_tree(self) -> None: for col in (0, 1): self.resizeColumnToContents(col) - def add_action_to_tree( - self, action: HistoryAction, session_index: int | None = None - ) -> None: - """Add an action under the session item at ``session_index``. + def rebuild_session(self, session_index: int) -> None: + """Rebuild the tree subtree for the session at ``session_index``. Args: - action: Action to add. - session_index: Top-level session item index. Defaults to the last - session (backward-compatible). + session_index: Top-level session item index. """ - if session_index is None: - session_index = self.topLevelItemCount() - 1 ritem = self.topLevelItem(session_index) if ritem is None: return From ad4101f90b5a97d190ee204578259b545dbe8be3 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Fri, 24 Jul 2026 13:43:39 +0200 Subject: [PATCH 061/108] Fix: Harden History replay and recomputation consistency Post-merge auditing exposed cases where plugin provenance could be lost during History operations, partial recomputation failures could leave outputs in an inconsistent state, and multi-action edits could replay dependent work more than once. History execution now preserves feature identity, reports failures explicitly, and applies dependent updates in a deterministic, transactional way. * [FIX] : Preserve plugin origins when replaying actions, remapping metadata, recomputing transformations, and refreshing analyses * [FIX] : Stop dependent cascades after failed actions and keep affected actions stale while allowing independent branches to continue * [FIX] : Validate multi-output recomputation before updating objects and roll back all outputs when an update cannot be completed * [FIX] : Isolate multi-object analysis persistence failures, continue with remaining objects, and distinguish empty results from failed execution * [CHG] : Deduplicate and globally order multi-action edits, restore action state on cancellation, and cascade analyses after upstream changes * [NEW] : Add regression coverage for plugin provenance, transactional recomputation, cascade failures, and multi-action History edits * [CHG] : Synchronize French translations for recomputation failure messages --- datalab/adapters_metadata/common.py | 1 + datalab/gui/panel/base.py | 65 +- datalab/gui/panel/history/chainmodel.py | 1 + .../gui/panel/history/interactive_replay.py | 75 +- datalab/gui/panel/history/recompute.py | 340 +++++---- datalab/gui/panel/history/reconnection.py | 7 +- datalab/gui/processor/base.py | 103 +-- datalab/history/action.py | 13 +- datalab/locale/fr/LC_MESSAGES/datalab.po | 26 +- .../features/common/history_workflow_test.py | 660 +++++++++++++++++- .../common/interactive_processing_test.py | 153 +++- 11 files changed, 1231 insertions(+), 213 deletions(-) diff --git a/datalab/adapters_metadata/common.py b/datalab/adapters_metadata/common.py index d63052fc5..e334dff9a 100644 --- a/datalab/adapters_metadata/common.py +++ b/datalab/adapters_metadata/common.py @@ -55,6 +55,7 @@ class ResultData: results: list[BaseResultAdapter] | None = None ylabels: list[str] | None = None short_ids: list[str] | None = None + execution_success: bool = True def __bool__(self) -> bool: """Return True if there are results stored""" diff --git a/datalab/gui/panel/base.py b/datalab/gui/panel/base.py index f8401b3d0..2c26a6e89 100644 --- a/datalab/gui/panel/base.py +++ b/datalab/gui/panel/base.py @@ -895,7 +895,7 @@ def apply_analysis_parameters( obj: SignalObj | ImageObj | None = None, interactive: bool = True, param: gds.DataSet | None = None, - ) -> None: + ) -> bool: """Apply analysis parameters: re-run the 1-to-0 analysis in place. Args: @@ -911,7 +911,7 @@ def apply_analysis_parameters( editor = self.analysis_param_editor obj = obj or self.current_analysis_obj if obj is None: - return + return False # Extract analysis parameters proc_params = extract_analysis_parameters(obj) @@ -920,7 +920,7 @@ def apply_analysis_parameters( QW.QMessageBox.warning( self, _("Error"), _("Analysis metadata is incomplete.") ) - return + return False func_name = proc_params.func_name @@ -929,21 +929,22 @@ def apply_analysis_parameters( # the stored analysis parameters. if param is None: param = editor.dataset if editor is not None else proc_params.param + recompute_param = copy.deepcopy(param) # Disable ROI creation during re-analysis: detection functions store # create_rois=True in their parameters, but re-running should only # update analysis results, not recreate ROIs (which would make them # impossible to delete or modify). - if hasattr(param, "create_rois"): - param.create_rois = False + if hasattr(recompute_param, "create_rois"): + recompute_param.create_rois = False # Re-run the analysis in place (no history entry: runs under replaying) processor = self.__get_processor_associated_to(obj) try: - processor.recompute_1_to_0( + success = processor.recompute_1_to_0( func_name, obj, - param, + recompute_param, plugin_origin=proc_params.plugin_origin, ) except Exception as exc: # pylint: disable=broad-exception-caught @@ -954,7 +955,13 @@ def apply_analysis_parameters( _("Error"), _("Failed to recompute analysis:\n%s") % str(exc), ) - return + return False + if not success: + if interactive: + QW.QMessageBox.warning( + self, _("Error"), _("Failed to recompute analysis.") + ) + return False # Propagate the edited param to the History panel: mutate the matching # analysis action (snapshot originals first) and refresh its tree @@ -965,7 +972,7 @@ def apply_analysis_parameters( action = hpanel.find_analysis_action(get_uuid(obj), func_name) if action is not None: action.snapshot_kwargs() - action.kwargs["param"] = copy.deepcopy(param) + action.kwargs["param"] = copy.deepcopy(recompute_param) hpanel.refresh_action(action) # Refresh the object display after re-analysis @@ -983,6 +990,7 @@ def apply_analysis_parameters( self.current_analysis_obj, set_current=True ), ) + return True def __get_processor_associated_to( self, obj: SignalObj | ImageObj @@ -3111,14 +3119,17 @@ def recompute_1_to_1_objects( return recomputed_uuids, True return recomputed_uuids, False - def recompute_1_to_0_objects(self, objects: list[SignalObj | ImageObj]) -> None: + def recompute_1_to_0_objects( + self, objects: list[SignalObj | ImageObj] + ) -> tuple[set[str], bool]: """Recompute 1-to-0 analysis operations for the given objects. Args: objects: Objects with stored 1-to-0 analysis parameters """ if not objects: - return + return set(), False + recomputed_uuids: set[str] = set() with create_progress_bar( self, _("Recomputing analyses"), max_=len(objects) ) as progress: @@ -3126,8 +3137,36 @@ def recompute_1_to_0_objects(self, objects: list[SignalObj | ImageObj]) -> None: progress.setValue(index + 1) QW.QApplication.processEvents() if progress.wasCanceled(): - break - self.processor.recompute_analysis(obj) + return recomputed_uuids, True + try: + success = self.processor.recompute_analysis(obj) + message = _("Analysis computation failed.") + except Exception as exc: # pylint: disable=broad-exception-caught + success = False + message = str(exc) + if success: + recomputed_uuids.add(get_uuid(obj)) + continue + if execenv.unattended: + continue + failtxt = _("Failed to recompute analysis") + if index == len(objects) - 1: + QW.QMessageBox.warning( + self, + _("Recompute"), + f"{failtxt} '{obj.title}':\n{message}", + ) + else: + conttxt = _("Do you want to continue with the next object?") + answer = QW.QMessageBox.warning( + self, + _("Recompute"), + f"{failtxt} '{obj.title}':\n{message}\n\n{conttxt}", + QW.QMessageBox.Yes | QW.QMessageBox.No, + ) + if answer == QW.QMessageBox.No: + return recomputed_uuids, True + return recomputed_uuids, False def select_source_objects(self) -> None: """Select source objects associated with the selected object's processing. diff --git a/datalab/gui/panel/history/chainmodel.py b/datalab/gui/panel/history/chainmodel.py index ec0017943..801243989 100644 --- a/datalab/gui/panel/history/chainmodel.py +++ b/datalab/gui/panel/history/chainmodel.py @@ -150,6 +150,7 @@ def remap_processing_parameters( param=parameters.param, source_uuid=source_uuid, source_uuids=source_uuids, + plugin_origin=parameters.plugin_origin, ) diff --git a/datalab/gui/panel/history/interactive_replay.py b/datalab/gui/panel/history/interactive_replay.py index f2a97172d..7ee0f8bfc 100644 --- a/datalab/gui/panel/history/interactive_replay.py +++ b/datalab/gui/panel/history/interactive_replay.py @@ -14,8 +14,10 @@ from datalab.config import _ from datalab.env import execenv +from datalab.gui.panel.history import chain as hchain from datalab.gui.panel.history import recompute as hrec from datalab.history import HistoryAction, HistorySession +from datalab.history.core import copy_history_value if TYPE_CHECKING: from datalab.gui.panel.history.panel import HistoryPanel @@ -124,11 +126,13 @@ def prompt_edit_action_params( def edit_mode_replay_actions(panel: HistoryPanel, actions: list[HistoryAction]) -> None: - """Edit and recompute only the selected actions, in session order. + """Edit selected actions and recompute their affected branches once. - Each selected action gets exactly one parameter dialog; non-selected - downstream actions are left untouched (no automatic cascade). A - re-entrance guard prevents nested prompt loops. + Each selected action gets exactly one parameter dialog. Recomputable + selected actions are always included, while accepted parameter edits also + include all downstream dependent actions. The resulting global plan is + deduplicated and executed in session order. A re-entrance guard prevents + nested prompt loops. """ # Deduplicate and sort the selected actions in their session order ordered = order_selected_actions(panel, actions) @@ -137,8 +141,16 @@ def edit_mode_replay_actions(panel: HistoryPanel, actions: list[HistoryAction]) with panel.runtime.execution.replaying_edits() as started: if not started: return + entry_states = { + action.uuid: ( + copy_history_value(action.kwargs), + copy_history_value(action.saved_kwargs), + ) + for action in ordered + } edited_actions: list[HistoryAction] = [] recomputable: list[HistoryAction] = [] + deferred_actions: list[HistoryAction] = [] for action in ordered: is_creation = ( action.kind == HistoryAction.KIND_UI @@ -148,14 +160,15 @@ def edit_mode_replay_actions(panel: HistoryPanel, actions: list[HistoryAction]) action.kind == HistoryAction.KIND_COMPUTE and action.pattern is not None ) if not is_creation and not is_compute: - with panel.replaying(), panel.output_suppressed(): - action.replay(panel.mainwindow, restore_selection=True, edit=True) + deferred_actions.append(action) continue result = prompt_edit_action_params(panel, action) if result is False: - for done in edited_actions: - done.restore_kwargs() - panel.tree.refresh_action_item(done) + for selected_action in ordered: + kwargs, saved_kwargs = entry_states[selected_action.uuid] + selected_action.kwargs = kwargs + selected_action.saved_kwargs = saved_kwargs + panel.tree.refresh_action_item(selected_action) return if result is True: edited_actions.append(action) @@ -163,11 +176,38 @@ def edit_mode_replay_actions(panel: HistoryPanel, actions: list[HistoryAction]) for action in edited_actions: panel.tree.refresh_action_item(action) - for action in recomputable: - hrec.recompute_action_in_place(panel, action) + planned = list(recomputable) + for action in edited_actions: + planned.extend(hchain.get_downstream_actions(panel, action)) + planned = order_selected_actions(panel, planned) + execution_plan = order_selected_actions(panel, deferred_actions + planned) + for action in planned: + action.is_stale = True panel.tree.refresh_action_item(action) - if edited_actions: - hrec.recompute_cascade(panel, edited_actions[0]) + QW.QApplication.processEvents() + blocked_outputs: set[str] = set() + try: + for action in execution_plan: + if action in deferred_actions: + with panel.replaying(), panel.output_suppressed(): + action.replay( + panel.mainwindow, restore_selection=True, edit=True + ) + continue + if hchain.action_consumes_any(action, blocked_outputs): + blocked_outputs.update( + panel.runtime.objects.action_output_uuids.get(action.uuid, []) + ) + continue + success = hrec.recompute_action_in_place(panel, action) + action.is_stale = not success + panel.tree.refresh_action_item(action) + if not success: + blocked_outputs.update( + panel.runtime.objects.action_output_uuids.get(action.uuid, []) + ) + finally: + hrec.flush_cascade_warnings(panel) QW.QApplication.processEvents() @@ -214,6 +254,11 @@ def restore_action_params( continue action.restore_kwargs() panel.tree.refresh_action_item(action) - hrec.recompute_action_in_place(panel, action) - hrec.recompute_cascade(panel, action) + success = hrec.recompute_action_in_place(panel, action) + action.is_stale = not success + panel.tree.refresh_action_item(action) + if not success: + break + if not isinstance(item, HistorySession): + hrec.recompute_cascade(panel, action) panel.ui.update_actions_state() diff --git a/datalab/gui/panel/history/recompute.py b/datalab/gui/panel/history/recompute.py index 95040b5cd..b5a8cea13 100644 --- a/datalab/gui/panel/history/recompute.py +++ b/datalab/gui/panel/history/recompute.py @@ -4,6 +4,7 @@ from __future__ import annotations +import copy import logging from typing import TYPE_CHECKING @@ -22,6 +23,7 @@ from datalab.gui.processor.base import ( FeatureNotFoundError, ProcessingParameters, + extract_analysis_parameters, extract_processing_parameters, insert_processing_parameters, ) @@ -117,16 +119,15 @@ def record_missing_outputs( ) -def recompute_action_in_place(panel: HistoryPanel, action: HistoryAction) -> None: +def recompute_action_in_place(panel: HistoryPanel, action: HistoryAction) -> bool: """Re-run ``action`` on the existing output object(s) (same UUIDs).""" if ( action.kind == HistoryAction.KIND_UI and action.method_name in HistoryAction.UI_CREATION_METHODS ): - recompute_creation_in_place(panel, action) - return + return recompute_creation_in_place(panel, action) if action.kind != HistoryAction.KIND_COMPUTE: - return + return False method = { "1_to_1": recompute_1_to_1_in_place, "1_to_n": recompute_1_to_n_in_place, @@ -144,12 +145,24 @@ def recompute_action_in_place(panel: HistoryPanel, action: HistoryAction) -> Non _("Action %s uses pattern %r which is not recomputable yet.") % (action.func_name or action.uuid, action.pattern) ) - return + return False try: - method(panel, action) + warning_count = len(panel.runtime.execution.cascade_warnings) + success = method(panel, action) + if ( + not success + and len(panel.runtime.execution.cascade_warnings) == warning_count + ): + panel.runtime.execution.cascade_warnings.append( + _("Action %s could not be fully recomputed.") + % (action.func_name or action.uuid) + ) + return success except FeatureNotFoundError as exc: handle_missing_feature(panel, action, exc) except (RuntimeError, ValueError, AttributeError, KeyError, TypeError) as exc: + action.is_stale = True + panel.runtime.execution.broken_actions.add(action.uuid) _logger.exception( "Cascade recompute failed for action %s (%s): %s", action.uuid, @@ -160,6 +173,7 @@ def recompute_action_in_place(panel: HistoryPanel, action: HistoryAction) -> Non _("Recompute failed for action %s: %s") % (action.func_name or action.uuid, exc) ) + return False def handle_missing_feature( @@ -192,7 +206,7 @@ def handle_missing_feature( ) -def recompute_creation_in_place(panel: HistoryPanel, action: HistoryAction) -> None: +def recompute_creation_in_place(panel: HistoryPanel, action: HistoryAction) -> bool: """Recompute a creation (``new_object``) action in place. Rebuild the object from the edited ``param`` and copy it onto the @@ -200,75 +214,77 @@ def recompute_creation_in_place(panel: HistoryPanel, action: HistoryAction) -> N """ panel_data = hchain.resolve_panel_for_action(panel, action) if panel_data is None: - return + return False existing, missing = hchain.resolve_target_outputs(panel, panel_data, action) record_missing_outputs(panel, action, missing) - if not existing: - return + if missing or not existing: + return False output_uuid = existing[0] if not panel_data.objmodel.has_uuid(output_uuid): - return + return False output_obj = panel_data.objmodel[output_uuid] param = action.kwargs.get("param") if param is None: - return + return False if action.target == "signalpanel": prepared = prepare_signal_parameters(param, edit=False) if prepared is None: - return + return False new_obj = create_signal_from_param(prepared) else: new_obj = create_image_from_param(param) update_obj_in_place(output_obj, new_obj) insert_creation_parameters(output_obj, param) refresh_target(panel_data, output_uuid) + return True -def recompute_1_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> None: +def recompute_1_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> bool: """Recompute a single 1-to-1 action in place.""" panel_data = hchain.resolve_panel_for_action(panel, action) if panel_data is None: - return + return False existing, missing = hchain.resolve_target_outputs(panel, panel_data, action) if not existing and not missing: legacy = hchain.find_output_object_uuid(panel, panel_data, action) if legacy is not None: existing = [legacy] record_missing_outputs(panel, action, missing) - if not existing: - return + if missing or not existing: + return False output_uuid = existing[0] if not panel_data.objmodel.has_uuid(output_uuid): - return + return False output_obj = panel_data.objmodel[output_uuid] pp = extract_processing_parameters(output_obj) if pp is None or pp.source_uuid is None: - return + return False if not panel_data.objmodel.has_uuid(pp.source_uuid): panel.runtime.execution.cascade_warnings.append( _("Action %s: source object was deleted — skipping.") % (action.func_name or action.uuid) ) - return + return False source_obj = panel_data.objmodel[pp.source_uuid] param = action.kwargs.get("param") + plugin_origin = action.plugin_origin or pp.plugin_origin compout = panel_data.processor.recompute_1_to_1( action.func_name, source_obj, param, - plugin_origin=action.plugin_origin, + plugin_origin=plugin_origin, ) if compout.cancelled: - return + return False if compout.error_msg: panel.runtime.execution.cascade_warnings.append( _("Recompute failed for action %s: %s") % (action.func_name or action.uuid, compout.error_msg) ) - return + return False new_obj = compout.result if not isinstance(new_obj, (SignalObj, ImageObj)): - return + return False panel_data.objprop.apply_recomputed_object_in_place( output_obj, new_obj, @@ -277,82 +293,105 @@ def recompute_1_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> Non pattern=pp.pattern, param=param if param is not None else pp.param, source_uuid=pp.source_uuid, + plugin_origin=plugin_origin, ), ) refresh_target(panel_data, output_uuid) + return True -def recompute_1_to_n_in_place(panel: HistoryPanel, action: HistoryAction) -> None: +def recompute_1_to_n_in_place(panel: HistoryPanel, action: HistoryAction) -> bool: """Recompute a 1-to-n action in place: replace each of the N outputs.""" panel_data = hchain.resolve_panel_for_action(panel, action) if panel_data is None: - return + return False existing, missing = hchain.resolve_target_outputs(panel, panel_data, action) record_missing_outputs(panel, action, missing) - if not existing or not panel_data.objmodel.has_uuid(existing[0]): - return + if missing or not existing or not panel_data.objmodel.has_uuid(existing[0]): + return False first_obj = panel_data.objmodel[existing[0]] pp = extract_processing_parameters(first_obj) if pp is None or pp.source_uuid is None: - return + return False if not panel_data.objmodel.has_uuid(pp.source_uuid): panel.runtime.execution.cascade_warnings.append( _("Action %s: source object was deleted — skipping.") % (action.func_name or action.uuid) ) - return + return False source_obj = panel_data.objmodel[pp.source_uuid] params = action.kwargs.get("params") or [] if not params: - return + return False + plugin_origin = action.plugin_origin or pp.plugin_origin new_objs = panel_data.processor.recompute_1_to_n( action.func_name, source_obj, params, - plugin_origin=action.plugin_origin, + plugin_origin=plugin_origin, ) if not new_objs: - return - n = min(len(existing), len(new_objs)) - for idx in range(n): - out_uuid = existing[idx] - if not panel_data.objmodel.has_uuid(out_uuid): - continue - out_obj = panel_data.objmodel[out_uuid] - new_obj = new_objs[idx] - update_obj_in_place(out_obj, new_obj) - new_param = params[idx] if idx < len(params) else None - insert_processing_parameters( - out_obj, - ProcessingParameters( - func_name=action.func_name, - pattern="1-to-n", - param=new_param, - source_uuid=pp.source_uuid, - ), - ) - refresh_target(panel_data, out_uuid) - if len(new_objs) != len(existing): + return False + if len(new_objs) != len(existing) or not all( + isinstance(obj, (SignalObj, ImageObj)) for obj in new_objs + ): _logger.warning( "1-to-n cardinality changed for action %s: %d outputs, %d existing.", action.uuid, len(new_objs), len(existing), ) - - -def recompute_n_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> None: + panel.runtime.execution.cascade_warnings.append( + _("Action %s: recompute returned %d output(s), expected %d.") + % (action.func_name or action.uuid, len(new_objs), len(existing)) + ) + return False + snapshots = { + out_uuid: copy.deepcopy(panel_data.objmodel[out_uuid]) for out_uuid in existing + } + try: + for idx, out_uuid in enumerate(existing): + out_obj = panel_data.objmodel[out_uuid] + update_obj_in_place(out_obj, new_objs[idx]) + insert_processing_parameters( + out_obj, + ProcessingParameters( + func_name=action.func_name, + pattern="1-to-n", + param=params[idx], + source_uuid=pp.source_uuid, + plugin_origin=plugin_origin, + ), + ) + for out_uuid in existing: + refresh_target(panel_data, out_uuid) + except Exception: + for out_uuid, snapshot in snapshots.items(): + update_obj_in_place(panel_data.objmodel[out_uuid], snapshot) + for out_uuid in snapshots: + try: + refresh_target(panel_data, out_uuid) + except Exception: + _logger.exception( + "Cascade recompute rollback refresh failed for output %s.", + out_uuid, + ) + raise + return True + + +def recompute_n_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> bool: """Recompute an n-to-1 action in place.""" panel_data = hchain.resolve_panel_for_action(panel, action) if panel_data is None: - return + return False existing, missing = hchain.resolve_target_outputs(panel, panel_data, action) record_missing_outputs(panel, action, missing) - if not existing: - return + if missing or not existing: + return False output_uuid = existing[0] if not panel_data.objmodel.has_uuid(output_uuid): - return + return False output_obj = panel_data.objmodel[output_uuid] pp = extract_processing_parameters(output_obj) source_uuids: list[str] = [] @@ -360,25 +399,25 @@ def recompute_n_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> Non source_uuids = list(pp.source_uuids) else: source_uuids = list(action.state.selection.get(panel_data.PANEL_STR_ID, [])) - src_objs: list[SignalObj | ImageObj] = [] - for uuid in source_uuids: - if panel_data.objmodel.has_uuid(uuid): - src_objs.append(panel_data.objmodel[uuid]) - if not src_objs: + if not source_uuids or not all( + panel_data.objmodel.has_uuid(uuid) for uuid in source_uuids + ): panel.runtime.execution.cascade_warnings.append( - _("Action %s: all source objects were deleted — skipping.") + _("Action %s: source object(s) were deleted — skipping.") % (action.func_name or action.uuid) ) - return + return False + src_objs = [panel_data.objmodel[uuid] for uuid in source_uuids] param = action.kwargs.get("param") + plugin_origin = action.plugin_origin or (pp.plugin_origin if pp else None) new_obj = panel_data.processor.recompute_n_to_1( action.func_name, src_objs, param, - plugin_origin=action.plugin_origin, + plugin_origin=plugin_origin, ) - if new_obj is None: - return + if not isinstance(new_obj, (SignalObj, ImageObj)): + return False update_obj_in_place(output_obj, new_obj) insert_processing_parameters( output_obj, @@ -387,31 +426,41 @@ def recompute_n_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> Non pattern="n-to-1", param=param, source_uuids=[get_uuid(o) for o in src_objs], + plugin_origin=plugin_origin, ), ) refresh_target(panel_data, output_uuid) + return True -def recompute_2_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> None: +def recompute_2_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> bool: """Recompute a 2-to-1 action in place (single or pairwise).""" panel_data = hchain.resolve_panel_for_action(panel, action) if panel_data is None: - return + return False existing, missing = hchain.resolve_target_outputs(panel, panel_data, action) record_missing_outputs(panel, action, missing) - if not existing: - return + if missing or not existing: + return False param = action.kwargs.get("param") obj2_uuids = action.kwargs.get("obj2_uuids") or [] if isinstance(obj2_uuids, str): obj2_uuids = [obj2_uuids] pairwise = bool(action.kwargs.get("pairwise")) recorded_inputs = list(action.state.selection.get(panel_data.PANEL_STR_ID, [])) + staged: list[ + tuple[ + str, + SignalObj | ImageObj, + SignalObj | ImageObj, + SignalObj | ImageObj, + dict | None, + ] + ] = [] for idx, out_uuid in enumerate(existing): if not panel_data.objmodel.has_uuid(out_uuid): - continue - output_obj = panel_data.objmodel[out_uuid] - pp = extract_processing_parameters(output_obj) + return False + pp = extract_processing_parameters(panel_data.objmodel[out_uuid]) src_uuids = ( list(pp.source_uuids) if pp is not None and pp.source_uuids @@ -426,7 +475,7 @@ def recompute_2_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> Non _("Action %s: missing source(s) for output #%d — skipping.") % (action.func_name or action.uuid, idx + 1) ) - continue + return False if not ( panel_data.objmodel.has_uuid(src_uuids[0]) and panel_data.objmodel.has_uuid(src_uuids[1]) @@ -435,58 +484,100 @@ def recompute_2_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> Non _("Action %s: source object(s) were deleted — skipping.") % (action.func_name or action.uuid) ) - continue + return False obj1 = panel_data.objmodel[src_uuids[0]] obj2 = panel_data.objmodel[src_uuids[1]] + plugin_origin = action.plugin_origin or (pp.plugin_origin if pp else None) new_obj = panel_data.processor.recompute_2_to_1( action.func_name, obj1, obj2, param, - plugin_origin=action.plugin_origin, + plugin_origin=plugin_origin, ) - if new_obj is None: - continue - update_obj_in_place(output_obj, new_obj) - insert_processing_parameters( - output_obj, - ProcessingParameters( - func_name=action.func_name, - pattern="2-to-1", - param=param, - source_uuids=[get_uuid(obj1), get_uuid(obj2)], - ), - ) - refresh_target(panel_data, out_uuid) - - -def recompute_1_to_0_in_place(panel: HistoryPanel, action: HistoryAction) -> None: + if not isinstance(new_obj, (SignalObj, ImageObj)): + return False + staged.append((out_uuid, new_obj, obj1, obj2, plugin_origin)) + snapshots = { + out_uuid: copy.deepcopy(panel_data.objmodel[out_uuid]) + for out_uuid, *_rest in staged + } + try: + for out_uuid, new_obj, obj1, obj2, plugin_origin in staged: + output_obj = panel_data.objmodel[out_uuid] + update_obj_in_place(output_obj, new_obj) + insert_processing_parameters( + output_obj, + ProcessingParameters( + func_name=action.func_name, + pattern="2-to-1", + param=param, + source_uuids=[get_uuid(obj1), get_uuid(obj2)], + plugin_origin=plugin_origin, + ), + ) + for out_uuid, *_rest in staged: + refresh_target(panel_data, out_uuid) + except Exception: + for out_uuid, snapshot in snapshots.items(): + update_obj_in_place(panel_data.objmodel[out_uuid], snapshot) + for out_uuid in snapshots: + try: + refresh_target(panel_data, out_uuid) + except Exception: + _logger.exception( + "Cascade recompute rollback refresh failed for output %s.", + out_uuid, + ) + raise + return True + + +def recompute_1_to_0_in_place(panel: HistoryPanel, action: HistoryAction) -> bool: """Recompute a 1-to-0 analysis on each source object in place.""" panel_data = hchain.resolve_panel_for_action(panel, action) if panel_data is None: - return + return False sources = list(action.state.selection.get(panel_data.PANEL_STR_ID, [])) if not sources: - return - param = action.kwargs.get("param") - missing: list[str] = [] - for uuid in sources: - if not panel_data.objmodel.has_uuid(uuid): - missing.append(uuid) - continue - src_obj = panel_data.objmodel[uuid] - panel_data.processor.recompute_1_to_0( - action.func_name, - src_obj, - param, - plugin_origin=action.plugin_origin, - ) - refresh_target(panel_data, uuid) + return False + param = copy.deepcopy(action.kwargs.get("param")) + if hasattr(param, "create_rois"): + param.create_rois = False + missing = [uuid for uuid in sources if not panel_data.objmodel.has_uuid(uuid)] if missing: panel.runtime.execution.cascade_warnings.append( _("Action %s: %d analysed object(s) were deleted — skipping.") % (action.func_name or action.uuid, len(missing)) ) + return False + source_objs = [panel_data.objmodel[uuid] for uuid in sources] + metadata_snapshots = [copy.deepcopy(obj.metadata) for obj in source_objs] + try: + for src_obj in source_objs: + analysis_parameters = extract_analysis_parameters(src_obj) + plugin_origin = action.plugin_origin or ( + analysis_parameters.plugin_origin if analysis_parameters else None + ) + success = panel_data.processor.recompute_1_to_0( + action.func_name, + src_obj, + param, + plugin_origin=plugin_origin, + ) + if not success: + for obj, metadata in zip(source_objs, metadata_snapshots): + obj.metadata.clear() + obj.metadata.update(metadata) + return False + except Exception: + for obj, metadata in zip(source_objs, metadata_snapshots): + obj.metadata.clear() + obj.metadata.update(metadata) + raise + for uuid in sources: + refresh_target(panel_data, uuid) + return True def recompute_cascade( @@ -513,23 +604,14 @@ def recompute_cascade( action.is_stale = True panel.tree.refresh_action_item(action) QW.QApplication.processEvents() - try: - for action in descendants: - try: - recompute_action_in_place(panel, action) - finally: - if action.uuid not in panel.runtime.execution.broken_actions: - action.is_stale = False - panel.tree.refresh_action_item(action) - QW.QApplication.processEvents() - finally: - for action in descendants: - if ( - action.is_stale - and action.uuid not in panel.runtime.execution.broken_actions - ): - action.is_stale = False - panel.tree.refresh_action_item(action) + for action in descendants: + success = recompute_action_in_place(panel, action) + if success: + action.is_stale = False + panel.tree.refresh_action_item(action) + QW.QApplication.processEvents() + if not success: + break flush_cascade_warnings(panel) diff --git a/datalab/gui/panel/history/reconnection.py b/datalab/gui/panel/history/reconnection.py index 8bb02b356..c2c88d0fa 100644 --- a/datalab/gui/panel/history/reconnection.py +++ b/datalab/gui/panel/history/reconnection.py @@ -36,8 +36,11 @@ def reconnect_chain_after_removal( for plan in plans: hchain.apply_reconnection_plan(panel, panel_data, plan, roots_to_recompute) for action in roots_to_recompute: - hrec.recompute_action_in_place(panel, action) - hrec.recompute_cascade(panel, action) + success = hrec.recompute_action_in_place(panel, action) + action.is_stale = not success + panel.tree.refresh_action_item(action) + if success: + hrec.recompute_cascade(panel, action) hchain.show_reconnection_warnings( panel, [plan.warning for plan in plans if plan.warning is not None] ) diff --git a/datalab/gui/processor/base.py b/datalab/gui/processor/base.py index 4d3606430..895943562 100644 --- a/datalab/gui/processor/base.py +++ b/datalab/gui/processor/base.py @@ -9,6 +9,7 @@ from __future__ import annotations import abc +import copy import inspect import multiprocessing import os.path as osp @@ -639,12 +640,14 @@ def _detect_plugin_origin(func: Callable) -> dict[str, Any] | None: candidates.append(func) module_name = "" + origin_candidate = func for candidate in candidates: mod = getattr(candidate, "__module__", "") or "" if mod: top = mod.split(".", 1)[0] if top not in _BUILTIN_MODULE_PREFIXES: module_name = mod + origin_candidate = candidate break if not module_name: # All candidates are built-in; fall back to the outer func's module @@ -691,7 +694,7 @@ def _detect_plugin_origin(func: Callable) -> dict[str, Any] | None: if top and top not in _BUILTIN_MODULE_PREFIXES: directory = None try: - directory = osp.basename(osp.dirname(inspect.getfile(func))) + directory = osp.basename(osp.dirname(inspect.getfile(origin_candidate))) except (TypeError, OSError): pass return { @@ -1216,7 +1219,7 @@ def _handle_keep_results(self, result_obj: SignalObj | ImageObj) -> None: def recompute_analysis( self, obj: SignalObj | ImageObj, refresh_plot: bool = True - ) -> None: + ) -> bool: """Recompute analysis (1-to-0) operations on demand. This method checks if the object has 1-to-0 analysis parameters (analysis @@ -1236,10 +1239,10 @@ def recompute_analysis( # Check if object has 1-to-0 analysis parameters (analysis operations) proc_params = extract_analysis_parameters(obj) if proc_params is None or proc_params.pattern != "1-to-0": - return + return False # Get the parameter from processing parameters - param = proc_params.param + param = copy.deepcopy(proc_params.param) # Disable ROI creation during recompute: detection functions store # create_rois=True in their parameters, but recompute should only @@ -1250,18 +1253,21 @@ def recompute_analysis( # Recompute the analysis operation silently, only for this specific object # (not all selected objects, to avoid O(n²) behavior when called in a loop). - self.recompute_1_to_0( + success = self.recompute_1_to_0( proc_params.func_name, obj, param, plugin_origin=proc_params.plugin_origin, ) + if not success: + return False # Update the view obj_uuid = get_uuid(obj) self.panel.objview.update_item(obj_uuid) if refresh_plot: self.panel.refresh_plot(obj_uuid, update_items=True, force=True) + return True def recompute_processing( self, @@ -1645,7 +1651,7 @@ def recompute_1_to_0( obj: SignalObj | ImageObj, param: gds.DataSet | None = None, plugin_origin: dict[str, Any] | None = None, - ) -> None: + ) -> bool: """Recompute a 1-to-0 analysis on ``obj`` in place. Reuses :meth:`compute_1_to_0` with ``target_objs=[obj]`` under the @@ -1657,6 +1663,9 @@ def recompute_1_to_0( obj: Object whose analysis must be refreshed. param: Analysis parameters (optional). plugin_origin: Optional plugin origin descriptor. + + Returns: + True if the analysis result was refreshed successfully. """ paramclass_name = type(param).__name__ if param is not None else None feature = self.get_feature( @@ -1666,7 +1675,10 @@ def recompute_1_to_0( ) historypanel = self.mainwindow.historypanel with historypanel.replaying(), Conf.proc.show_result_dialog.temp(False): - self.compute_1_to_0(feature.function, param, edit=False, target_objs=[obj]) + result = self.compute_1_to_0( + feature.function, param, edit=False, target_objs=[obj] + ) + return result is not None and result.execution_success def _compute_1_to_1_subroutine( self, funcs: list[Callable], params: list, title: str @@ -1960,14 +1972,15 @@ def compute_1_to_0( comment: str | None = None, edit: bool | None = None, target_objs: list[SignalObj | ImageObj] | None = None, - ) -> ResultData: + ) -> ResultData | None: """Generic processing method: 1 object in → no object out. Applies a function to each selected object (or specified target objects), returning metadata or measurement results (e.g. peak coordinates, statistical properties) without generating new objects. Results are stored in the object's metadata and returned as a - ResultData instance. + ResultData instance, or None if parameter editing is cancelled or + preprocessing fails. Args: func: Function to execute, that takes either `(obj)` or `(obj, param)` as @@ -1982,7 +1995,8 @@ def compute_1_to_0( processes all currently selected objects. Returns: - ResultData instance containing the results for all processed objects. + ResultData instance containing the results for all processed objects, + or None if the operation is cancelled or cannot be prepared. .. note:: With k selected objects, the method performs k analyses and produces @@ -2028,46 +2042,53 @@ def compute_1_to_0( # Execute function compout = self.__exec_func(func, args, progress) if compout is None: + rdata.execution_success = False break result = self.handle_output( compout, _("Computing: %s") % title, progress ) if result is None: + rdata.execution_success = False continue - # Using the adapters: - if isinstance(result, GeometryResult): - adapter = GeometryAdapter(result) - elif isinstance(result, TableResult): - adapter = TableAdapter(result) - else: - # For "compute 1 to 0" functions, the result is either a - # GeometryResult or TableResult: - raise TypeError("Unsupported result type") - - # Add result shape to object's metadata - # Pass function name for better parameter context in the Analysis tab - adapter.add_to(obj, param) - - # Store analysis parameters to enable on-demand recomputation - # via the manual "Recompute" action. - # Analysis parameters (1-to-0) are stored separately from - # transformation history to avoid overwriting the processing chain - # when analyzing objects. - pp = ProcessingParameters( - func_name=func.__name__, - pattern="1-to-0", - param=param, - source_uuid=get_uuid(obj), - plugin_origin=self._get_plugin_origin_for(func), - ) - insert_processing_parameters(obj, pp) + metadata_snapshot = copy.deepcopy(obj.metadata) + result_count = len(rdata.results) + ylabel_count = len(rdata.ylabels) + short_id_count = len(rdata.short_ids) - # Apply processor-specific post-processing on the result - refresh_needed |= self.postprocess_1_to_0_result(obj, result) + def persist_result() -> bool: + if isinstance(result, GeometryResult): + adapter = GeometryAdapter(result) + elif isinstance(result, TableResult): + adapter = TableAdapter(result) + else: + raise TypeError("Unsupported result type") - # Append result to result data for later display - rdata.append(adapter, obj) + adapter.add_to(obj, param) + pp = ProcessingParameters( + func_name=func.__name__, + pattern="1-to-0", + param=param, + source_uuid=get_uuid(obj), + plugin_origin=self._get_plugin_origin_for(func), + ) + insert_processing_parameters(obj, pp) + result_modified = self.postprocess_1_to_0_result(obj, result) + rdata.append(adapter, obj) + return result_modified + + persistence_output = wng_err_func(persist_result, ()) + result_modified = self.handle_output( + persistence_output, _("Computing: %s") % title, progress + ) + if result_modified is None: + obj.metadata = metadata_snapshot + del rdata.results[result_count:] + del rdata.ylabels[ylabel_count:] + del rdata.short_ids[short_id_count:] + rdata.execution_success = False + continue + refresh_needed |= result_modified if obj is current_obj: # Mark object as having fresh analysis results to show Analysis tab diff --git a/datalab/history/action.py b/datalab/history/action.py index a67a108d7..5c9f05c4b 100644 --- a/datalab/history/action.py +++ b/datalab/history/action.py @@ -548,10 +548,18 @@ def replay_compute( ) panel = self.resolve_panel(mainwindow) processor = panel.processor - feature = processor.get_feature(self.func_name) + param = self.kwargs.get("param") + params = self.kwargs.get("params") or [] + paramclass_name = type(param).__name__ if param is not None else None + if self.pattern == "1_to_n" and params: + paramclass_name = type(params[0]).__name__ + feature = processor.get_feature( + self.func_name, + plugin_origin=self.plugin_origin, + paramclass_name=paramclass_name, + ) run_kwargs: dict[str, Any] = {self.FUNC_EDIT_MODE: edit} - param = self.kwargs.get("param") if self.pattern in {"1_to_1", "1_to_0", "n_to_1"}: if param is not None: run_kwargs["param"] = param @@ -582,7 +590,6 @@ def replay_compute( if "pairwise" in self.kwargs: run_kwargs["pairwise"] = self.kwargs["pairwise"] elif self.pattern == "1_to_n": - params = self.kwargs.get("params") or [] run_kwargs["params"] = params else: raise ValueError(f"Unknown compute pattern: {self.pattern!r}") diff --git a/datalab/locale/fr/LC_MESSAGES/datalab.po b/datalab/locale/fr/LC_MESSAGES/datalab.po index 2498d0e41..376d52e88 100644 --- a/datalab/locale/fr/LC_MESSAGES/datalab.po +++ b/datalab/locale/fr/LC_MESSAGES/datalab.po @@ -1299,7 +1299,7 @@ msgstr "Ouvrir %d fichiers HDF5" msgid "Open HDF5 file" msgstr "Ouvrir un fichier HDF5" -#, fuzzy, python-format +#, python-format msgid "New %s" msgstr "Créer un nouvel objet %s" @@ -1466,6 +1466,9 @@ msgstr "" "Échec du recalcul de l'analyse :\n" "%s" +msgid "Failed to recompute analysis." +msgstr "Échec du recalcul de l'analyse." + msgid "Analysis was recomputed." msgstr "L'analyse a été recalculée." @@ -1501,6 +1504,9 @@ msgstr "Le signal a été retraité." msgid "Image was reprocessed." msgstr "L'image a été retraitée." +msgid "Failed to reprocess object." +msgstr "Échec du retraitement de l'objet." + msgid "Geometry results" msgstr "Résultats géométriques" @@ -1674,6 +1680,12 @@ msgstr "Échec du retraitement de l'objet" msgid "Do you want to continue with the next object?" msgstr "Souhaitez-vous continuer avec l'objet suivant ?" +msgid "Analysis computation failed." +msgstr "Le calcul de l'analyse a échoué." + +msgid "Failed to recompute analysis" +msgstr "Échec du recalcul de l'analyse" + msgid "Selected object does not have processing metadata." msgstr "L'objet sélectionné n'a pas de métadonnées de traitement." @@ -1762,6 +1774,14 @@ msgstr "Panneau d'historique" msgid "History files" msgstr "Fichiers d'historique" +#, python-format +msgid "Action %s could not be fully recomputed." +msgstr "L'action %s n'a pas pu être entièrement recalculée." + +#, python-format +msgid "Action %s: recompute returned %d output(s), expected %d." +msgstr "Action %s : le recalcul a renvoyé %d sortie(s), %d attendue(s)." + msgid "Record mode" msgstr "Mode d'enregistrement" @@ -1857,10 +1877,6 @@ msgstr "" msgid "Action %s: source object was deleted — skipping." msgstr "Action %s : l'objet source a été supprimé — ignorée." -#, python-format -msgid "Action %s: all source objects were deleted — skipping." -msgstr "Action %s : tous les objets source ont été supprimés — ignorée." - #, python-format msgid "Action %s: missing source(s) for output #%d — skipping." msgstr "Action %s : source(s) manquante(s) pour la sortie n°%d — ignorée." diff --git a/datalab/tests/features/common/history_workflow_test.py b/datalab/tests/features/common/history_workflow_test.py index 464639e44..1a35ab1b4 100644 --- a/datalab/tests/features/common/history_workflow_test.py +++ b/datalab/tests/features/common/history_workflow_test.py @@ -6,6 +6,7 @@ import os import tempfile +from types import SimpleNamespace from unittest.mock import patch import numpy as np @@ -13,10 +14,22 @@ import sigima.proc.signal as sips from sigima.tests.data import create_paracetamol_signal +from datalab.adapters_metadata.common import ResultData from datalab.gui import historytools_ops as htools from datalab.gui.panel.history import HistoryAction -from datalab.gui.panel.history.chainmodel import build_session_chains -from datalab.gui.processor.base import extract_processing_parameters +from datalab.gui.panel.history import interactive_replay as hireplay +from datalab.gui.panel.history import recompute as hrec +from datalab.gui.panel.history.chainmodel import ( + build_session_chains, + remap_processing_parameters, +) +from datalab.gui.processor.base import ( + ProcessingParameters, + extract_analysis_parameters, + extract_processing_parameters, + insert_processing_parameters, +) +from datalab.gui.processor.catcher import CompOut from datalab.h5.native import NativeH5Reader, NativeH5Writer from datalab.objectmodel import get_uuid from datalab.tests import datalab_test_app_context @@ -52,6 +65,42 @@ def assert_duplicate_head(history, panel, session) -> None: assert clone_uuid in panel.objmodel.get_object_ids() +def build_independent_signal_branch(panel, history) -> tuple[HistoryAction, ...]: + """Build a three-action branch using UUID-based selections.""" + source_uuid = add_paracetamol_signals(panel, 1)[0] + panel.objview.select_objects([source_uuid]) + panel.processor.run_feature( + sips.gaussian_filter, sigima.params.GaussianParam.create(sigma=1.5) + ) + first_action = history[len(history)] + panel.objview.select_objects(first_action.output_uuids) + panel.processor.run_feature(sips.derivative) + second_action = history[len(history)] + panel.objview.select_objects(second_action.output_uuids) + panel.processor.run_feature( + sips.moving_average, sigima.params.MovingAverageParam.create(n=3) + ) + return first_action, second_action, history[len(history)] + + +def test_remap_processing_parameters_preserves_plugin_origin() -> None: + """Preserve plugin provenance while remapping processing source UUIDs.""" + plugin_origin = {"module": "test_plugin.operations", "directory": "test_plugin"} + parameters = ProcessingParameters( + func_name="difference", + pattern="2-to-1", + source_uuids=["source-1", "source-2"], + plugin_origin=plugin_origin, + ) + + remapped = remap_processing_parameters( + parameters, {"source-1": "copy-1", "source-2": "copy-2"} + ) + + assert remapped.source_uuids == ["copy-1", "copy-2"] + assert remapped.plugin_origin == plugin_origin + + def test_history_recording_contract_and_output_index() -> None: """Record producing patterns and index every output without replay entries.""" with datalab_test_app_context(history=True) as win: @@ -129,6 +178,65 @@ def test_analysis_replay_requires_explicit_edit() -> None: run_feature.assert_called_once() +def test_replay_resolves_feature_with_plugin_origin_and_paramclass() -> None: + """Resolve replayed features with their plugin and parameter identities.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + add_paracetamol_signals(panel, 1) + panel.objview.select_objects([1]) + param = sigima.params.GaussianParam.create(sigma=1.5) + panel.processor.run_feature(sips.gaussian_filter, param) + action = history[len(history)] + plugin_origin = { + "module": "test_plugin.operations", + "directory": "test_plugin", + } + action.plugin_origin = plugin_origin + + with patch.object( + panel.processor, "get_feature", wraps=panel.processor.get_feature + ) as get_feature: + action.replay(win, restore_selection=True, edit=False) + + get_feature.assert_called_once_with( + action.func_name, + plugin_origin=plugin_origin, + paramclass_name=type(param).__name__, + ) + + +def test_replay_1_to_n_resolves_feature_with_first_paramclass() -> None: + """Resolve a 1-to-n feature with the first stored parameter identity.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + add_paracetamol_signals(panel, 1) + panel.objview.select_objects([1]) + params = [sigima.params.GaussianParam.create(sigma=1.5)] + action = HistoryAction() + action.kind = HistoryAction.KIND_COMPUTE + action.pattern = "1_to_n" + action.target = "signalpanel" + action.panel_str = "signal" + action.func_name = sips.gaussian_filter.__name__ + action.kwargs = {"params": params} + + with ( + patch.object( + panel.processor, "get_feature", return_value=sips.gaussian_filter + ) as get_feature, + patch.object(panel.processor, "run_feature"), + ): + action.replay_compute(win, edit=False) + + get_feature.assert_called_once_with( + action.func_name, + plugin_origin=None, + paramclass_name=type(params[0]).__name__, + ) + + def test_history_hdf5_pristine_load_and_nonempty_import() -> None: """Distinguish pristine loading, non-empty import and missing history.""" with tempfile.TemporaryDirectory() as tmpdir: @@ -241,12 +349,30 @@ def test_edit_cascade_preserves_identity_and_action_state() -> None: history.toggle_record_mode(True) history.toggle_edit_mode(True) chain = build_signal_chain(panel, history) - root_action, _middle_action, leaf_action = chain.actions - root_output, _middle_output, leaf_output = chain.outputs + root_action, middle_action, leaf_action = chain.actions + root_output, middle_output, leaf_output = chain.outputs + plugin_origin = { + "module": "test_plugin.operations", + "directory": "test_plugin", + } + middle_action.plugin_origin = plugin_origin + leaf_action.plugin_origin = plugin_origin panel.objview.select_objects([leaf_output]) panel.processor.run_feature(sips.stats) analysis_action = history[len(history)] assert analysis_action.pattern == "1_to_0" + middle_parameters = extract_processing_parameters(middle_output) + assert middle_parameters is not None + middle_parameters.plugin_origin = plugin_origin + insert_processing_parameters(middle_output, middle_parameters) + middle_action.plugin_origin = None + analysis_action.plugin_origin = None + analysis_parameters = extract_analysis_parameters(leaf_output) + assert analysis_parameters is not None + analysis_parameters.plugin_origin = plugin_origin + leaf_output.set_metadata_option( + "analysis_parameters", analysis_parameters.to_dict() + ) leaf_uuid = get_uuid(leaf_output) leaf_number = panel.objmodel.get_number(leaf_output) leaf_data = leaf_output.xydata.copy() @@ -265,12 +391,17 @@ def test_edit_cascade_preserves_identity_and_action_state() -> None: root_output, interactive=False ) recompute_analysis.assert_called_once() + assert recompute_analysis.call_args.kwargs["plugin_origin"] == plugin_origin assert report.success and root_action.has_pending_edits assert root_action.kwargs["param"].sigma == 7.0 assert get_uuid(panel.objmodel[leaf_uuid]) == leaf_uuid assert panel.objmodel.get_number(panel.objmodel[leaf_uuid]) == leaf_number assert panel.objmodel[leaf_uuid].metadata["user_marker"] == 123 assert not np.array_equal(panel.objmodel[leaf_uuid].xydata, leaf_data) + for output in (middle_output, leaf_output): + parameters = extract_processing_parameters(output) + assert parameters is not None + assert parameters.plugin_origin == plugin_origin with tempfile.TemporaryDirectory() as tmpdir: path = os.path.join(tmpdir, "edited.dlhist") assert history.save_to_dlhist_file(path) @@ -287,6 +418,527 @@ def test_edit_cascade_preserves_identity_and_action_state() -> None: assert leaf_action.is_stale is False +def test_edit_cascade_stops_after_failed_descendant() -> None: + """Keep a failed action and unexecuted analysis stale after cascade failure.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + add_paracetamol_signals(panel, 1) + panel.objview.select_objects([1]) + panel.processor.run_feature( + sips.gaussian_filter, sigima.params.GaussianParam.create(sigma=1.5) + ) + first_action = history[len(history)] + panel.objview.select_objects([2]) + panel.processor.run_feature(sips.derivative) + failed_action = history[len(history)] + failed_output = panel.objmodel[failed_action.output_uuids[0]] + failed_data = failed_output.xydata.copy() + panel.objview.select_objects([failed_action.output_uuids[0]]) + panel.processor.run_feature(sips.stats) + analysis_action = history[len(history)] + first_action.is_stale = True + original_recompute = panel.processor.recompute_1_to_1 + call_count = 0 + + def fail_second_recompute(*args, **kwargs): + nonlocal call_count + call_count += 1 + if call_count == 2: + return CompOut(error_msg="expected cascade failure") + return original_recompute(*args, **kwargs) + + with ( + patch.object( + panel.processor, + "recompute_1_to_1", + side_effect=fail_second_recompute, + ), + patch.object(panel.processor, "recompute_1_to_0") as recompute_analysis, + ): + history.recompute_cascade(first_action) + + recompute_analysis.assert_not_called() + assert first_action.is_stale is False + assert failed_action.is_stale is True + assert analysis_action.is_stale is True + assert np.array_equal(failed_output.xydata, failed_data) + + +def test_multi_action_edit_recomputes_selected_descendants_once() -> None: + """Recompute selected ancestors and their analysis descendant exactly once.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + history.toggle_edit_mode(True) + chain = build_signal_chain(panel, history) + panel.objview.select_objects([chain.outputs[-1]]) + panel.processor.run_feature(sips.stats) + analysis_action = history[len(history)] + selected = [chain.actions[0], chain.actions[1]] + expected = [*chain.actions, analysis_action] + + with ( + patch.object( + hireplay, "prompt_edit_action_params", return_value=True + ) as prompt, + patch.object( + hrec, "recompute_action_in_place", return_value=True + ) as recompute, + ): + hireplay.edit_mode_replay_actions(history, selected) + + assert [call.args[1] for call in prompt.call_args_list] == selected + assert [call.args[1] for call in recompute.call_args_list] == expected + assert all(action.is_stale is False for action in expected) + + +def test_multi_action_edit_cascades_across_independent_sessions() -> None: + """Recompute edited branches from multiple sessions in global order.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + history.toggle_edit_mode(True) + first_chain = build_independent_signal_branch(panel, history) + history.create_new_session(panel_str="signal") + second_chain = build_independent_signal_branch(panel, history) + selected = [second_chain[0], first_chain[0]] + expected = [*first_chain, *second_chain] + + with ( + patch.object(hireplay, "prompt_edit_action_params", return_value=True), + patch.object( + hrec, "recompute_action_in_place", return_value=True + ) as recompute, + ): + hireplay.edit_mode_replay_actions(history, selected) + + assert [call.args[1] for call in recompute.call_args_list] == expected + assert all(action.is_stale is False for action in expected) + + +def test_multi_action_edit_failure_skips_dependents_and_continues() -> None: + """Leave a failed branch stale while recomputing an independent session.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + history.toggle_edit_mode(True) + failed_chain = build_independent_signal_branch(panel, history) + history.create_new_session(panel_str="signal") + successful_chain = build_independent_signal_branch(panel, history) + failed_root = failed_chain[0] + recomputed: list[HistoryAction] = [] + + def recompute_action(_panel, action): + recomputed.append(action) + return action is not failed_root + + with ( + patch.object(hireplay, "prompt_edit_action_params", return_value=True), + patch.object( + hrec, "recompute_action_in_place", side_effect=recompute_action + ), + ): + hireplay.edit_mode_replay_actions( + history, [failed_root, successful_chain[0]] + ) + + assert recomputed == [failed_root, *successful_chain] + assert all(action.is_stale is True for action in failed_chain) + assert all(action.is_stale is False for action in successful_chain) + + +def test_multi_action_edit_cancel_restores_entry_pending_edit() -> None: + """Restore current kwargs and their saved baseline after a later cancel.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + history.toggle_edit_mode(True) + first_action, second_action = build_signal_chain(panel, history).actions[:2] + first_action.snapshot_kwargs() + first_action.kwargs["param"].sigma = 2.5 + + def prompt(_panel, action): + if action is first_action: + action.kwargs["param"].sigma = 3.5 + return True + return False + + with patch.object(hireplay, "prompt_edit_action_params", side_effect=prompt): + hireplay.edit_mode_replay_actions(history, [first_action, second_action]) + + assert first_action.kwargs["param"].sigma == 2.5 + assert first_action.saved_kwargs["param"].sigma == 1.5 + + +def test_multi_action_edit_cancel_skips_deferred_ui_replay() -> None: + """Do not replay noncompute UI actions when a later dialog is cancelled.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + history.toggle_edit_mode(True) + compute_action = build_signal_chain(panel, history).actions[0] + ui_action = HistoryAction( + title="Select next", + kind=HistoryAction.KIND_UI, + target="signalpanel", + method_name="select_next", + ) + + with ( + patch.object(ui_action, "replay") as replay, + patch.object(hireplay, "prompt_edit_action_params", return_value=False), + ): + hireplay.edit_mode_replay_actions(history, [ui_action, compute_action]) + + replay.assert_not_called() + + +def test_multi_action_edit_preserves_mixed_ui_compute_order() -> None: + """Execute deferred UI and planned compute actions in global session order.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + history.toggle_edit_mode(True) + source_uuid = add_paracetamol_signals(panel, 1)[0] + panel.objview.select_objects([source_uuid]) + panel.processor.run_feature(sips.derivative) + first_compute = history[len(history)] + ui_action = history.add_ui_entry("Select next", "signalpanel", "select_next") + assert ui_action is not None + panel.objview.select_objects(first_compute.output_uuids) + panel.processor.run_feature(sips.derivative) + second_compute = history[len(history)] + execution_order = [] + + def recompute(_panel, action): + execution_order.append(action) + return True + + def replay_ui(*_args, **_kwargs): + execution_order.append(ui_action) + + with ( + patch.object(hireplay, "prompt_edit_action_params", return_value=True), + patch.object(hrec, "recompute_action_in_place", side_effect=recompute), + patch.object(ui_action, "replay", side_effect=replay_ui), + ): + hireplay.edit_mode_replay_actions(history, [first_compute, ui_action]) + + assert execution_order == [first_compute, ui_action, second_compute] + + +def test_multi_action_edit_flushes_cascade_warnings_once() -> None: + """Flush warnings exactly once after executing a custom replay plan.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + history.toggle_edit_mode(True) + action = build_signal_chain(panel, history).actions[0] + + def recompute(_panel, _action): + history.runtime.execution.cascade_warnings.append("expected warning") + return True + + with ( + patch.object(hireplay, "prompt_edit_action_params", return_value=True), + patch.object(hrec, "recompute_action_in_place", side_effect=recompute), + patch.object( + hrec, + "flush_cascade_warnings", + wraps=hrec.flush_cascade_warnings, + ) as flush, + ): + hireplay.edit_mode_replay_actions(history, [action]) + + flush.assert_called_once_with(history) + assert history.runtime.execution.cascade_warnings == [] + + +def test_restore_failure_marks_action_stale_without_cascade() -> None: + """Stop restore recomputation when its root action fails.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + action = build_signal_chain(panel, history).actions[0] + action.snapshot_kwargs() + action.kwargs["param"].sigma = 7.0 + + with ( + patch.object(hrec, "recompute_action_in_place", return_value=False), + patch.object(hrec, "recompute_cascade") as recompute_cascade, + ): + hireplay.restore_action_params(history, action) + + recompute_cascade.assert_not_called() + assert action.is_stale is True + + +def test_empty_analysis_result_is_successful() -> None: + """Treat an executed analysis with no detections as successful.""" + with datalab_test_app_context(history=True) as win: + panel = win.signalpanel + panel.new_object(edit=False) + signal = panel.objview.get_current_object() + assert signal is not None + + with patch.object(panel.processor, "compute_1_to_0", return_value=ResultData()): + success = panel.processor.recompute_1_to_0("stats", signal) + + assert success is True + + +def test_legacy_resultdata_defaults_execution_success() -> None: + """Use the dataclass default when legacy state lacks execution_success.""" + result = ResultData() + del result.__dict__["execution_success"] + + assert result.execution_success is True + + +def test_2_to_1_failure_does_not_partially_mutate_outputs() -> None: + """Stage every pairwise result before mutating existing outputs.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + add_paracetamol_signals(panel, 4) + actions = [] + for first, second in ((1, 2), (3, 4)): + panel.objview.select_objects([first]) + panel.processor.run_feature( + sips.difference, panel.objmodel.get_object_from_number(second) + ) + actions.append(history[len(history)]) + action = actions[0] + action.output_uuids.extend(actions[1].output_uuids) + history.runtime.objects.action_output_uuids[action.uuid] = list( + action.output_uuids + ) + outputs = [panel.objmodel[uuid] for uuid in action.output_uuids] + original_data = [obj.xydata.copy() for obj in outputs] + staged_result = outputs[0].copy() + staged_result.xydata = staged_result.xydata * 0.0 + + with patch.object( + panel.processor, + "recompute_2_to_1", + side_effect=[staged_result, None], + ): + success = hrec.recompute_action_in_place(history, action) + + assert success is False + for output, data in zip(outputs, original_data): + assert np.array_equal(output.xydata, data) + + +def test_2_to_1_refresh_failure_rolls_back_and_resyncs_outputs() -> None: + """Refresh only after commit and resync every target after rollback.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + add_paracetamol_signals(panel, 4) + actions = [] + for first, second in ((1, 2), (3, 4)): + panel.objview.select_objects([first]) + panel.processor.run_feature( + sips.difference, panel.objmodel.get_object_from_number(second) + ) + actions.append(history[len(history)]) + action = actions[0] + action.output_uuids.extend(actions[1].output_uuids) + history.runtime.objects.action_output_uuids[action.uuid] = list( + action.output_uuids + ) + outputs = [panel.objmodel[uuid] for uuid in action.output_uuids] + identities = [id(obj) for obj in outputs] + original_titles = [obj.title for obj in outputs] + original_data = [obj.xydata.copy() for obj in outputs] + original_metadata = [obj.metadata.copy() for obj in outputs] + original_sources = [ + extract_processing_parameters(obj).source_uuids for obj in outputs + ] + staged_results = [obj.copy() for obj in outputs] + staged_titles = [] + for index, result in enumerate(staged_results): + result.title = f"staged-{index}" + staged_titles.append(result.title) + result.xydata = result.xydata * 0.0 + refresh_effects = [] + + def refresh_with_failure(_panel, output_uuid): + refresh_effects.append( + ( + output_uuid, + [obj.title for obj in outputs], + [ + extract_processing_parameters(obj).source_uuids + for obj in outputs + ], + ) + ) + if len(refresh_effects) in (2, 3): + raise RuntimeError(f"refresh failed #{len(refresh_effects)}") + + with ( + patch.object( + panel.processor, + "recompute_2_to_1", + side_effect=staged_results, + ), + patch.object( + hrec, + "refresh_target", + side_effect=refresh_with_failure, + ), + ): + success = hrec.recompute_action_in_place(history, action) + + assert success is False + assert [effect[0] for effect in refresh_effects] == [ + action.output_uuids[0], + action.output_uuids[1], + action.output_uuids[0], + action.output_uuids[1], + ] + assert refresh_effects[0][1] == staged_titles + assert refresh_effects[0][2] == original_sources + assert refresh_effects[2][1] == original_titles + for index, output in enumerate(outputs): + assert id(output) == identities[index] + assert output.title == original_titles[index] + assert np.array_equal(output.xydata, original_data[index]) + assert output.metadata == original_metadata[index] + + +def test_1_to_n_refresh_failure_rolls_back_and_resyncs_outputs() -> None: + """Commit all 1-to-n outputs before refresh and fully roll back on failure.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + source_uuid = add_paracetamol_signals(panel, 1)[0] + actions = [] + for _index in range(2): + panel.objview.select_objects([source_uuid]) + panel.processor.run_feature(sips.derivative) + actions.append(history[len(history)]) + action = actions[0] + action.pattern = "1_to_n" + action.kwargs = { + "params": [ + sigima.params.GaussianParam.create(sigma=1.5), + sigima.params.GaussianParam.create(sigma=2.5), + ] + } + action.output_uuids.extend(actions[1].output_uuids) + history.runtime.objects.action_output_uuids[action.uuid] = list( + action.output_uuids + ) + outputs = [panel.objmodel[uuid] for uuid in action.output_uuids] + identities = [id(obj) for obj in outputs] + original_titles = [obj.title for obj in outputs] + original_data = [obj.xydata.copy() for obj in outputs] + original_metadata = [obj.metadata.copy() for obj in outputs] + staged_results = [obj.copy() for obj in outputs] + staged_titles = [] + for index, result in enumerate(staged_results): + result.title = f"staged-{index}" + staged_titles.append(result.title) + result.xydata = result.xydata * 0.0 + refresh_effects = [] + + def refresh_with_failure(_panel, output_uuid): + refresh_effects.append((output_uuid, [obj.title for obj in outputs])) + if len(refresh_effects) in (2, 3): + raise RuntimeError(f"refresh failed #{len(refresh_effects)}") + + with ( + patch.object( + panel.processor, + "recompute_1_to_n", + return_value=staged_results, + ), + patch.object(hrec, "refresh_target", side_effect=refresh_with_failure), + ): + success = hrec.recompute_action_in_place(history, action) + + assert success is False + assert [effect[0] for effect in refresh_effects] == [ + action.output_uuids[0], + action.output_uuids[1], + action.output_uuids[0], + action.output_uuids[1], + ] + assert refresh_effects[0][1] == staged_titles + assert refresh_effects[2][1] == original_titles + for index, output in enumerate(outputs): + assert id(output) == identities[index] + assert output.title == original_titles[index] + assert np.array_equal(output.xydata, original_data[index]) + assert output.metadata == original_metadata[index] + + +def test_1_to_0_failure_rolls_back_all_source_metadata() -> None: + """Restore every analysis source when a later recomputation fails.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + source_uuids = add_paracetamol_signals(panel, 2) + panel.objview.select_objects([1, 2]) + panel.processor.run_feature(sips.stats) + action = history[len(history)] + sources = [panel.objmodel[uuid] for uuid in source_uuids] + for index, source in enumerate(sources): + source.metadata["user_marker"] = index + + call_count = 0 + + def fail_second_analysis(_func_name, source, _param, plugin_origin=None): + del plugin_origin + nonlocal call_count + call_count += 1 + source.metadata["temporary_analysis"] = call_count + return call_count == 1 + + with patch.object( + panel.processor, + "recompute_1_to_0", + side_effect=fail_second_analysis, + ): + success = hrec.recompute_action_in_place(history, action) + + assert success is False + for index, source in enumerate(sources): + assert source.metadata["user_marker"] == index + assert "temporary_analysis" not in source.metadata + + +def test_1_to_0_cascade_uses_roi_safe_parameter_copy() -> None: + """Disable ROI creation on a copy during analysis cascade recomputation.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + source_uuid = add_paracetamol_signals(panel, 1)[0] + param = SimpleNamespace(create_rois=True) + action = HistoryAction() + action.kind = HistoryAction.KIND_COMPUTE + action.pattern = "1_to_0" + action.target = "signalpanel" + action.panel_str = "signal" + action.func_name = "analysis" + action.kwargs = {"param": param} + action.state.selection = {panel.PANEL_STR_ID: [source_uuid]} + + with patch.object( + panel.processor, "recompute_1_to_0", return_value=True + ) as recompute: + success = hrec.recompute_action_in_place(history, action) + + assert success is True + passed_param = recompute.call_args.args[2] + assert passed_param is not param + assert passed_param.create_rois is False + assert action.kwargs["param"].create_rois is True + + def test_deletion_reconnects_and_splices_chain() -> None: """Reconnect after data deletion, then splice the producing action.""" with datalab_test_app_context(history=True) as win: diff --git a/datalab/tests/features/common/interactive_processing_test.py b/datalab/tests/features/common/interactive_processing_test.py index 447d8ec27..bd84ad34a 100644 --- a/datalab/tests/features/common/interactive_processing_test.py +++ b/datalab/tests/features/common/interactive_processing_test.py @@ -36,15 +36,17 @@ ) from sigima.proc.image import RadialProfileParam +from datalab.adapters_metadata.common import ResultData from datalab.env import execenv from datalab.gui.newobject import CREATION_PARAMETERS_OPTION from datalab.gui.processor.base import ( PROCESSING_PARAMETERS_OPTION, + _detect_plugin_origin, extract_analysis_parameters, extract_processing_parameters, ) from datalab.gui.processor.catcher import CompOut -from datalab.objectmodel import get_uuid +from datalab.objectmodel import get_short_id, get_uuid from datalab.tests import datalab_test_app_context @@ -291,6 +293,100 @@ def record_recompute_1_to_0(*args, **kwargs): assert kwargs["plugin_origin"] == plugin_origin +def test_wrapped_plugin_origin_uses_inner_callable_file() -> None: + """Use the origin candidate for both module and directory detection.""" + + def plugin_function(): + pass + + plugin_function.__module__ = "wrapped_plugin.operations" + + def wrapper(): + pass + + wrapper.__module__ = "datalab.gui.processor.base" + wrapper.__wrapped__ = plugin_function + + with ( + patch("datalab.plugins.PluginRegistry.get_plugins", return_value=[]), + patch( + "datalab.gui.processor.base.inspect.getfile", + return_value="/plugins/wrapped_plugin/operations.py", + ) as getfile, + ): + origin = _detect_plugin_origin(wrapper) + + assert origin is not None + assert origin["module"] == "wrapped_plugin.operations" + assert origin["directory"] == "wrapped_plugin" + getfile.assert_called_once_with(plugin_function) + + +def test_analysis_persistence_failure_is_isolated_per_object() -> None: + """Roll back one failed analysis and continue with the next object.""" + with qt_app_context(): + with datalab_test_app_context() as win: + panel = win.signalpanel + processor = panel.processor + panel.new_object(edit=False) + first = panel.objview.get_current_object() + panel.new_object(edit=False) + second = panel.objview.get_current_object() + assert first is not None and second is not None + first.metadata["existing"] = {"value": 1} + first_metadata = first.metadata.copy() + appended = [] + first_append_lengths = None + original_append = ResultData.append + + def fail_after_first_append(rdata, adapter, obj): + nonlocal first_append_lengths + original_append(rdata, adapter, obj) + appended.append((adapter, obj)) + if obj is first: + first_append_lengths = ( + len(rdata.results), + len(rdata.ylabels), + len(rdata.short_ids), + ) + raise RuntimeError("Expected persistence error") + + stats_func = processor.get_feature("stats").function + with ( + execenv.context(catcher_test=True), + patch.object( + ResultData, + "append", + new=fail_after_first_append, + ), + patch("datalab.gui.processor.base.show_warning_error") as show_error, + ): + result = processor.compute_1_to_0( + stats_func, + edit=False, + target_objs=[first, second], + ) + + assert result is not None + assert result.execution_success is False + assert [obj for _adapter, obj in appended] == [first, second] + assert first_append_lengths is not None + assert all(count > 0 for count in first_append_lengths) + assert first.metadata == first_metadata + assert extract_analysis_parameters(first) is None + assert extract_analysis_parameters(second) is not None + second_adapter = appended[1][0] + second_short_id = get_short_id(second) + assert result.results == [second_adapter] + assert result.ylabels == [f"{second_adapter.func_name}({second_short_id})"] + assert result.short_ids == [second_short_id] + error_calls = [ + call for call in show_error.call_args_list if call.args[1] == "error" + ] + assert len(error_calls) == 1 + assert "Expected persistence error" in error_calls[0].args[3] + + def test_recompute_selected_continues_after_1_to_1_error(): """Test that an ordinary 1-to-1 error is not treated as cancellation.""" with qt_app_context(): @@ -324,6 +420,7 @@ def recompute_1_to_1_with_first_error( def record_recompute_analysis(obj, *args, **kwargs): analysis_objects.append(obj) + return True processor.recompute_1_to_1 = recompute_1_to_1_with_first_error processor.recompute_analysis = record_recompute_analysis @@ -346,6 +443,60 @@ def record_recompute_analysis(obj, *args, **kwargs): assert analysis_objects == [processed_images[1]] +def test_apply_analysis_parameters_failure_preserves_action() -> None: + """Do not record or announce a failed direct analysis recomputation.""" + with qt_app_context(): + with datalab_test_app_context(history=True) as win: + panel = win.signalpanel + history = win.historypanel + history.toggle_record_mode(True) + panel.new_object(edit=False) + signal = panel.objview.get_current_object() + assert signal is not None + panel.processor.run_feature("stats") + action = history[len(history)] + original_kwargs = action.kwargs.copy() + status_messages = [] + panel.SIG_STATUS_MESSAGE.connect(status_messages.append) + + with patch.object(panel.processor, "recompute_1_to_0", return_value=False): + success = panel.objprop.apply_analysis_parameters( + signal, interactive=False + ) + + assert success is False + assert action.kwargs == original_kwargs + assert status_messages == [] + + +def test_recompute_analyses_continues_after_failure_unattended() -> None: + """Continue with later analyses after an unattended object failure.""" + with qt_app_context(): + with datalab_test_app_context() as win: + panel = win.signalpanel + panel.new_object(edit=False) + first = panel.objview.get_current_object() + panel.new_object(edit=False) + second = panel.objview.get_current_object() + assert first is not None and second is not None + + with ( + execenv.context(unattended=True), + patch.object( + panel.processor, + "recompute_analysis", + side_effect=[False, True], + ) as recompute_analysis, + ): + recomputed, interrupted = panel.recompute_1_to_0_objects( + [first, second] + ) + + assert recompute_analysis.call_count == 2 + assert recomputed == {get_uuid(second)} + assert interrupted is False + + def test_apply_creation_parameters_signal(): """Test apply_creation_parameters for signals""" with qt_app_context(): From 9f836611193ac7ec4bbae0b33e88dc2c2d1d6ea3 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Mon, 3 Aug 2026 11:48:32 +0200 Subject: [PATCH 062/108] Fix: Preserve complete History edit cascades Editing a complete History session could bypass the global in-place recompute planner, while multi-output or legacy actions could lose downstream dependencies after runtime mappings were pruned. All edit selections now use one deduplicated plan with consistent output UUID resolution. * [FIX] : Expand selected sessions into actions and process overlapping selections once through the global edit planner * [FIX] : Resolve dependency closure and failed-branch blocking from durable, runtime, then legacy output UUIDs * [CHG] : Cover Qt tree selection, pruned multi-output mappings, and legacy failed branches on Python 3.9 and 3.14 --- datalab/gui/panel/history/chain.py | 23 +++-- .../gui/panel/history/interactive_replay.py | 28 +++--- .../features/common/history_workflow_test.py | 97 +++++++++++++++++++ 3 files changed, 130 insertions(+), 18 deletions(-) diff --git a/datalab/gui/panel/history/chain.py b/datalab/gui/panel/history/chain.py index fbea141b1..f767ed3bd 100644 --- a/datalab/gui/panel/history/chain.py +++ b/datalab/gui/panel/history/chain.py @@ -219,6 +219,19 @@ def action_output_uuid(panel: HistoryPanel, action: HistoryAction) -> str | None return find_output_object_uuid(panel, panel_data, action) +def recorded_action_output_uuids( + panel: HistoryPanel, action: HistoryAction +) -> list[str]: + """Return output UUIDs recorded for ``action``, preferring durable history.""" + if action.output_uuids: + return list(action.output_uuids) + runtime_outputs = panel.runtime.objects.action_output_uuids.get(action.uuid, []) + if runtime_outputs: + return list(runtime_outputs) + legacy_output = action_output_uuid(panel, action) + return [legacy_output] if legacy_output is not None else [] + + def action_consumes_any(action: HistoryAction, uuids: set[str]) -> bool: """Return True if ``action``'s input UUIDs intersect ``uuids``.""" if action.kind != HistoryAction.KIND_COMPUTE: @@ -235,10 +248,10 @@ def get_downstream_actions( current = get_session_of(panel, action) if current is None: return [] - root_out = action_output_uuid(panel, action) - if root_out is None: + root_outputs = recorded_action_output_uuids(panel, action) + if not root_outputs: return [] - closure: set[str] = {root_out} + closure: set[str] = set(root_outputs) downstream: list[HistoryAction] = [] idx = current.actions.index(action) for candidate in current.actions[idx + 1 :]: @@ -247,9 +260,7 @@ def get_downstream_actions( if not action_consumes_any(candidate, closure): continue downstream.append(candidate) - out_uuid = action_output_uuid(panel, candidate) - if out_uuid is not None: - closure.add(out_uuid) + closure.update(recorded_action_output_uuids(panel, candidate)) return downstream diff --git a/datalab/gui/panel/history/interactive_replay.py b/datalab/gui/panel/history/interactive_replay.py index 7ee0f8bfc..1477eff4f 100644 --- a/datalab/gui/panel/history/interactive_replay.py +++ b/datalab/gui/panel/history/interactive_replay.py @@ -43,9 +43,15 @@ def replay_restore_actions( if not panel.history_sessions: return selected = [panel.history_sessions[-1]] + edit_mode = panel.runtime.execution.edit_mode edit_actions: list[HistoryAction] = [] for session_or_action in selected: - if isinstance(session_or_action, HistoryAction) and session_or_action.is_stale: + if ( + replay + and not edit_mode + and isinstance(session_or_action, HistoryAction) + and session_or_action.is_stale + ): hrec.recompute_cascade(panel, session_or_action) continue if not session_or_action.is_current_state_compatible( @@ -59,22 +65,20 @@ def replay_restore_actions( ) return if replay: - if panel.runtime.execution.edit_mode and isinstance( - session_or_action, HistoryAction - ): - # Defer: edit only the selected actions, no automatic cascade - edit_actions.append(session_or_action) + if edit_mode: + if isinstance(session_or_action, HistorySession): + edit_actions.extend(session_or_action.actions) + else: + edit_actions.append(session_or_action) else: - # Scope decision: clicking a session in edit mode now replays it - # WITH parameter dialogs (view-only session replay disabled). with panel.replaying(), panel.output_suppressed(): session_or_action.replay( panel.mainwindow, restore_selection=restore_selection, - edit=panel.runtime.execution.edit_mode, + edit=edit_mode, ) elif restore_selection: - if panel.runtime.execution.edit_mode or any( + if edit_mode or any( action.has_pending_edits for session in panel.history_sessions for action in session.actions @@ -196,7 +200,7 @@ def edit_mode_replay_actions(panel: HistoryPanel, actions: list[HistoryAction]) continue if hchain.action_consumes_any(action, blocked_outputs): blocked_outputs.update( - panel.runtime.objects.action_output_uuids.get(action.uuid, []) + hchain.recorded_action_output_uuids(panel, action) ) continue success = hrec.recompute_action_in_place(panel, action) @@ -204,7 +208,7 @@ def edit_mode_replay_actions(panel: HistoryPanel, actions: list[HistoryAction]) panel.tree.refresh_action_item(action) if not success: blocked_outputs.update( - panel.runtime.objects.action_output_uuids.get(action.uuid, []) + hchain.recorded_action_output_uuids(panel, action) ) finally: hrec.flush_cascade_warnings(panel) diff --git a/datalab/tests/features/common/history_workflow_test.py b/datalab/tests/features/common/history_workflow_test.py index 1a35ab1b4..8f7255953 100644 --- a/datalab/tests/features/common/history_workflow_test.py +++ b/datalab/tests/features/common/history_workflow_test.py @@ -17,6 +17,7 @@ from datalab.adapters_metadata.common import ResultData from datalab.gui import historytools_ops as htools from datalab.gui.panel.history import HistoryAction +from datalab.gui.panel.history import chain as hchain from datalab.gui.panel.history import interactive_replay as hireplay from datalab.gui.panel.history import recompute as hrec from datalab.gui.panel.history.chainmodel import ( @@ -36,6 +37,7 @@ from datalab.tests.features.common.history_test_helpers import ( add_paracetamol_signals, build_signal_chain, + get_tree_item, read_history_sessions, select_tree_entry, select_tree_session, @@ -493,6 +495,87 @@ def test_multi_action_edit_recomputes_selected_descendants_once() -> None: assert all(action.is_stale is False for action in expected) +def test_edit_mode_selected_session_uses_global_replay_planner() -> None: + """Plan a selected session and duplicate stale action exactly once.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + history.toggle_edit_mode(True) + build_signal_chain(panel, history) + session = history.history_sessions[-1] + expected = list(session.actions) + stale_action = expected[1] + stale_action.is_stale = True + select_tree_session(history, session) + get_tree_item(history, stale_action.uuid).setSelected(True) + selected = history.tree.get_selected_actions_or_sessions( + history.history_sessions + ) + assert selected == [session, stale_action] + + with ( + patch.object(type(session), "replay") as direct_replay, + patch.object(hrec, "recompute_cascade") as direct_cascade, + patch.object( + hireplay, + "edit_mode_replay_actions", + wraps=hireplay.edit_mode_replay_actions, + ) as edit_planner, + patch.object( + hireplay, "prompt_edit_action_params", return_value=True + ) as prompt, + patch.object( + hrec, "recompute_action_in_place", return_value=True + ) as recompute, + ): + hireplay.replay_restore_actions(history) + + direct_replay.assert_not_called() + direct_cascade.assert_not_called() + edit_planner.assert_called_once_with(history, [*expected, stale_action]) + assert [call.args[1] for call in prompt.call_args_list] == expected + assert [call.args[1] for call in recompute.call_args_list] == expected + assert all(action.is_stale is False for action in expected) + + +def test_downstream_actions_follow_every_registered_output() -> None: + """Follow second registered outputs through transitive dependencies.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + producer, consumer, descendant = build_signal_chain(panel, history).actions + producer_second_output = "producer-second-output" + consumer_second_output = "consumer-second-output" + producer.output_uuids.append(producer_second_output) + consumer.output_uuids.append(consumer_second_output) + history.runtime.objects.action_output_uuids[producer.uuid] = list( + producer.output_uuids + ) + history.runtime.objects.action_output_uuids[consumer.uuid] = list( + consumer.output_uuids + ) + history.runtime.objects.output_to_action[producer_second_output] = producer.uuid + history.runtime.objects.output_to_action[consumer_second_output] = consumer.uuid + hchain.prune_output_mapping(history) + assert producer_second_output in producer.output_uuids + assert consumer_second_output in consumer.output_uuids + assert ( + producer_second_output + not in (history.runtime.objects.action_output_uuids[producer.uuid]) + ) + assert ( + consumer_second_output + not in (history.runtime.objects.action_output_uuids[consumer.uuid]) + ) + consumer.state.selection["signal"] = [producer_second_output] + descendant.state.selection["signal"] = [consumer_second_output] + + assert hchain.get_downstream_actions(history, producer) == [ + consumer, + descendant, + ] + + def test_multi_action_edit_cascades_across_independent_sessions() -> None: """Recompute edited branches from multiple sessions in global order.""" with datalab_test_app_context(history=True) as win: @@ -527,6 +610,20 @@ def test_multi_action_edit_failure_skips_dependents_and_continues() -> None: history.create_new_session(panel_str="signal") successful_chain = build_independent_signal_branch(panel, history) failed_root = failed_chain[0] + failed_output_uuid = failed_root.output_uuids[0] + failed_root.output_uuids.clear() + history.runtime.objects.action_output_uuids.pop(failed_root.uuid) + history.runtime.objects.output_to_action.pop(failed_output_uuid) + failed_output = panel.objmodel[failed_output_uuid] + processing_parameters = extract_processing_parameters(failed_output) + assert not failed_root.output_uuids + assert failed_root.uuid not in history.runtime.objects.action_output_uuids + assert failed_output_uuid not in history.runtime.objects.output_to_action + assert processing_parameters is not None + assert processing_parameters.func_name == failed_root.func_name + assert hchain.recorded_action_output_uuids(history, failed_root) == [ + failed_output_uuid + ] recomputed: list[HistoryAction] = [] def recompute_action(_panel, action): From a9838d183833a9b9d011045defc7a9d0071c89b9 Mon Sep 17 00:00:00 2001 From: Stefano Pierini <s.pierini@codra.fr> Date: Mon, 3 Aug 2026 17:55:10 +0200 Subject: [PATCH 063/108] fix: Improve file handling in BaseDataPanel to fix error when using "save signal" --- datalab/gui/panel/base.py | 42 ++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/datalab/gui/panel/base.py b/datalab/gui/panel/base.py index 6955ae276..7ff7449f2 100644 --- a/datalab/gui/panel/base.py +++ b/datalab/gui/panel/base.py @@ -2759,6 +2759,8 @@ def load_from_files( filters = self.IO_REGISTRY.get_read_filters() with save_restore_stds(): filenames, _filt = getopenfilenames(self, _("Open"), basedir, filters) + if not filenames: # pragma: no cover + return [] # Sort filenames to ensure consistent alphabetical order across all platforms filenames = sorted(filenames) nbf = len(filenames) @@ -2805,36 +2807,44 @@ def save_to_files(self, filenames: list[str] | str | None = None) -> None: filenames: File names """ objs = self.objview.get_sel_objects(include_groups=True) + if isinstance(filenames, str): + filenames = [filenames] if filenames is None: # pragma: no cover filenames = [None] * len(objs) assert len(filenames) == len(objs), ( "Number of filenames must match number of objects" ) - nbf = len(filenames) + # Ask for missing file names first, so that the history entry reflects the + # actual files written (and is skipped altogether if the user cancels) + pairs: list[tuple[TypeObj, str]] = [] + for obj, filename in zip(objs, filenames): + if filename is None: # pragma: no cover + basedir = Conf.main.base_dir.get() + filters = self.IO_REGISTRY.get_write_filters() + with save_restore_stds(): + filename, _filt = getsavefilename( + self, _("Save as"), basedir, filters + ) + if filename: + pairs.append((obj, filename)) + if not pairs: # pragma: no cover + return + nbf = len(pairs) if nbf > 1: entry_title = _("Save to %d different files") % nbf else: - entry_title = _('Save to "%s"') % osp.basename(filenames[0]) + entry_title = _('Save to "%s"') % osp.basename(pairs[0][1]) self.mainwindow.historypanel.add_ui_entry( entry_title, target=self.PANEL_STR_ID + "panel", method_name="save_to_files", save_state=False, - filenames=filenames, + filenames=[filename for _obj, filename in pairs], ) - for index, obj in enumerate(objs): - filename = filenames[index] - if filename is None: - basedir = Conf.main.base_dir.get() - filters = self.IO_REGISTRY.get_write_filters() - with save_restore_stds(): - filename, _filt = getsavefilename( - self, _("Save as"), basedir, filters - ) - if filename: - with qt_try_loadsave_file(self.parentWidget(), filename, "save"): - Conf.main.base_dir.set(filename) - self.__save_to_file(obj, filename) + for obj, filename in pairs: + with qt_try_loadsave_file(self.parentWidget(), filename, "save"): + Conf.main.base_dir.set(filename) + self.__save_to_file(obj, filename) def save_to_directory(self, param: SaveToDirectoryParam | None = None) -> None: """Save signals or images to directory using a filename pattern. From 91f57f38fa409ef72951a9a1d8a7d018352749fc Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Tue, 4 Aug 2026 15:25:35 +0200 Subject: [PATCH 064/108] Test: Verify edited image creation cascades Edited image creation needs a pure non-GUI regression contract to ensure cascade recomputation preserves existing workspace objects while propagating regenerated data to downstream processing. * [CHG] : Verify the exact edited Gauss2D parameters reach production image creation * [CHG] : Verify source identity, UUID and metadata are preserved in place * [CHG] : Verify downstream 1-to-1 processing consumes regenerated data and updates its existing output in place --- .../common/history_model_unit_test.py | 199 ++++++++++++++++++ 1 file changed, 199 insertions(+) diff --git a/datalab/tests/features/common/history_model_unit_test.py b/datalab/tests/features/common/history_model_unit_test.py index 348108336..010f0d726 100644 --- a/datalab/tests/features/common/history_model_unit_test.py +++ b/datalab/tests/features/common/history_model_unit_test.py @@ -6,11 +6,28 @@ import os import tempfile +from types import SimpleNamespace +from unittest.mock import patch +import numpy as np +from sigima.objects import Gauss2DParam, ImageObj + +from datalab.gui.creation import ( + create_image_from_param, + extract_creation_parameters, +) +from datalab.gui.panel.history import recompute as hrec +from datalab.gui.processor.base import ( + ProcessingParameters, + extract_processing_parameters, + insert_processing_parameters, +) from datalab.h5.native import NativeH5Writer from datalab.history.action import HistoryAction from datalab.history.core import HISTORY_ACTION_SCHEMA_VERSION, HISTORY_SCHEMA_VERSION from datalab.history.session import HistorySession +from datalab.history.workspace_state import WorkspaceState +from datalab.objectmodel import get_uuid, set_uuid from datalab.tests.features.common.history_test_helpers import ( build_history_action, build_replay_map, @@ -20,6 +37,25 @@ ) +class CascadeObjectModel: + """Minimal object model for pure cascade recomputation tests.""" + + def __init__(self, objects: list[ImageObj]) -> None: + self.objects = {get_uuid(obj): obj for obj in objects} + + def __getitem__(self, uuid: str) -> ImageObj: + """Return the image identified by ``uuid``.""" + return self.objects[uuid] + + def has_uuid(self, uuid: str) -> bool: + """Return whether ``uuid`` exists in the model.""" + return uuid in self.objects + + def get_object_ids(self) -> list[str]: + """Return all object UUIDs in insertion order.""" + return list(self.objects) + + def test_action_hdf5_current_and_legacy_contract() -> None: """Round-trip current fields and apply all legacy defaults.""" action = build_history_action() @@ -143,3 +179,166 @@ def test_replay_uuid_map_preserves_operands_and_tracks_changes() -> None: replay_map.capture_changes(HistoryAction(), before) assert "old-new" not in replay_map.mapping["signal"] assert image_model.get_object_ids() == ["image-old"] + + +def test_edited_image_creation_recomputes_downstream_in_place() -> None: + """Regenerate an edited image before recomputing its existing descendant.""" + initial_param = Gauss2DParam.create( + title="Initial Gaussian", + height=24, + width=28, + x0=-4.0, + y0=2.0, + sigma=1.2, + a=25.0, + ) + edited_param = Gauss2DParam.create( + title="Edited Gaussian", + height=24, + width=28, + x0=3.0, + y0=-2.0, + sigma=3.5, + a=80.0, + ) + source = create_image_from_param(initial_param) + source_uuid = get_uuid(source) + source_identity = id(source) + initial_source_data = source.data.copy() + expected_source = create_image_from_param(edited_param) + + downstream = source.copy() + set_uuid(downstream) + downstream.title = "Initial downstream" + downstream.data = np.full(source.data.shape, -1.0) + downstream_uuid = get_uuid(downstream) + downstream_identity = id(downstream) + initial_downstream_data = downstream.data.copy() + insert_processing_parameters( + downstream, + ProcessingParameters( + func_name="unit_transform", + pattern="1-to-1", + source_uuid=source_uuid, + ), + ) + + creation_action = HistoryAction( + title="Create edited Gaussian", + kind=HistoryAction.KIND_UI, + target="imagepanel", + method_name="new_object", + kwargs={"param": edited_param}, + ) + creation_action.output_uuids = [source_uuid] + downstream_state = WorkspaceState() + downstream_state.selection = {"image": [source_uuid]} + downstream_action = HistoryAction( + title="Transform edited Gaussian", + kind=HistoryAction.KIND_COMPUTE, + panel_str="image", + func_name="unit_transform", + pattern="1_to_1", + state=downstream_state, + ) + downstream_action.output_uuids = [downstream_uuid] + session = HistorySession(number=1) + session.add_action(creation_action) + session.add_action(downstream_action) + + processor_source_objects: list[ImageObj] = [] + processor_source_data: list[np.ndarray] = [] + + def recompute_1_to_1( + func_name: str | None, + source_obj: ImageObj, + param: object, + *, + plugin_origin: dict[str, object] | None, + ) -> SimpleNamespace: + assert func_name == "unit_transform" + assert param is None + assert plugin_origin is None + processor_source_objects.append(source_obj) + processor_source_data.append(source_obj.data.copy()) + new_obj = source_obj.copy() + new_obj.title = f"unit_transform({source_obj.title})" + new_obj.data = source_obj.data.astype(float) * 2.0 + 3.0 + return SimpleNamespace(cancelled=False, error_msg=None, result=new_obj) + + def apply_recomputed_object_in_place( + obj: ImageObj, + new_obj: ImageObj, + proc_params: ProcessingParameters, + ) -> None: + hrec.update_obj_in_place(obj, new_obj) + insert_processing_parameters(obj, proc_params) + + object_model = CascadeObjectModel([source, downstream]) + data_panel = SimpleNamespace( + PANEL_STR_ID="image", + objmodel=object_model, + processor=SimpleNamespace(recompute_1_to_1=recompute_1_to_1), + objprop=SimpleNamespace( + apply_recomputed_object_in_place=apply_recomputed_object_in_place + ), + ) + runtime = SimpleNamespace( + objects=SimpleNamespace( + action_output_uuids={ + creation_action.uuid: [source_uuid], + downstream_action.uuid: [downstream_uuid], + } + ), + execution=SimpleNamespace(cascade_warnings=[], broken_actions=set()), + ) + history_panel = SimpleNamespace( + runtime=runtime, + history_sessions=[session], + ) + refreshed_uuids: list[str] = [] + + def record_refresh(panel_data: object, output_uuid: str) -> None: + assert panel_data is data_panel + refreshed_uuids.append(output_uuid) + + descendants = hrec.hchain.get_downstream_actions(history_panel, creation_action) + assert descendants == [downstream_action] + + with ( + patch.object(hrec.hchain, "resolve_panel_for_action", return_value=data_panel), + patch.object( + hrec, "create_image_from_param", wraps=create_image_from_param + ) as create_image_mock, + patch.object(hrec, "refresh_target", side_effect=record_refresh), + ): + assert hrec.recompute_creation_in_place(history_panel, creation_action) + assert hrec.recompute_1_to_1_in_place(history_panel, downstream_action) + + create_image_mock.assert_called_once() + assert create_image_mock.call_args.args[0] is edited_param + + assert id(source) == source_identity + assert object_model[source_uuid] is source + assert get_uuid(source) == source_uuid + np.testing.assert_allclose(source.data, expected_source.data) + assert not np.array_equal(source.data, initial_source_data) + creation_param = extract_creation_parameters(source) + assert isinstance(creation_param, Gauss2DParam) + for name in ("height", "width", "x0", "y0", "sigma", "a"): + assert getattr(creation_param, name) == getattr(edited_param, name) + + assert processor_source_objects == [source] + np.testing.assert_allclose(processor_source_data[0], expected_source.data) + assert id(downstream) == downstream_identity + assert object_model[downstream_uuid] is downstream + assert get_uuid(downstream) == downstream_uuid + np.testing.assert_allclose( + downstream.data, expected_source.data.astype(float) * 2.0 + 3.0 + ) + assert not np.array_equal(downstream.data, initial_downstream_data) + downstream_params = extract_processing_parameters(downstream) + assert downstream_params is not None + assert downstream_params.source_uuid == source_uuid + assert refreshed_uuids == [source_uuid, downstream_uuid] + assert runtime.execution.cascade_warnings == [] From 3bba27e731938fceb2dad7ef665afe9761d1f530 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Tue, 4 Aug 2026 17:48:12 +0200 Subject: [PATCH 065/108] Fix: Simplify History session creation and type routing History sessions exposed redundant hierarchy and could route actions through the current panel instead of their actual data owner, causing unnecessary prompts and incorrect signal or image session assignment. * [CHG] : Name default sessions "Processing" and display actions directly beneath their session * [FIX] : Skip first-use prompts and create type-specific sessions for new or loaded signals and images * [FIX] : Preserve effective data ownership during recording, loading, navigation, replay, and legacy action handling * [FIX] : Keep image histogram actions in the image session when producing signal outputs * [CHG] : Add pure non-GUI unit coverage for session naming, routing, prompting, legacy compatibility, and histogram ownership --- datalab/gui/historysession_ops.py | 42 +- datalab/gui/historytools_ops.py | 12 +- datalab/gui/panel/base.py | 8 +- datalab/gui/panel/history/chain.py | 10 +- datalab/gui/panel/history/chainmodel.py | 4 +- datalab/gui/panel/history/facade.py | 6 +- datalab/gui/panel/history/navigation.py | 5 +- datalab/history/action.py | 18 +- datalab/history/session.py | 5 +- .../common/history_model_unit_test.py | 449 +++++++++++++++++- datalab/widgets/historytree.py | 27 +- 11 files changed, 515 insertions(+), 71 deletions(-) diff --git a/datalab/gui/historysession_ops.py b/datalab/gui/historysession_ops.py index 3efe207b1..4bef6e559 100644 --- a/datalab/gui/historysession_ops.py +++ b/datalab/gui/historysession_ops.py @@ -47,15 +47,19 @@ def start_new_session_after_workspace_reset(panel: HistoryPanel) -> None: panel.create_new_session() -def maybe_start_session_for_input(panel: HistoryPanel, *, load: bool = False) -> None: +def maybe_start_session_for_input( + panel: HistoryPanel, panel_str: str | None = None, *, load: bool = False +) -> None: """Offer to start a new history session before a creation/load is recorded. - When the current session already contains actions, prompt the user to start - a fresh session so the new creation/load becomes the root of a clean, - self-contained pipeline. A new session is opened *before* the action is - recorded when the user accepts. + When the target panel's active session already contains actions, prompt the + user to start a fresh session so the new creation/load becomes the root of + a clean, self-contained pipeline. A new session is opened *before* the + action is recorded when the user accepts. Args: + panel_str: Target data panel ("signal"/"image"). Defaults to the + current data panel for backward-compatible load callers. load: True when triggered by a file/workspace load, False for an object creation. Only affects the prompt wording. """ @@ -63,9 +67,9 @@ def maybe_start_session_for_input(panel: HistoryPanel, *, load: bool = False) -> return if panel.runtime.execution.suppress_session_prompt: return - # Reuse the current session when there is none yet or it has no actions: - # there is nothing to preserve, so no need to prompt. - if not panel.history_sessions or not panel.history_sessions[-1].actions: + target_panel_str = panel_str or panel.navigation.current_panel_str() + active_session = panel.navigation.get_active_session(target_panel_str) + if active_session is None or not active_session.actions: return # Debounce: a synchronous burst of creations (plugin/macro) must prompt only # once. The guard is reset on the next event-loop turn. @@ -75,7 +79,7 @@ def maybe_start_session_for_input(panel: HistoryPanel, *, load: bool = False) -> # Headless runs: honor the accept_dialogs flag (default False -> "No"), # so tests can drive the behavior without a real modal dialog. if execenv.accept_dialogs: - panel.create_new_session() + panel.create_new_session(panel_str=target_panel_str) return if load: message = _("A new object was loaded. Start a new history session?") @@ -88,7 +92,7 @@ def maybe_start_session_for_input(panel: HistoryPanel, *, load: bool = False) -> QW.QMessageBox.Yes | QW.QMessageBox.No, ) if answer == QW.QMessageBox.Yes: - panel.create_new_session() + panel.create_new_session(panel_str=target_panel_str) def add_compute_entry( @@ -296,18 +300,18 @@ def add_ui_entry( """ if not panel.record_mode_enabled or panel.is_replaying(): return None - # When the entry is an object creation, offer to start a fresh history - # session first so the creation becomes the root of a clean pipeline. - if method_name in HistoryAction.UI_CREATION_METHODS: - panel.maybe_start_session_for_input(load=False) - # Derive the action's panel from the UI target so the captured state only - # constrains the panel the action actually operates on. + # Derive the action's panel from the UI target so prompting and captured + # state concern the panel the action actually operates on. target_panel_str = { "signalpanel": "signal", "imagepanel": "image", "signalprocessor": "signal", "imageprocessor": "image", }.get(target) + # When the entry is an object creation, offer to start a fresh history + # session first so the creation becomes the root of a clean pipeline. + if method_name in HistoryAction.UI_CREATION_METHODS: + panel.maybe_start_session_for_input(panel_str=target_panel_str, load=False) state = WorkspaceState() if save_state: state.save(panel.mainwindow, panel_str=target_panel_str) @@ -320,9 +324,7 @@ def add_ui_entry( method_name=method_name, kwargs=deepcopy(kwargs), state=state, - panel_str=target_panel_str - if target in ("signalprocessor", "imageprocessor") - else None, + panel_str=target_panel_str, ) panel.add_object(action) return action @@ -336,7 +338,7 @@ def add_object(panel: HistoryPanel, obj: HistoryAction) -> None: and image pipelines stay in separate sessions and recording resumes in the user-selected session. """ - pstr = obj.panel_str or panel.navigation.current_panel_str() + pstr = obj.effective_panel_str() or panel.navigation.current_panel_str() session = panel.navigation.get_active_session(pstr) if session is None: session = panel.create_new_session(panel_str=pstr) diff --git a/datalab/gui/historytools_ops.py b/datalab/gui/historytools_ops.py index 5b77babf6..b34247827 100644 --- a/datalab/gui/historytools_ops.py +++ b/datalab/gui/historytools_ops.py @@ -41,9 +41,7 @@ def action_panel_str(action: HistoryAction) -> str: """Return the panel an action operates on, using target as fallback.""" - if action.panel_str: - return action.panel_str - return {"imagepanel": "image", "signalpanel": "signal"}.get(action.target, "signal") + return action.effective_panel_str() or "signal" def make_initial_state_head(pstr: str, clone_uuid: str, title: str) -> HistoryAction: @@ -391,7 +389,7 @@ def split_chain_on_action_delete( The UUID of the deleted action's output object if it remains present (now truly orphaned) in its data panel, otherwise ``None``. """ - panel_str = action.panel_str or "" + panel_str = action.effective_panel_str() # Compute downstream + captured output UUIDs BEFORE removing the action. downstream = hchain.get_downstream_actions(panel, action) output_uuids = list(panel.runtime.objects.action_output_uuids.get(action.uuid, [])) @@ -400,7 +398,7 @@ def split_chain_on_action_delete( if not downstream: return first_alive_output(panel, panel_str, output_uuids) first = downstream[0] - data_panel = data_panel_for(panel, first.panel_str or "") + data_panel = data_panel_for(panel, first.effective_panel_str()) if data_panel is None: return first_alive_output(panel, panel_str, output_uuids) # Locate the orphaned output object that ``first`` still consumes. @@ -423,7 +421,7 @@ def split_chain_on_action_delete( for d in downstream: if orphan_uuid not in action_input_uuids(d): continue - hchain.rewrite_action_source(d, d.panel_str or "", orphan_uuid, new_uuid) + hchain.rewrite_action_source(d, d.effective_panel_str(), orphan_uuid, new_uuid) for out_uuid in panel.runtime.objects.action_output_uuids.get(d.uuid, []): if data_panel.objmodel.has_uuid(out_uuid): remap_object_source( @@ -486,7 +484,7 @@ def apply_deletion(panel: HistoryPanel, plan: DeletionPlan) -> DeletionResult: for action in plan.actions: orphan_uuid = split_chain_on_action_delete(panel, action) if orphan_uuid is not None: - orphan_refs.append((action.panel_str or "", orphan_uuid)) + orphan_refs.append((action.effective_panel_str(), orphan_uuid)) for session in panel.history_sessions: if id(session) in plan.session_ids: for action in session.actions: diff --git a/datalab/gui/panel/base.py b/datalab/gui/panel/base.py index 7ff7449f2..91d701e19 100644 --- a/datalab/gui/panel/base.py +++ b/datalab/gui/panel/base.py @@ -2690,7 +2690,9 @@ def load_from_directory(self, directory: str | None = None) -> list[TypeObj]: if not directory: return [] # Offer a fresh history session for this batch *before* loading anything. - self.mainwindow.historypanel.maybe_start_session_for_input(load=True) + self.mainwindow.historypanel.maybe_start_session_for_input( + panel_str=self.PANEL_STR_ID, load=True + ) folders = [ path for path in glob.glob(osp.join(directory, "**"), recursive=True) @@ -2769,7 +2771,9 @@ def load_from_files( else: entry_title = _('Load "%s"') % osp.basename(filenames[0]) # Offer a fresh history session for this batch *before* recording any entry. - self.mainwindow.historypanel.maybe_start_session_for_input(load=True) + self.mainwindow.historypanel.maybe_start_session_for_input( + panel_str=self.PANEL_STR_ID, load=True + ) action = self.mainwindow.historypanel.add_ui_entry( entry_title, target=self.PANEL_STR_ID + "panel", diff --git a/datalab/gui/panel/history/chain.py b/datalab/gui/panel/history/chain.py index f767ed3bd..88c1385e5 100644 --- a/datalab/gui/panel/history/chain.py +++ b/datalab/gui/panel/history/chain.py @@ -43,11 +43,9 @@ def find_parent_session( def action_panel_target(action: HistoryAction) -> str | None: """Return the main-window data-panel attribute targeted by ``action``.""" - if action.kind == HistoryAction.KIND_UI: - if action.method_name in HistoryAction.UI_CREATION_METHODS: - return action.target - return None - return {"signal": "signalpanel", "image": "imagepanel"}.get(action.panel_str) + return {"signal": "signalpanel", "image": "imagepanel"}.get( + action.effective_panel_str() + ) def resolve_panel_for_action( @@ -129,7 +127,7 @@ def find_action_for_output( continue if action.func_name != func_name: continue - if action.panel_str != panel_data.PANEL_STR_ID: + if action.effective_panel_str() != panel_data.PANEL_STR_ID: continue captured = action.state.selection.get(panel_data.PANEL_STR_ID, []) if captured and captured[0] == target_source_uuid: diff --git a/datalab/gui/panel/history/chainmodel.py b/datalab/gui/panel/history/chainmodel.py index 801243989..2ad6e49c1 100644 --- a/datalab/gui/panel/history/chainmodel.py +++ b/datalab/gui/panel/history/chainmodel.py @@ -122,7 +122,9 @@ def action_input_uuids(action: HistoryAction) -> set[str]: Returns: The set of object UUIDs that the action consumed as inputs. """ - captured: set[str] = set(action.state.selection.get(action.panel_str or "", [])) + captured: set[str] = set( + action.state.selection.get(action.effective_panel_str(), []) + ) obj2 = action.kwargs.get("obj2_uuids") if obj2: if isinstance(obj2, str): diff --git a/datalab/gui/panel/history/facade.py b/datalab/gui/panel/history/facade.py index 714f03b29..c816abe8e 100644 --- a/datalab/gui/panel/history/facade.py +++ b/datalab/gui/panel/history/facade.py @@ -173,9 +173,11 @@ def start_new_session_after_workspace_reset(self) -> None: """Start a history session after a workspace reset when useful.""" hsess.start_new_session_after_workspace_reset(self) - def maybe_start_session_for_input(self, *, load: bool = False) -> None: + def maybe_start_session_for_input( + self, panel_str: str | None = None, *, load: bool = False + ) -> None: """Offer to start a new session before recording an input.""" - hsess.maybe_start_session_for_input(self, load=load) + hsess.maybe_start_session_for_input(self, panel_str=panel_str, load=load) @contextmanager def session_prompt_suppressed(self) -> Generator[None, None, None]: diff --git a/datalab/gui/panel/history/navigation.py b/datalab/gui/panel/history/navigation.py index 1661d6a3a..6777fc735 100644 --- a/datalab/gui/panel/history/navigation.py +++ b/datalab/gui/panel/history/navigation.py @@ -96,8 +96,9 @@ def update_state_widget(self) -> None: def session_panel_str(self, session: HistorySession) -> str | None: """Return the data panel to which a session belongs.""" for action in session.actions: - if action.panel_str: - return action.panel_str + panel_str = action.effective_panel_str() + if panel_str: + return panel_str for panel_str, active_session in self.active_session_by_panel.items(): if active_session is session: return panel_str diff --git a/datalab/history/action.py b/datalab/history/action.py index 5c9f05c4b..2c1f8f3bf 100644 --- a/datalab/history/action.py +++ b/datalab/history/action.py @@ -232,13 +232,18 @@ def copy(self, title_suffix: str | None = None) -> HistoryAction: def effective_panel_str(self) -> str: """Return the panel this action operates on ("signal"/"image"). - Falls back to the UI ``target`` when ``panel_str`` is unset (the case for - creation actions such as ``new_object``, whose ``panel_str`` is ``None`` - but whose ``target`` identifies the panel). + Falls back to the UI ``target`` when ``panel_str`` is unset. This covers + creation actions targeting a data panel and legacy actions targeting a + panel processor. """ if self.panel_str: return self.panel_str - return {"imagepanel": "image", "signalpanel": "signal"}.get(self.target, "") + return { + "signalpanel": "signal", + "signalprocessor": "signal", + "imagepanel": "image", + "imageprocessor": "image", + }.get(self.target, "") def copy_with_uuid_remap( self, uuid_remap: dict[str, dict[str, str]] @@ -643,8 +648,9 @@ def replay_ui( call_kwargs = dict(self.kwargs) # Translate a recorded source object UUID through the session uuid_remap # so deterministic replay after save/reload still targets the right object. - if uuid_remap and self.panel_str and "source_uuid" in call_kwargs: - panel_map = uuid_remap.get(self.panel_str, {}) + pstr = self.effective_panel_str() + if uuid_remap and pstr and "source_uuid" in call_kwargs: + panel_map = uuid_remap.get(pstr, {}) old = call_kwargs["source_uuid"] call_kwargs["source_uuid"] = panel_map.get(old, old) # Inject edit mode if the method supports it diff --git a/datalab/history/session.py b/datalab/history/session.py index 3e1f0b63f..75542cb7e 100644 --- a/datalab/history/session.py +++ b/datalab/history/session.py @@ -28,10 +28,9 @@ class HistorySession: number: Number of the history session """ - def __init__(self, title: str = "", number: int = 0) -> None: + def __init__(self, title: str | None = None, number: int = 0) -> None: """Create a new history session""" - prefix = _("Session") - self.title = title if title else f"{prefix} {number:03d}" + self.title = _("Processing") if title is None else title self.number = number self.dtstr: str = get_datetime_str() self.actions: list[HistoryAction] = [] diff --git a/datalab/tests/features/common/history_model_unit_test.py b/datalab/tests/features/common/history_model_unit_test.py index 010f0d726..778471bf0 100644 --- a/datalab/tests/features/common/history_model_unit_test.py +++ b/datalab/tests/features/common/history_model_unit_test.py @@ -4,25 +4,34 @@ from __future__ import annotations +import ast +import inspect import os import tempfile +import textwrap +from contextlib import nullcontext from types import SimpleNamespace from unittest.mock import patch import numpy as np from sigima.objects import Gauss2DParam, ImageObj +from datalab.gui import historysession_ops as hsess +from datalab.gui import historytools_ops as hops from datalab.gui.creation import ( create_image_from_param, extract_creation_parameters, ) +from datalab.gui.panel.base import BaseDataPanel +from datalab.gui.panel.history import chain as hchain from datalab.gui.panel.history import recompute as hrec +from datalab.gui.panel.history.navigation import HistoryNavigation from datalab.gui.processor.base import ( ProcessingParameters, extract_processing_parameters, insert_processing_parameters, ) -from datalab.h5.native import NativeH5Writer +from datalab.h5.native import NativeH5Reader, NativeH5Writer from datalab.history.action import HistoryAction from datalab.history.core import HISTORY_ACTION_SCHEMA_VERSION, HISTORY_SCHEMA_VERSION from datalab.history.session import HistorySession @@ -56,6 +65,444 @@ def get_object_ids(self) -> list[str]: return list(self.objects) +class PromptExecution: + """Minimal execution state for input-session prompt tests.""" + + def __init__(self, prompt_allowed: bool = True) -> None: + self.suppress_session_prompt = False + self.prompt_allowed = prompt_allowed + self.prompt_count = 0 + + def start_session_input_prompt(self) -> bool: + """Record that the debounce guard was reached.""" + self.prompt_count += 1 + return self.prompt_allowed + + +class PromptNavigation: + """Minimal active-session registry for prompt tests.""" + + def __init__(self, active_sessions: dict[str, HistorySession]) -> None: + self.active_sessions = dict(active_sessions) + + def current_panel_str(self) -> str: + """Return the fallback panel used by legacy load callers.""" + return "signal" + + def get_active_session(self, panel_str: str) -> HistorySession | None: + """Return the active session for ``panel_str``.""" + return self.active_sessions.get(panel_str) + + +class PromptTree: + """Minimal tree recorder for production history routing.""" + + def __init__(self) -> None: + self.rebuilt_session_indices: list[int] = [] + self.rearrange_count = 0 + + def rebuild_session(self, session_index: int) -> None: + """Record the rebuilt session index.""" + self.rebuilt_session_indices.append(session_index) + + def rearrange_tree(self) -> None: + """Record that tree layout was refreshed.""" + self.rearrange_count += 1 + + +class PromptUI: + """Minimal UI state recorder for production history routing.""" + + def __init__(self) -> None: + self.update_count = 0 + + def update_actions_state(self) -> None: + """Record that action states were refreshed.""" + self.update_count += 1 + + +class PromptPanel: + """Minimal history panel for pure input-session prompt tests.""" + + def __init__( + self, + active_sessions: dict[str, HistorySession], + prompt_allowed: bool = True, + ) -> None: + self.record_mode_enabled = True + self.navigation = PromptNavigation(active_sessions) + self.runtime = SimpleNamespace(execution=PromptExecution(prompt_allowed)) + self.history_sessions = list(active_sessions.values()) + self.tree = PromptTree() + self.ui = PromptUI() + self.created_panel_strs: list[str] = [] + self.prompt_panel_strs: list[str | None] = [] + self.added_actions: list[HistoryAction] = [] + self.compatibility_refresh_count = 0 + + def is_replaying(self) -> bool: + """Return whether history replay is active.""" + return False + + def create_new_session(self, panel_str: str | None = None) -> HistorySession: + """Create and activate a session without constructing GUI objects.""" + assert panel_str is not None + self.created_panel_strs.append(panel_str) + session = HistorySession(number=len(self.history_sessions) + 1) + self.history_sessions.append(session) + self.navigation.active_sessions[panel_str] = session + return session + + def maybe_start_session_for_input( + self, panel_str: str | None = None, *, load: bool = False + ) -> None: + """Forward to the session operation while recording its target.""" + self.prompt_panel_strs.append(panel_str) + hsess.maybe_start_session_for_input(self, panel_str=panel_str, load=load) + + def add_object(self, action: HistoryAction) -> None: + """Route an action through the production session operation.""" + self.added_actions.append(action) + hsess.add_object(self, action) + + def refresh_compatibility_items(self) -> None: + """Record that compatibility state was refreshed.""" + self.compatibility_refresh_count += 1 + + +def make_prompt_session(panel_str: str, *, populated: bool) -> HistorySession: + """Return a session optionally populated with one panel action.""" + session = HistorySession(number=1) + if populated: + session.add_action(HistoryAction(panel_str=panel_str)) + return session + + +def test_history_session_default_and_explicit_titles() -> None: + """Translate only the default title and preserve explicit titles.""" + with patch("datalab.history.session._", return_value="Traitement") as translate: + default_session = HistorySession(number=7) + explicit_session = HistorySession(title="Acquisition", number=8) + assert default_session.title == "Traitement" + assert default_session.number == 7 + assert explicit_session.title == "Acquisition" + assert explicit_session.number == 8 + translate.assert_called_once_with("Processing") + + +def test_image_creation_routes_to_image_session_when_signal_is_current() -> None: + """Route an image creation independently of the globally current panel.""" + signal_session = make_prompt_session("signal", populated=True) + signal_actions = list(signal_session.actions) + panel = PromptPanel({"signal": signal_session}) + unattended = SimpleNamespace(unattended=True, accept_dialogs=True) + with patch.object(hsess, "execenv", unattended): + action = hsess.add_ui_entry( + panel, + "New image", + target="imagepanel", + method_name="new_object", + save_state=False, + ) + image_session = panel.navigation.get_active_session("image") + assert action is panel.added_actions[0] + assert action.panel_str == "image" + assert panel.prompt_panel_strs == ["image"] + assert panel.runtime.execution.prompt_count == 0 + assert panel.created_panel_strs == ["image"] + assert image_session is panel.history_sessions[-1] + assert image_session.actions == [action] + assert signal_session.actions == signal_actions + + +def test_empty_active_image_session_skips_prompt() -> None: + """Reuse an empty active image session without reaching the debounce.""" + image_session = make_prompt_session("image", populated=False) + panel = PromptPanel({"image": image_session}) + hsess.maybe_start_session_for_input(panel, panel_str="image") + assert panel.runtime.execution.prompt_count == 0 + assert panel.created_panel_strs == [] + + +def test_accepted_image_prompt_routes_action_to_new_image_session() -> None: + """Record an image creation in the newly accepted image session.""" + image_session = make_prompt_session("image", populated=True) + previous_actions = list(image_session.actions) + panel = PromptPanel({"image": image_session}) + unattended = SimpleNamespace(unattended=True, accept_dialogs=True) + with patch.object(hsess, "execenv", unattended): + action = hsess.add_ui_entry( + panel, + "New image", + target="imagepanel", + method_name="new_object", + save_state=False, + ) + new_image_session = panel.navigation.get_active_session("image") + assert panel.runtime.execution.prompt_count == 1 + assert panel.created_panel_strs == ["image"] + assert new_image_session is panel.history_sessions[-1] + assert new_image_session.actions == [action] + assert image_session.actions == previous_actions + + +def test_populated_active_signal_session_is_evaluated_independently() -> None: + """Start a signal session without replacing the active image session.""" + signal_session = make_prompt_session("signal", populated=True) + image_session = make_prompt_session("image", populated=False) + panel = PromptPanel({"signal": signal_session, "image": image_session}) + unattended = SimpleNamespace(unattended=True, accept_dialogs=True) + with patch.object(hsess, "execenv", unattended): + hsess.maybe_start_session_for_input(panel, panel_str="signal") + assert panel.runtime.execution.prompt_count == 1 + assert panel.created_panel_strs == ["signal"] + assert panel.navigation.get_active_session("image") is image_session + + +def test_ui_entries_serialize_data_target_ownership() -> None: + """Round-trip data-target ownership and preserve legacy target fallback.""" + expected_ownership = { + "signalpanel": "signal", + "imagepanel": "image", + "signalprocessor": "signal", + "imageprocessor": "image", + "mainwindow": None, + "historypanel": None, + } + panel = PromptPanel({}) + actions = [] + for target, panel_str in expected_ownership.items(): + action = hsess.add_ui_entry( + panel, + target, + target=target, + method_name="refresh", + save_state=False, + ) + assert action is not None + assert action.panel_str == panel_str + actions.append(action) + + legacy_ownership = { + "signalprocessor": "signal", + "imageprocessor": "image", + } + legacy_actions = [ + HistoryAction( + title=target, + kind=HistoryAction.KIND_UI, + panel_str="", + target=target, + method_name="refresh", + ) + for target in legacy_ownership + ] + session = HistorySession(number=1) + for action in actions + legacy_actions: + session.add_action(action) + with tempfile.TemporaryDirectory() as tmpdir: + path = os.path.join(tmpdir, "history.dlhist") + with NativeH5Writer(path) as writer: + writer.write_object_list([session], "history_session") + with NativeH5Reader(path) as reader: + loaded_actions = reader.read_object_list("history_session", HistorySession)[ + 0 + ].actions + + for action, (target, panel_str) in zip( + loaded_actions[: len(actions)], expected_ownership.items() + ): + assert action.target == target + assert action.panel_str == panel_str + assert action.effective_panel_str() == (panel_str or "") + for action, (target, panel_str) in zip( + loaded_actions[len(actions) :], legacy_ownership.items() + ): + assert action.target == target + assert action.panel_str == "" + assert action.effective_panel_str() == panel_str + + +def test_legacy_imageprocessor_replay_remaps_source_uuid() -> None: + """Remap a legacy processor UI action through its effective image owner.""" + replayed_source_uuids: list[str] = [] + + def load_from_source(source_uuid: str) -> None: + replayed_source_uuids.append(source_uuid) + + mainwindow = SimpleNamespace( + historypanel=SimpleNamespace( + is_output_suppressed=lambda: False, + replaying=nullcontext, + ), + imagepanel=SimpleNamespace( + processor=SimpleNamespace(load_from_source=load_from_source) + ), + ) + action = HistoryAction( + kind=HistoryAction.KIND_UI, + panel_str="", + target="imageprocessor", + method_name="load_from_source", + kwargs={"source_uuid": "old-image"}, + ) + + action.replay( + mainwindow, + restore_selection=False, + edit=False, + uuid_remap={"image": {"old-image": "new-image"}}, + ) + + assert replayed_source_uuids == ["new-image"] + + +def test_resolve_panel_for_data_owned_ui_actions() -> None: + """Resolve legacy processor and data-panel load actions to image data.""" + signal_panel = SimpleNamespace(name="signal") + image_panel = SimpleNamespace(name="image") + history_panel = SimpleNamespace( + mainwindow=SimpleNamespace( + signalpanel=signal_panel, + imagepanel=image_panel, + ) + ) + image_actions = ( + HistoryAction( + kind=HistoryAction.KIND_UI, + panel_str="", + target="imageprocessor", + method_name="run_feature", + ), + HistoryAction( + kind=HistoryAction.KIND_UI, + panel_str="", + target="imagepanel", + method_name="load_from_files", + ), + ) + + for action in image_actions: + assert hchain.resolve_panel_for_action(history_panel, action) is image_panel + for target in ("mainwindow", "historypanel"): + action = HistoryAction( + kind=HistoryAction.KIND_UI, + target=target, + method_name="refresh", + ) + assert hchain.resolve_panel_for_action(history_panel, action) is None + + +def test_history_tools_action_panel_str_uses_effective_ownership() -> None: + """Recognize a legacy image processor while preserving ownerless fallback.""" + action = HistoryAction( + kind=HistoryAction.KIND_UI, + panel_str="", + target="imageprocessor", + ) + assert hops.action_panel_str(action) == "image" + assert hops.action_panel_str(HistoryAction(target="mainwindow")) == "signal" + + +def test_image_histogram_action_keeps_image_session_ownership() -> None: + """Keep a signal-valued histogram in its image source session.""" + signal_session = make_prompt_session("signal", populated=True) + image_session = make_prompt_session("image", populated=True) + signal_actions = list(signal_session.actions) + image_actions = list(image_session.actions) + signal_output = SimpleNamespace(uuid="histogram-signal", panel_str="signal") + image_source_panel = SimpleNamespace(name="image") + panel = PromptPanel({"signal": signal_session, "image": image_session}) + panel.mainwindow = SimpleNamespace( + signalpanel=SimpleNamespace(name="signal", objects=[signal_output]), + imagepanel=image_source_panel, + ) + action = HistoryAction( + title="Histogram", + kind=HistoryAction.KIND_COMPUTE, + panel_str="image", + func_name="histogram", + pattern="1_to_1", + ) + action.output_uuids = [signal_output.uuid] + + panel.add_object(action) + + assert panel.navigation.current_panel_str() == "signal" + assert signal_output.panel_str == "signal" + assert action.effective_panel_str() == "image" + assert hops.action_panel_str(action) == "image" + assert hchain.resolve_panel_for_action(panel, action) is image_source_panel + assert signal_session.actions == signal_actions + assert image_session.actions == image_actions + [action] + + +def test_debounce_rejection_does_not_start_or_prompt() -> None: + """Keep routing in the active target session when debounce rejects.""" + image_session = make_prompt_session("image", populated=True) + panel = PromptPanel({"image": image_session}, prompt_allowed=False) + attended = SimpleNamespace(unattended=False, accept_dialogs=True) + with ( + patch.object(hsess, "execenv", attended), + patch.object(hsess.QW, "QMessageBox") as message_box, + ): + action = hsess.add_ui_entry( + panel, + "New image", + target="imagepanel", + method_name="new_object", + save_state=False, + ) + assert panel.runtime.execution.prompt_count == 1 + assert panel.created_panel_strs == [] + assert panel.navigation.get_active_session("image") is image_session + assert image_session.actions[-1] is action + message_box.question.assert_not_called() + + +def test_unattended_reject_keeps_populated_target_session() -> None: + """Leave the active image session untouched after unattended rejection.""" + image_session = make_prompt_session("image", populated=True) + previous_actions = list(image_session.actions) + panel = PromptPanel({"image": image_session}) + unattended = SimpleNamespace(unattended=True, accept_dialogs=False) + with patch.object(hsess, "execenv", unattended): + hsess.maybe_start_session_for_input(panel, panel_str="image") + assert panel.runtime.execution.prompt_count == 1 + assert panel.created_panel_strs == [] + assert panel.navigation.get_active_session("image") is image_session + assert image_session.actions == previous_actions + + +def test_navigation_uses_effective_panel_for_ui_only_session() -> None: + """Resolve legacy UI-only sessions from their action target.""" + session = HistorySession(number=1) + session.add_action(HistoryAction(kind=HistoryAction.KIND_UI, target="imagepanel")) + navigation = HistoryNavigation(SimpleNamespace()) + assert navigation.session_panel_str(session) == "image" + + +def test_data_panel_load_prompts_are_target_aware() -> None: + """Require both load entry points to pass their data-panel identifier.""" + for method in (BaseDataPanel.load_from_directory, BaseDataPanel.load_from_files): + tree = ast.parse(textwrap.dedent(inspect.getsource(method))) + calls = [ + node + for node in ast.walk(tree) + if isinstance(node, ast.Call) + and isinstance(node.func, ast.Attribute) + and node.func.attr == "maybe_start_session_for_input" + ] + assert len(calls) == 1 + keywords = {keyword.arg: keyword.value for keyword in calls[0].keywords} + panel_str = keywords["panel_str"] + assert isinstance(panel_str, ast.Attribute) + assert isinstance(panel_str.value, ast.Name) + assert (panel_str.value.id, panel_str.attr) == ("self", "PANEL_STR_ID") + load = keywords["load"] + assert isinstance(load, ast.Constant) and load.value is True + + def test_action_hdf5_current_and_legacy_contract() -> None: """Round-trip current fields and apply all legacy defaults.""" action = build_history_action() diff --git a/datalab/widgets/historytree.py b/datalab/widgets/historytree.py index 928516882..6bede3140 100644 --- a/datalab/widgets/historytree.py +++ b/datalab/widgets/historytree.py @@ -12,7 +12,6 @@ from qtpy import QtWidgets as QW from datalab.config import _ -from datalab.gui.panel.history.chainmodel import build_session_chains from datalab.history import HistoryAction, HistorySession from datalab.widgets.historydescription import CollapsibleDescriptionWidget @@ -29,7 +28,6 @@ class HistoryTree(QW.QTreeWidget): SESSION_NUMBER_ROLE = QC.Qt.UserRole + 2 ITEM_KIND_ROLE = QC.Qt.UserRole + 3 ITEM_SESSION = "session" - ITEM_CHAIN = "chain" ITEM_ACTION = "action" def __init__(self, parent: QW.QWidget) -> None: @@ -176,29 +174,17 @@ def populate_tree(self, history_sessions: list[HistorySession]) -> None: def build_session_children( self, session_item: QW.QTreeWidgetItem, session: HistorySession ) -> None: - """(Re)build the chain/action subtree under ``session_item``. + """(Re)build the action rows directly under ``session_item``. Args: session_item: Top-level tree item for ``session``. - session: History session whose actions are grouped into chains. + session: History session whose actions are displayed in order. """ session_item.takeChildren() - chains = build_session_chains(session) - for chain in chains: - chain_item = QW.QTreeWidgetItem([chain.root.title, ""]) - chain_item.setData(0, self.ITEM_KIND_ROLE, self.ITEM_CHAIN) - chain_item.setData(0, self.COMPATIBILITY_ROLE, True) - font = chain_item.font(0) - font.setBold(True) - chain_item.setFont(0, font) - chain_item.setToolTip( - 0, _("Processing chain \u2014 %d step(s)") % len(chain.actions) - ) - session_item.addChild(chain_item) - for action in chain.actions: - child = self.action_to_tree_item(action) - chain_item.addChild(child) - self.install_description_widget(child, action) + for action in session.actions: + child = self.action_to_tree_item(action) + session_item.addChild(child) + self.install_description_widget(child, action) def set_active_sessions(self, active_session_numbers: dict[int, str]) -> None: """Flag the active recording session(s) by session number and panel. @@ -315,5 +301,4 @@ def get_selected_actions_or_sessions( selected.append(self.get_action_from_uuid(uuid, history_sessions)) except ValueError: continue - # chain-header items are containers only: ignored here. return selected From 218729a3737ab41c1b918a9e799ee64bf836f92f Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Tue, 4 Aug 2026 18:05:25 +0200 Subject: [PATCH 066/108] Feat: Add configurable history session policies History session creation relied on a fixed prompt flow, preventing callers from consistently choosing whether new inputs start or continue a populated session. Add persisted ask/yes/no policies and a typed decision path, ahead of separate plugin runtime integration. * [NEW] : Add persisted policies for regular inputs, plugin-created inputs, and plugin multi-load operations * [NEW] : Expose history session policies in the processing settings * [CHG] : Propagate typed policies and session-creation results through the history facade * [NEW] : Cover explicit policies, invalid values, and settings round trips with focused tests --- datalab/config.py | 16 +++++ datalab/gui/historysession_ops.py | 42 +++++++++--- datalab/gui/panel/history/facade.py | 12 +++- datalab/gui/settings.py | 48 +++++++++++++- .../common/history_model_unit_test.py | 66 +++++++++++++++++-- .../features/utilities/settings_unit_test.py | 42 +++++++++++- 6 files changed, 205 insertions(+), 21 deletions(-) diff --git a/datalab/config.py b/datalab/config.py index b74e7bf54..eb98eab5e 100644 --- a/datalab/config.py +++ b/datalab/config.py @@ -302,6 +302,19 @@ class ProcSection(conf.Section, metaclass=conf.SectionMeta): # - False: user must enable it manually via the History panel toolbar history_auto_record = conf.Option() + # History session behavior for new inputs: + history_new_session_behavior = conf.EnumOption(["ask", "yes", "no"], default="ask") + + # History session behavior for plugin-created inputs: + history_plugin_new_session_behavior = conf.EnumOption( + ["ask", "yes", "no"], default="no" + ) + + # History session behavior when plugins load multiple inputs: + history_plugin_multiload_behavior = conf.EnumOption( + ["ask", "yes", "no"], default="no" + ) + # X-array compatibility behavior for multi-signal computations: # - "ask": ask user for confirmation when x-arrays are incompatible (default) # - "interpolate": automatically interpolate when x-arrays are incompatible @@ -649,6 +662,9 @@ def initialize(): Conf.proc.show_result_dialog.get(True) Conf.proc.ignore_warnings.get(False) Conf.proc.history_auto_record.get(False) + Conf.proc.history_new_session_behavior.get("ask") + Conf.proc.history_plugin_new_session_behavior.get("no") + Conf.proc.history_plugin_multiload_behavior.get("no") Conf.proc.xarray_compat_behavior.get("ask") Conf.proc.small_mono_font.get((configtools.MONOSPACE, 8, False)) # View section diff --git a/datalab/gui/historysession_ops.py b/datalab/gui/historysession_ops.py index 4bef6e559..e3213dce1 100644 --- a/datalab/gui/historysession_ops.py +++ b/datalab/gui/historysession_ops.py @@ -6,7 +6,7 @@ from contextlib import contextmanager from copy import deepcopy -from typing import TYPE_CHECKING, Any, Generator +from typing import TYPE_CHECKING, Any, Generator, Literal from qtpy import QtWidgets as QW @@ -19,6 +19,10 @@ from datalab.gui.panel.history import HistoryPanel +SessionBehavior = Literal["ask", "yes", "no"] +SESSION_BEHAVIORS: tuple[SessionBehavior, ...] = ("ask", "yes", "no") + + def create_new_session( panel: HistoryPanel, panel_str: str | None = None ) -> HistorySession: @@ -48,8 +52,12 @@ def start_new_session_after_workspace_reset(panel: HistoryPanel) -> None: def maybe_start_session_for_input( - panel: HistoryPanel, panel_str: str | None = None, *, load: bool = False -) -> None: + panel: HistoryPanel, + panel_str: str | None = None, + *, + load: bool = False, + behavior: SessionBehavior = "ask", +) -> bool: """Offer to start a new history session before a creation/load is recorded. When the target panel's active session already contains actions, prompt the @@ -62,25 +70,41 @@ def maybe_start_session_for_input( current data panel for backward-compatible load callers. load: True when triggered by a file/workspace load, False for an object creation. Only affects the prompt wording. + behavior: Session creation policy: ask, always create ("yes"), or keep + the current session ("no"). + + Returns: + True if a new session was created. + + Raises: + ValueError: If ``behavior`` is unsupported. """ + if behavior not in SESSION_BEHAVIORS: + raise ValueError(f"Invalid session behavior: {behavior!r}") if not panel.record_mode_enabled or panel.is_replaying(): - return + return False if panel.runtime.execution.suppress_session_prompt: - return + return False target_panel_str = panel_str or panel.navigation.current_panel_str() active_session = panel.navigation.get_active_session(target_panel_str) if active_session is None or not active_session.actions: - return + return False + if behavior == "no": + return False + if behavior == "yes": + panel.create_new_session(panel_str=target_panel_str) + return True # Debounce: a synchronous burst of creations (plugin/macro) must prompt only # once. The guard is reset on the next event-loop turn. if not panel.runtime.execution.start_session_input_prompt(): - return + return False if execenv.unattended: # Headless runs: honor the accept_dialogs flag (default False -> "No"), # so tests can drive the behavior without a real modal dialog. if execenv.accept_dialogs: panel.create_new_session(panel_str=target_panel_str) - return + return True + return False if load: message = _("A new object was loaded. Start a new history session?") else: @@ -93,6 +117,8 @@ def maybe_start_session_for_input( ) if answer == QW.QMessageBox.Yes: panel.create_new_session(panel_str=target_panel_str) + return True + return False def add_compute_entry( diff --git a/datalab/gui/panel/history/facade.py b/datalab/gui/panel/history/facade.py index c816abe8e..9ac2d0848 100644 --- a/datalab/gui/panel/history/facade.py +++ b/datalab/gui/panel/history/facade.py @@ -174,10 +174,16 @@ def start_new_session_after_workspace_reset(self) -> None: hsess.start_new_session_after_workspace_reset(self) def maybe_start_session_for_input( - self, panel_str: str | None = None, *, load: bool = False - ) -> None: + self, + panel_str: str | None = None, + *, + load: bool = False, + behavior: hsess.SessionBehavior = "ask", + ) -> bool: """Offer to start a new session before recording an input.""" - hsess.maybe_start_session_for_input(self, panel_str=panel_str, load=load) + return hsess.maybe_start_session_for_input( + self, panel_str=panel_str, load=load, behavior=behavior + ) @contextmanager def session_prompt_suppressed(self) -> Generator[None, None, None]: diff --git a/datalab/gui/settings.py b/datalab/gui/settings.py index 19f4cb58b..47a610586 100644 --- a/datalab/gui/settings.py +++ b/datalab/gui/settings.py @@ -205,7 +205,51 @@ class ProcSettings(gds.DataSet): ), ) _g0 = gds.EndGroup("") - g1 = gds.BeginGroup(_("Settings for results management")) + g1 = gds.BeginGroup(_("History sessions")) + history_new_session_behavior = gds.ChoiceItem( + _("New object or file"), + zip( + Conf.proc.history_new_session_behavior.values, + [ + _("Ask"), + _("Always start a new session"), + _("Continue in the current session"), + ], + ), + help=_( + "Behavior when a new object or file is added to a populated history " + "session." + ), + ) + history_plugin_new_session_behavior = gds.ChoiceItem( + _("Plugin-created object"), + zip( + Conf.proc.history_plugin_new_session_behavior.values, + [ + _("Ask"), + _("Always start a new session"), + _("Continue in the current session"), + ], + ), + help=_("Behavior when a plugin adds an object to a populated history session."), + ) + history_plugin_multiload_behavior = gds.ChoiceItem( + _("Plugin multi-load"), + zip( + Conf.proc.history_plugin_multiload_behavior.values, + [ + _("Ask once"), + _("Start a new session"), + _("Continue in the current session"), + ], + ), + help=_( + "Behavior when a plugin loads multiple objects into a populated history " + "session." + ), + ) + _g1 = gds.EndGroup("") + g2 = gds.BeginGroup(_("Settings for results management")) keep_results = gds.BoolItem( _("Keep results in metadata after computation"), _("Keep results"), @@ -228,7 +272,7 @@ class ProcSettings(gds.DataSet): "If disabled, the results dialog will not be shown automatically." ), ) - _g1 = gds.EndGroup("") + _g2 = gds.EndGroup("") class ImageDefaultSettings(BaseImageParam): diff --git a/datalab/tests/features/common/history_model_unit_test.py b/datalab/tests/features/common/history_model_unit_test.py index 778471bf0..5acff5507 100644 --- a/datalab/tests/features/common/history_model_unit_test.py +++ b/datalab/tests/features/common/history_model_unit_test.py @@ -11,9 +11,11 @@ import textwrap from contextlib import nullcontext from types import SimpleNamespace +from typing import cast from unittest.mock import patch import numpy as np +import pytest from sigima.objects import Gauss2DParam, ImageObj from datalab.gui import historysession_ops as hsess @@ -137,6 +139,7 @@ def __init__( self.ui = PromptUI() self.created_panel_strs: list[str] = [] self.prompt_panel_strs: list[str | None] = [] + self.prompt_behaviors: list[hsess.SessionBehavior] = [] self.added_actions: list[HistoryAction] = [] self.compatibility_refresh_count = 0 @@ -154,11 +157,18 @@ def create_new_session(self, panel_str: str | None = None) -> HistorySession: return session def maybe_start_session_for_input( - self, panel_str: str | None = None, *, load: bool = False - ) -> None: + self, + panel_str: str | None = None, + *, + load: bool = False, + behavior: hsess.SessionBehavior = "ask", + ) -> bool: """Forward to the session operation while recording its target.""" self.prompt_panel_strs.append(panel_str) - hsess.maybe_start_session_for_input(self, panel_str=panel_str, load=load) + self.prompt_behaviors.append(behavior) + return hsess.maybe_start_session_for_input( + self, panel_str=panel_str, load=load, behavior=behavior + ) def add_object(self, action: HistoryAction) -> None: """Route an action through the production session operation.""" @@ -208,6 +218,7 @@ def test_image_creation_routes_to_image_session_when_signal_is_current() -> None assert action is panel.added_actions[0] assert action.panel_str == "image" assert panel.prompt_panel_strs == ["image"] + assert panel.prompt_behaviors == ["ask"] assert panel.runtime.execution.prompt_count == 0 assert panel.created_panel_strs == ["image"] assert image_session is panel.history_sessions[-1] @@ -219,9 +230,50 @@ def test_empty_active_image_session_skips_prompt() -> None: """Reuse an empty active image session without reaching the debounce.""" image_session = make_prompt_session("image", populated=False) panel = PromptPanel({"image": image_session}) - hsess.maybe_start_session_for_input(panel, panel_str="image") + created = hsess.maybe_start_session_for_input(panel, panel_str="image") + assert created is False + assert panel.runtime.execution.prompt_count == 0 + assert panel.created_panel_strs == [] + + +def test_explicit_session_behaviors_bypass_prompt() -> None: + """Apply explicit yes/no policies without debounce or a dialog.""" + cases: tuple[tuple[hsess.SessionBehavior, bool], ...] = ( + ("yes", True), + ("no", False), + ) + attended = SimpleNamespace(unattended=False, accept_dialogs=False) + for behavior, expected_created in cases: + image_session = make_prompt_session("image", populated=True) + panel = PromptPanel({"image": image_session}) + with ( + patch.object(hsess, "execenv", attended), + patch.object(hsess.QW, "QMessageBox") as message_box, + ): + created = panel.maybe_start_session_for_input( + panel_str="image", behavior=behavior + ) + assert created is expected_created + assert panel.runtime.execution.prompt_count == 0 + assert panel.created_panel_strs == (["image"] if expected_created else []) + message_box.question.assert_not_called() + + +def test_invalid_session_behavior_has_no_side_effects() -> None: + """Reject an invalid policy before debounce or session creation.""" + image_session = make_prompt_session("image", populated=True) + panel = PromptPanel({"image": image_session}) + + with pytest.raises(ValueError, match="Invalid session behavior"): + hsess.maybe_start_session_for_input( + panel, + panel_str="image", + behavior=cast(hsess.SessionBehavior, "invalid"), + ) + assert panel.runtime.execution.prompt_count == 0 assert panel.created_panel_strs == [] + assert panel.history_sessions == [image_session] def test_accepted_image_prompt_routes_action_to_new_image_session() -> None: @@ -253,7 +305,8 @@ def test_populated_active_signal_session_is_evaluated_independently() -> None: panel = PromptPanel({"signal": signal_session, "image": image_session}) unattended = SimpleNamespace(unattended=True, accept_dialogs=True) with patch.object(hsess, "execenv", unattended): - hsess.maybe_start_session_for_input(panel, panel_str="signal") + created = hsess.maybe_start_session_for_input(panel, panel_str="signal") + assert created is True assert panel.runtime.execution.prompt_count == 1 assert panel.created_panel_strs == ["signal"] assert panel.navigation.get_active_session("image") is image_session @@ -467,7 +520,8 @@ def test_unattended_reject_keeps_populated_target_session() -> None: panel = PromptPanel({"image": image_session}) unattended = SimpleNamespace(unattended=True, accept_dialogs=False) with patch.object(hsess, "execenv", unattended): - hsess.maybe_start_session_for_input(panel, panel_str="image") + created = hsess.maybe_start_session_for_input(panel, panel_str="image") + assert created is False assert panel.runtime.execution.prompt_count == 1 assert panel.created_panel_strs == [] assert panel.navigation.get_active_session("image") is image_session diff --git a/datalab/tests/features/utilities/settings_unit_test.py b/datalab/tests/features/utilities/settings_unit_test.py index 167839f1c..58b61e497 100644 --- a/datalab/tests/features/utilities/settings_unit_test.py +++ b/datalab/tests/features/utilities/settings_unit_test.py @@ -11,9 +11,15 @@ from guidata.qthelpers import qt_app_context from qtpy import QtWidgets as QW -from datalab.config import _ +from datalab.config import Conf, _ from datalab.env import execenv -from datalab.gui.settings import create_dataset_dict, edit_settings +from datalab.gui.settings import ( + ProcSettings, + conf_to_datasets, + create_dataset_dict, + datasets_to_conf, + edit_settings, +) from datalab.utils import qthelpers as qth @@ -24,6 +30,38 @@ def test_edit_settings(): execenv.print(changed) +def test_proc_history_policy_settings_round_trip() -> None: + """Load and save history policies through generic settings machinery.""" + option_names = ( + "history_new_session_behavior", + "history_plugin_new_session_behavior", + "history_plugin_multiload_behavior", + ) + original_values = tuple(getattr(Conf.proc, name).get() for name in option_names) + loaded_values = ("yes", "ask", "no") + saved_values = ("no", "yes", "ask") + + try: + for name, value in zip(option_names, loaded_values): + getattr(Conf.proc, name).set(value) + + settings = ProcSettings() + paramdict = {"proc": settings} + conf_to_datasets(paramdict) + assert tuple(getattr(settings, name) for name in option_names) == loaded_values + + for name, value in zip(option_names, saved_values): + setattr(settings, name, value) + datasets_to_conf(paramdict) + assert ( + tuple(getattr(Conf.proc, name).get() for name in option_names) + == saved_values + ) + finally: + for name, value in zip(option_names, original_values): + getattr(Conf.proc, name).set(value) + + def capture_settings_screenshots(): """Capture screenshots of each settings tab From 37490e969f9e46e8ffaca84ec5394fb283f85b6f Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Tue, 4 Aug 2026 19:10:02 +0200 Subject: [PATCH 067/108] Fix: Apply history session policies consistently to plugin inputs Plugin-created objects did not consistently honor the configured session policy, and multi-object loads could prompt repeatedly or consume their decision before an object was accepted. Resolve persisted policies at the insertion boundary and carry one lazy, panel-specific decision across each plugin batch. * [FIX] : Apply live general and plugin ask/yes/no settings while preserving explicit per-call choices * [NEW] : Add a validated multi-load scope that decides on the first accepted object and leaves empty or cancelled batches untouched * [FIX] : Decide before insertion, suppress duplicate prompts, report memory refusals, and debounce signal and image panels independently * [CHG] : Batch Test Data plugin loads using the matching data panel * [NEW] : Cover plugin policy behavior and add French settings translations --- datalab/control/proxy.py | 140 ++++- datalab/gui/historysession_ops.py | 10 +- datalab/gui/main.py | 60 ++- datalab/gui/panel/history/facade.py | 2 +- datalab/gui/panel/history/runtime.py | 20 +- datalab/locale/fr/LC_MESSAGES/datalab.po | 37 +- datalab/plugins.py | 2 +- datalab/plugins/datalab_testdata.py | 26 +- .../common/history_model_unit_test.py | 223 ++++++-- .../plugin_history_policy_unit_test.py | 491 ++++++++++++++++++ 10 files changed, 925 insertions(+), 86 deletions(-) create mode 100644 datalab/tests/features/plugins/plugin_history_policy_unit_test.py diff --git a/datalab/control/proxy.py b/datalab/control/proxy.py index 8acd63d26..07382b628 100644 --- a/datalab/control/proxy.py +++ b/datalab/control/proxy.py @@ -75,15 +75,39 @@ from collections.abc import Generator from contextlib import contextmanager +from dataclasses import dataclass +from typing import TYPE_CHECKING, Literal import guidata.dataset as gds import numpy as np from sigima import ImageObj, SignalObj +from datalab.config import Conf from datalab.control.baseproxy import BaseProxy from datalab.control.remote import RemoteClient from datalab.utils import qthelpers as qth +if TYPE_CHECKING: + from datalab.gui.historysession_ops import SessionBehavior + from datalab.gui.main import DLMainWindow + + +@dataclass +class MultiLoadState: + """Track a local proxy multi-object load.""" + + panel: Literal["signal", "image"] + behavior: SessionBehavior | None + decision_applied: bool = False + + def behavior_for(self, panel: Literal["signal", "image"]) -> SessionBehavior | None: + """Return the session behavior for an object added to ``panel``.""" + if panel != self.panel: + raise ValueError( + f"Cannot add a {panel} object during a {self.panel} multiload session" + ) + return "no" if self.decision_applied else self.behavior + class RemoteProxy(RemoteClient): """DataLab remote proxy class. @@ -137,8 +161,20 @@ class LocalProxy(BaseProxy): Args: datalab (DLMainWindow): DLMainWindow instance. + input_source: Source of objects added through this proxy. """ + def __init__( + self, + datalab: DLMainWindow | None = None, + input_source: Literal["local", "plugin"] = "local", + ) -> None: + if input_source not in ("local", "plugin"): + raise ValueError(f"Invalid local proxy input source: {input_source!r}") + super().__init__(datalab) + self.input_source = input_source + self.multiload_state: MultiLoadState | None = None + def add_signal( self, title: str, @@ -150,6 +186,7 @@ def add_signal( ylabel: str = "", group_id: str = "", set_current: bool = True, + new_session_behavior: SessionBehavior | None = None, ) -> bool: # pylint: disable=too-many-arguments """Add signal data to DataLab. @@ -163,6 +200,7 @@ def add_signal( ylabel: Y label. Defaults to "" group_id: group id in which to add the signal. Defaults to "" set_current: if True, set the added signal as current + new_session_behavior: Optional history session creation policy Returns: True if signal was added successfully, False otherwise @@ -171,9 +209,28 @@ def add_signal( ValueError: Invalid xdata dtype ValueError: Invalid ydata dtype """ - return self._datalab.add_signal( - title, xdata, ydata, xunit, yunit, xlabel, ylabel, group_id, set_current + multiload_state = self.multiload_state + if multiload_state is None: + behavior = new_session_behavior + if behavior is None and self.input_source == "plugin": + behavior = Conf.proc.history_plugin_new_session_behavior.get() + else: + behavior = multiload_state.behavior_for("signal") + added = self._datalab.add_signal( + title, + xdata, + ydata, + xunit, + yunit, + xlabel, + ylabel, + group_id, + set_current, + new_session_behavior=behavior, ) + if added and multiload_state is not None: + multiload_state.decision_applied = True + return added def add_image( self, @@ -187,6 +244,7 @@ def add_image( zlabel: str = "", group_id: str = "", set_current: bool = True, + new_session_behavior: SessionBehavior | None = None, ) -> bool: # pylint: disable=too-many-arguments """Add image data to DataLab. @@ -201,6 +259,7 @@ def add_image( zlabel: Z label. Defaults to "" group_id: group id in which to add the image. Defaults to "" set_current: if True, set the added image as current + new_session_behavior: Optional history session creation policy Returns: True if image was added successfully, False otherwise @@ -208,7 +267,14 @@ def add_image( Raises: ValueError: Invalid data dtype """ - return self._datalab.add_image( + multiload_state = self.multiload_state + if multiload_state is None: + behavior = new_session_behavior + if behavior is None and self.input_source == "plugin": + behavior = Conf.proc.history_plugin_new_session_behavior.get() + else: + behavior = multiload_state.behavior_for("image") + added = self._datalab.add_image( title, data, xunit, @@ -219,19 +285,81 @@ def add_image( zlabel, group_id, set_current, + new_session_behavior=behavior, ) + if added and multiload_state is not None: + multiload_state.decision_applied = True + return added def add_object( - self, obj: SignalObj | ImageObj, group_id: str = "", set_current: bool = True - ) -> None: + self, + obj: SignalObj | ImageObj, + group_id: str = "", + set_current: bool = True, + new_session_behavior: SessionBehavior | None = None, + ) -> bool: """Add object to DataLab. Args: obj: Signal or image object group_id: group id in which to add the object. Defaults to "" set_current: if True, set the added object as current + new_session_behavior: Optional history session creation policy + + Returns: + True if the object was added successfully, False otherwise """ - self._datalab.add_object(obj, group_id, set_current) + multiload_state = self.multiload_state + if multiload_state is None: + behavior = new_session_behavior + if behavior is None and self.input_source == "plugin": + behavior = Conf.proc.history_plugin_new_session_behavior.get() + else: + if isinstance(obj, SignalObj): + panel = "signal" + elif isinstance(obj, ImageObj): + panel = "image" + else: + raise TypeError(f"Unsupported object type {type(obj)}") + behavior = multiload_state.behavior_for(panel) + added = self._datalab.add_object( + obj, group_id, set_current, new_session_behavior=behavior + ) + if added and multiload_state is not None: + multiload_state.decision_applied = True + return added + + @contextmanager + def multiload_session( + self, + panel: Literal["signal", "image"], + new_session_behavior: SessionBehavior | None = None, + ) -> Generator[None, None, None]: + """Apply one lazy session decision to a multi-object load. + + Args: + panel: Target data panel ("signal" or "image") + new_session_behavior: Optional history session creation policy + + Raises: + ValueError: If the panel or session behavior is invalid + RuntimeError: If another multiload session is already active + """ + if panel not in ("signal", "image"): + raise ValueError(f"Invalid data panel: {panel!r}") + behavior = new_session_behavior + if behavior is None and self.input_source == "plugin": + behavior = Conf.proc.history_plugin_multiload_behavior.get() + if behavior is not None and behavior not in ("ask", "yes", "no"): + raise ValueError(f"Invalid session behavior: {behavior!r}") + if self.multiload_state is not None: + raise RuntimeError("Nested multiload sessions are not supported") + previous_state = self.multiload_state + self.multiload_state = MultiLoadState(panel, behavior) + try: + yield + finally: + self.multiload_state = previous_state def calc(self, name: str, param: gds.DataSet | None = None) -> None: """Call computation feature ``name`` diff --git a/datalab/gui/historysession_ops.py b/datalab/gui/historysession_ops.py index e3213dce1..d7d04d658 100644 --- a/datalab/gui/historysession_ops.py +++ b/datalab/gui/historysession_ops.py @@ -10,7 +10,7 @@ from qtpy import QtWidgets as QW -from datalab.config import _ +from datalab.config import Conf, _ from datalab.env import execenv from datalab.gui.panel.history import chain as hchain from datalab.history import HistoryAction, HistorySession, WorkspaceState @@ -56,7 +56,7 @@ def maybe_start_session_for_input( panel_str: str | None = None, *, load: bool = False, - behavior: SessionBehavior = "ask", + behavior: SessionBehavior | None = None, ) -> bool: """Offer to start a new history session before a creation/load is recorded. @@ -71,7 +71,7 @@ def maybe_start_session_for_input( load: True when triggered by a file/workspace load, False for an object creation. Only affects the prompt wording. behavior: Session creation policy: ask, always create ("yes"), or keep - the current session ("no"). + the current session ("no"). Defaults to the live general policy. Returns: True if a new session was created. @@ -79,6 +79,8 @@ def maybe_start_session_for_input( Raises: ValueError: If ``behavior`` is unsupported. """ + if behavior is None: + behavior = Conf.proc.history_new_session_behavior.get() if behavior not in SESSION_BEHAVIORS: raise ValueError(f"Invalid session behavior: {behavior!r}") if not panel.record_mode_enabled or panel.is_replaying(): @@ -96,7 +98,7 @@ def maybe_start_session_for_input( return True # Debounce: a synchronous burst of creations (plugin/macro) must prompt only # once. The guard is reset on the next event-loop turn. - if not panel.runtime.execution.start_session_input_prompt(): + if not panel.runtime.execution.start_session_input_prompt(target_panel_str): return False if execenv.unattended: # Headless runs: honor the accept_dialogs flag (default False -> "No"), diff --git a/datalab/gui/main.py b/datalab/gui/main.py index a6a86783d..d4d6e8a2c 100644 --- a/datalab/gui/main.py +++ b/datalab/gui/main.py @@ -94,6 +94,7 @@ if TYPE_CHECKING: from typing import Literal + from datalab.gui.historysession_ops import SessionBehavior from datalab.gui.panel.base import AbstractPanel, BaseDataPanel from datalab.gui.panel.image import ImagePanel from datalab.gui.panel.macro import MacroPanel @@ -2336,36 +2337,51 @@ def import_h5_file(self, filename: str, reset_all: bool | None = None) -> None: # (see TODO regarding RemoteClient.add_object method) # @remote_controlled def add_object( - self, obj: SignalObj | ImageObj, group_id: str = "", set_current=True - ) -> None: + self, + obj: SignalObj | ImageObj, + group_id: str = "", + set_current=True, + new_session_behavior: SessionBehavior | None = None, + ) -> bool: """Add object - signal or image Args: obj: object to add (signal or image) group_id: group ID (optional) set_current: True to set the object as current object + new_session_behavior: Optional history session creation policy + + Returns: + True if the object was added successfully, False otherwise """ - if self.confirm_memory_state(): - if isinstance(obj, SignalObj): - self.signalpanel.add_object(obj, group_id, set_current) - panel_str = "signal" - elif isinstance(obj, ImageObj): - self.imagepanel.add_object(obj, group_id, set_current) - panel_str = "image" - else: - raise TypeError(f"Unsupported object type {type(obj)}") - # Record a creation entry so objects added programmatically (plugins, - # macros, remote control) appear in the history. ``panel.add_object`` - # deliberately does not record, so creations entering through this - # proxy boundary would otherwise be lost (notably the very first one). + if not self.confirm_memory_state(): + return False + if isinstance(obj, SignalObj): + panel = self.signalpanel + panel_str = "signal" + elif isinstance(obj, ImageObj): + panel = self.imagepanel + panel_str = "image" + else: + raise TypeError(f"Unsupported object type {type(obj)}") + self.historypanel.maybe_start_session_for_input( + panel_str=panel_str, behavior=new_session_behavior + ) + panel.add_object(obj, group_id, set_current) + # Record a creation entry so objects added programmatically (plugins, + # macros, remote control) appear in the history. ``panel.add_object`` + # deliberately does not record, so creations entering through this + # proxy boundary would otherwise be lost (notably the very first one). + with self.historypanel.session_prompt_suppressed(): action = self.historypanel.add_ui_entry( _("New %s") % panel_str, target=panel_str + "panel", method_name="new_object", save_state=False, ) - if action is not None: - self.historypanel.register_action_outputs(action, [get_uuid(obj)]) + if action is not None: + self.historypanel.register_action_outputs(action, [get_uuid(obj)]) + return True @remote_controlled def set_object(self, obj: SignalObj | ImageObj) -> None: @@ -2436,6 +2452,7 @@ def add_signal( ylabel: str = "", group_id: str = "", set_current: bool = True, + new_session_behavior: SessionBehavior | None = None, ) -> bool: # pylint: disable=too-many-arguments """Add signal data to DataLab. @@ -2449,6 +2466,7 @@ def add_signal( ylabel: Y label. Defaults to "" group_id: group id in which to add the signal. Defaults to "" set_current: if True, set the added signal as current + new_session_behavior: Optional history session creation policy Returns: True if signal was added successfully, False otherwise @@ -2464,8 +2482,7 @@ def add_signal( units=(xunit, yunit), labels=(xlabel, ylabel), ) - self.add_object(obj, group_id, set_current) - return True + return self.add_object(obj, group_id, set_current, new_session_behavior) # This API mirrors the image metadata accepted by create_image, so the # argument count is part of the stable public interface rather than noise. @@ -2481,6 +2498,7 @@ def add_image( # pylint: disable=too-many-arguments zlabel: str = "", group_id: str = "", set_current: bool = True, + new_session_behavior: SessionBehavior | None = None, ) -> bool: """Add image data to DataLab. @@ -2495,6 +2513,7 @@ def add_image( # pylint: disable=too-many-arguments zlabel: Z label. Defaults to "" group_id: group id in which to add the image. Defaults to "" set_current: if True, set the added image as current + new_session_behavior: Optional history session creation policy Returns: True if image was added successfully, False otherwise @@ -2508,8 +2527,7 @@ def add_image( # pylint: disable=too-many-arguments units=(xunit, yunit, zunit), labels=(xlabel, ylabel, zlabel), ) - self.add_object(obj, group_id, set_current) - return True + return self.add_object(obj, group_id, set_current, new_session_behavior) # ------? def __about(self) -> None: # pragma: no cover diff --git a/datalab/gui/panel/history/facade.py b/datalab/gui/panel/history/facade.py index 9ac2d0848..a6a178247 100644 --- a/datalab/gui/panel/history/facade.py +++ b/datalab/gui/panel/history/facade.py @@ -178,7 +178,7 @@ def maybe_start_session_for_input( panel_str: str | None = None, *, load: bool = False, - behavior: hsess.SessionBehavior = "ask", + behavior: hsess.SessionBehavior | None = None, ) -> bool: """Offer to start a new session before recording an input.""" return hsess.maybe_start_session_for_input( diff --git a/datalab/gui/panel/history/runtime.py b/datalab/gui/panel/history/runtime.py index ad6d3af0e..e026e40c8 100644 --- a/datalab/gui/panel/history/runtime.py +++ b/datalab/gui/panel/history/runtime.py @@ -22,7 +22,7 @@ class HistoryExecutionState: def __init__(self) -> None: self.record_mode = False self.edit_mode = False - self.session_input_pending = False + self.session_input_pending_panels: set[str] = set() self.suppress_session_prompt = False self.replaying_active = False self.output_suppressed_active = False @@ -61,17 +61,19 @@ def session_prompt_suppressed(self) -> Generator[None, None, None]: finally: self.suppress_session_prompt = previous - def start_session_input_prompt(self) -> bool: - """Start the input prompt debounce window if it is not already active.""" - if self.session_input_pending: + def start_session_input_prompt(self, panel_str: str) -> bool: + """Start the input prompt debounce window for a data panel.""" + if panel_str in self.session_input_pending_panels: return False - self.session_input_pending = True - QC.QTimer.singleShot(0, self.finish_session_input_prompt) + self.session_input_pending_panels.add(panel_str) + QC.QTimer.singleShot( + 0, functools.partial(self.finish_session_input_prompt, panel_str) + ) return True - def finish_session_input_prompt(self) -> None: - """End the input prompt debounce window.""" - self.session_input_pending = False + def finish_session_input_prompt(self, panel_str: str) -> None: + """End the input prompt debounce window for a data panel.""" + self.session_input_pending_panels.discard(panel_str) @contextmanager def recomputing_cascade(self) -> Generator[bool, None, None]: diff --git a/datalab/locale/fr/LC_MESSAGES/datalab.po b/datalab/locale/fr/LC_MESSAGES/datalab.po index a7d11e141..4416e1264 100644 --- a/datalab/locale/fr/LC_MESSAGES/datalab.po +++ b/datalab/locale/fr/LC_MESSAGES/datalab.po @@ -3092,6 +3092,42 @@ msgstr "Interpoler systématiquement" msgid "Behavior when X-axis arrays are incompatible in multi-signal computations:<ul><li><b>Ask</b>: display confirmation dialog (default)</li><li><b>Interpolate</b>: automatically interpolate signals</li></ul>" msgstr "Comportement lorsque les tableaux des X sont incompatibles dans les calculs multi-signaux :<ul><li><b>Demander</b> : afficher une boîte de dialogue de confirmation (par défaut)</li><li><b>Interpoler</b> : interpoler automatiquement les signaux</li></ul>" +msgid "History sessions" +msgstr "Sessions d'historique" + +msgid "New object or file" +msgstr "Nouvel objet ou fichier" + +msgid "Ask" +msgstr "Demander" + +msgid "Always start a new session" +msgstr "Toujours démarrer une nouvelle session" + +msgid "Continue in the current session" +msgstr "Continuer dans la session courante" + +msgid "Behavior when a new object or file is added to a populated history session." +msgstr "Comportement lorsqu'un nouvel objet ou fichier est ajouté à une session d'historique non vide." + +msgid "Plugin-created object" +msgstr "Objet créé par un plugin" + +msgid "Behavior when a plugin adds an object to a populated history session." +msgstr "Comportement lorsqu'un plugin ajoute un objet à une session d'historique non vide." + +msgid "Plugin multi-load" +msgstr "Chargement multiple par un plugin" + +msgid "Ask once" +msgstr "Demander une seule fois" + +msgid "Start a new session" +msgstr "Démarrer une nouvelle session" + +msgid "Behavior when a plugin loads multiple objects into a populated history session." +msgstr "Comportement lorsqu'un plugin charge plusieurs objets dans une session d'historique non vide." + msgid "Settings for results management" msgstr "Réglages de la gestion des résultats" @@ -4384,4 +4420,3 @@ msgstr "Un ou plusieurs signaux sélectionnés ont des paramètres d'ajustement #, python-format msgid "%s: fitting curve was computed by an earlier version and cannot be evaluated (please recompute the fit)" msgstr "%s : la courbe d'ajustement a été calculée par une version antérieure et ne peut pas être évaluée (veuillez recalculer l'ajustement)" - diff --git a/datalab/plugins.py b/datalab/plugins.py index a1750bdfb..40ab20e32 100644 --- a/datalab/plugins.py +++ b/datalab/plugins.py @@ -346,7 +346,7 @@ def register(self, main: main.DLMainWindow) -> None: PluginRegistry.register_plugin(self) self._is_registered = True self.main = main - self.proxy = LocalProxy(main) + self.proxy = LocalProxy(main, input_source="plugin") self.register_hooks() def unregister(self): diff --git a/datalab/plugins/datalab_testdata.py b/datalab/plugins/datalab_testdata.py index a8ae11c19..951d2416a 100644 --- a/datalab/plugins/datalab_testdata.py +++ b/datalab/plugins/datalab_testdata.py @@ -42,18 +42,24 @@ def load_test_objs( Args: registry_class: Registry class (SignalIORegistry or ImageIORegistry) title: Progress bar title - - Returns: - List of (filename, object) tuples """ + if issubclass(registry_class, SignalIORegistry): + panel_str = "signal" + panel = self.signalpanel + elif issubclass(registry_class, ImageIORegistry): + panel_str = "image" + panel = self.imagepanel + else: + raise TypeError(f"Unsupported I/O registry class: {registry_class!r}") test_objs = list(helpers.read_test_objects(registry_class)) - with create_progress_bar(self.signalpanel, title, max_=len(test_objs)) as prog: - for i_obj, (_fname, obj) in enumerate(test_objs): - prog.setValue(i_obj + 1) - if prog.wasCanceled(): - break - if obj is not None: - self.proxy.add_object(obj) + with self.proxy.multiload_session(panel_str): + with create_progress_bar(panel, title, max_=len(test_objs)) as prog: + for i_obj, (_fname, obj) in enumerate(test_objs): + prog.setValue(i_obj + 1) + if prog.wasCanceled(): + break + if obj is not None: + self.proxy.add_object(obj) # Signal processing features ------------------------------------------------ def create_paracetamol_signal(self) -> None: diff --git a/datalab/tests/features/common/history_model_unit_test.py b/datalab/tests/features/common/history_model_unit_test.py index 5acff5507..f84406807 100644 --- a/datalab/tests/features/common/history_model_unit_test.py +++ b/datalab/tests/features/common/history_model_unit_test.py @@ -4,12 +4,9 @@ from __future__ import annotations -import ast -import inspect import os import tempfile -import textwrap -from contextlib import nullcontext +from contextlib import contextmanager, nullcontext from types import SimpleNamespace from typing import cast from unittest.mock import patch @@ -24,9 +21,10 @@ create_image_from_param, extract_creation_parameters, ) -from datalab.gui.panel.base import BaseDataPanel +from datalab.gui.main import DLMainWindow from datalab.gui.panel.history import chain as hchain from datalab.gui.panel.history import recompute as hrec +from datalab.gui.panel.history import runtime as hruntime from datalab.gui.panel.history.navigation import HistoryNavigation from datalab.gui.processor.base import ( ProcessingParameters, @@ -74,12 +72,24 @@ def __init__(self, prompt_allowed: bool = True) -> None: self.suppress_session_prompt = False self.prompt_allowed = prompt_allowed self.prompt_count = 0 + self.prompt_panel_strs: list[str] = [] - def start_session_input_prompt(self) -> bool: + def start_session_input_prompt(self, panel_str: str) -> bool: """Record that the debounce guard was reached.""" self.prompt_count += 1 + self.prompt_panel_strs.append(panel_str) return self.prompt_allowed + @contextmanager + def session_prompt_suppressed(self): + """Suppress session prompts while preserving the previous state.""" + previous = self.suppress_session_prompt + self.suppress_session_prompt = True + try: + yield + finally: + self.suppress_session_prompt = previous + class PromptNavigation: """Minimal active-session registry for prompt tests.""" @@ -139,9 +149,12 @@ def __init__( self.ui = PromptUI() self.created_panel_strs: list[str] = [] self.prompt_panel_strs: list[str | None] = [] - self.prompt_behaviors: list[hsess.SessionBehavior] = [] + self.prompt_behaviors: list[hsess.SessionBehavior | None] = [] + self.prompt_suppressed_states: list[bool] = [] self.added_actions: list[HistoryAction] = [] + self.registered_outputs: list[tuple[HistoryAction, list[str]]] = [] self.compatibility_refresh_count = 0 + self.events: list[str] = [] def is_replaying(self) -> bool: """Return whether history replay is active.""" @@ -161,15 +174,44 @@ def maybe_start_session_for_input( panel_str: str | None = None, *, load: bool = False, - behavior: hsess.SessionBehavior = "ask", + behavior: hsess.SessionBehavior | None = None, ) -> bool: """Forward to the session operation while recording its target.""" + self.events.append("session_decision") self.prompt_panel_strs.append(panel_str) self.prompt_behaviors.append(behavior) + self.prompt_suppressed_states.append( + self.runtime.execution.suppress_session_prompt + ) return hsess.maybe_start_session_for_input( self, panel_str=panel_str, load=load, behavior=behavior ) + @contextmanager + def session_prompt_suppressed(self): + """Suppress input-session prompts for the context scope.""" + with self.runtime.execution.session_prompt_suppressed(): + yield + + def add_ui_entry( + self, + action_title: str, + target: str, + method_name: str, + save_state: bool = True, + **kwargs, + ) -> HistoryAction | None: + """Forward a UI entry through the production history operation.""" + return hsess.add_ui_entry( + self, action_title, target, method_name, save_state, **kwargs + ) + + def register_action_outputs( + self, action: HistoryAction, output_uuids: list[str] + ) -> None: + """Record output registration performed by the main window.""" + self.registered_outputs.append((action, output_uuids)) + def add_object(self, action: HistoryAction) -> None: """Route an action through the production session operation.""" self.added_actions.append(action) @@ -218,7 +260,7 @@ def test_image_creation_routes_to_image_session_when_signal_is_current() -> None assert action is panel.added_actions[0] assert action.panel_str == "image" assert panel.prompt_panel_strs == ["image"] - assert panel.prompt_behaviors == ["ask"] + assert panel.prompt_behaviors == [None] assert panel.runtime.execution.prompt_count == 0 assert panel.created_panel_strs == ["image"] assert image_session is panel.history_sessions[-1] @@ -236,6 +278,23 @@ def test_empty_active_image_session_skips_prompt() -> None: assert panel.created_panel_strs == [] +def test_omitted_session_behavior_reads_live_general_policy() -> None: + """Resolve the general policy on every omitted-behavior call.""" + image_session = make_prompt_session("image", populated=True) + panel = PromptPanel({"image": image_session}) + option = hsess.Conf.proc.history_new_session_behavior + + with patch.object(option, "get", side_effect=["no", "yes"]) as get_behavior: + first_created = panel.maybe_start_session_for_input(panel_str="image") + second_created = panel.maybe_start_session_for_input(panel_str="image") + + assert first_created is False + assert second_created is True + assert panel.created_panel_strs == ["image"] + assert panel.prompt_behaviors == [None, None] + assert get_behavior.call_count == 2 + + def test_explicit_session_behaviors_bypass_prompt() -> None: """Apply explicit yes/no policies without debounce or a dialog.""" cases: tuple[tuple[hsess.SessionBehavior, bool], ...] = ( @@ -282,7 +341,12 @@ def test_accepted_image_prompt_routes_action_to_new_image_session() -> None: previous_actions = list(image_session.actions) panel = PromptPanel({"image": image_session}) unattended = SimpleNamespace(unattended=True, accept_dialogs=True) - with patch.object(hsess, "execenv", unattended): + with ( + patch.object(hsess, "execenv", unattended), + patch.object( + hsess.Conf.proc.history_new_session_behavior, "get", return_value="ask" + ), + ): action = hsess.add_ui_entry( panel, "New image", @@ -305,13 +369,52 @@ def test_populated_active_signal_session_is_evaluated_independently() -> None: panel = PromptPanel({"signal": signal_session, "image": image_session}) unattended = SimpleNamespace(unattended=True, accept_dialogs=True) with patch.object(hsess, "execenv", unattended): - created = hsess.maybe_start_session_for_input(panel, panel_str="signal") + created = hsess.maybe_start_session_for_input( + panel, panel_str="signal", behavior="ask" + ) assert created is True assert panel.runtime.execution.prompt_count == 1 + assert panel.runtime.execution.prompt_panel_strs == ["signal"] assert panel.created_panel_strs == ["signal"] assert panel.navigation.get_active_session("image") is image_session +def test_input_prompt_debounce_is_panel_scoped() -> None: + """Debounce signal and image decisions on independent timer windows.""" + signal_session = make_prompt_session("signal", populated=True) + image_session = make_prompt_session("image", populated=True) + panel = PromptPanel({"signal": signal_session, "image": image_session}) + execution = hruntime.HistoryExecutionState() + panel.runtime = SimpleNamespace(execution=execution) + callbacks = [] + unattended = SimpleNamespace(unattended=True, accept_dialogs=False) + + with ( + patch.object( + hruntime.QC.QTimer, + "singleShot", + side_effect=lambda _delay, callback: callbacks.append(callback), + ), + patch.object(hsess, "execenv", unattended), + ): + assert not hsess.maybe_start_session_for_input( + panel, panel_str="signal", behavior="ask" + ) + assert not hsess.maybe_start_session_for_input( + panel, panel_str="image", behavior="ask" + ) + assert not hsess.maybe_start_session_for_input( + panel, panel_str="signal", behavior="ask" + ) + + assert execution.session_input_pending_panels == {"signal", "image"} + assert len(callbacks) == 2 + callbacks[0]() + assert execution.session_input_pending_panels == {"image"} + callbacks[1]() + assert execution.session_input_pending_panels == set() + + def test_ui_entries_serialize_data_target_ownership() -> None: """Round-trip data-target ownership and preserve legacy target fallback.""" expected_ownership = { @@ -498,6 +601,9 @@ def test_debounce_rejection_does_not_start_or_prompt() -> None: with ( patch.object(hsess, "execenv", attended), patch.object(hsess.QW, "QMessageBox") as message_box, + patch.object( + hsess.Conf.proc.history_new_session_behavior, "get", return_value="ask" + ), ): action = hsess.add_ui_entry( panel, @@ -520,7 +626,9 @@ def test_unattended_reject_keeps_populated_target_session() -> None: panel = PromptPanel({"image": image_session}) unattended = SimpleNamespace(unattended=True, accept_dialogs=False) with patch.object(hsess, "execenv", unattended): - created = hsess.maybe_start_session_for_input(panel, panel_str="image") + created = hsess.maybe_start_session_for_input( + panel, panel_str="image", behavior="ask" + ) assert created is False assert panel.runtime.execution.prompt_count == 1 assert panel.created_panel_strs == [] @@ -528,6 +636,76 @@ def test_unattended_reject_keeps_populated_target_session() -> None: assert image_session.actions == previous_actions +def test_mainwindow_add_object_decides_before_mutation_and_suppresses_entry() -> None: + """Decide before adding and suppress the creation entry's second prompt.""" + image_session = make_prompt_session("image", populated=True) + historypanel = PromptPanel({"image": image_session}) + added_objects = [] + + def add_to_image_panel(obj, group_id, set_current): + historypanel.events.append("panel_mutation") + added_objects.append((obj, group_id, set_current)) + + mainwindow = SimpleNamespace( + confirm_memory_state=lambda: True, + signalpanel=SimpleNamespace(), + imagepanel=SimpleNamespace(add_object=add_to_image_panel), + historypanel=historypanel, + ) + unattended = SimpleNamespace(unattended=True, accept_dialogs=False) + image = ImageObj() + with ( + patch.object(hsess, "execenv", unattended), + patch.object( + hsess.Conf.proc.history_new_session_behavior, "get", return_value="ask" + ), + ): + added = DLMainWindow.add_object(mainwindow, image, new_session_behavior="ask") + + assert added is True + assert added_objects == [(image, "", True)] + assert historypanel.events[:3] == [ + "session_decision", + "panel_mutation", + "session_decision", + ] + assert historypanel.prompt_behaviors == ["ask", None] + assert historypanel.prompt_suppressed_states == [False, True] + assert historypanel.runtime.execution.prompt_count == 1 + assert len(historypanel.registered_outputs) == 1 + + +def test_mainwindow_add_object_preserves_no_record_and_memory_rejection() -> None: + """Keep data addition without recording and stop entirely on memory refusal.""" + image_session = make_prompt_session("image", populated=True) + historypanel = PromptPanel({"image": image_session}) + historypanel.record_mode_enabled = False + added_objects = [] + + def add_to_image_panel(obj, group_id, set_current): + added_objects.append((obj, group_id, set_current)) + + mainwindow = SimpleNamespace( + confirm_memory_state=lambda: True, + signalpanel=SimpleNamespace(), + imagepanel=SimpleNamespace(add_object=add_to_image_panel), + historypanel=historypanel, + ) + image = ImageObj() + assert DLMainWindow.add_object(mainwindow, image, new_session_behavior="no") is True + assert added_objects == [(image, "", True)] + assert historypanel.added_actions == [] + assert historypanel.registered_outputs == [] + + mainwindow.confirm_memory_state = lambda: False + assert ( + DLMainWindow.add_object(mainwindow, ImageObj(), new_session_behavior="yes") + is False + ) + assert added_objects == [(image, "", True)] + assert historypanel.prompt_behaviors == ["no"] + + def test_navigation_uses_effective_panel_for_ui_only_session() -> None: """Resolve legacy UI-only sessions from their action target.""" session = HistorySession(number=1) @@ -536,27 +714,6 @@ def test_navigation_uses_effective_panel_for_ui_only_session() -> None: assert navigation.session_panel_str(session) == "image" -def test_data_panel_load_prompts_are_target_aware() -> None: - """Require both load entry points to pass their data-panel identifier.""" - for method in (BaseDataPanel.load_from_directory, BaseDataPanel.load_from_files): - tree = ast.parse(textwrap.dedent(inspect.getsource(method))) - calls = [ - node - for node in ast.walk(tree) - if isinstance(node, ast.Call) - and isinstance(node.func, ast.Attribute) - and node.func.attr == "maybe_start_session_for_input" - ] - assert len(calls) == 1 - keywords = {keyword.arg: keyword.value for keyword in calls[0].keywords} - panel_str = keywords["panel_str"] - assert isinstance(panel_str, ast.Attribute) - assert isinstance(panel_str.value, ast.Name) - assert (panel_str.value.id, panel_str.attr) == ("self", "PANEL_STR_ID") - load = keywords["load"] - assert isinstance(load, ast.Constant) and load.value is True - - def test_action_hdf5_current_and_legacy_contract() -> None: """Round-trip current fields and apply all legacy defaults.""" action = build_history_action() diff --git a/datalab/tests/features/plugins/plugin_history_policy_unit_test.py b/datalab/tests/features/plugins/plugin_history_policy_unit_test.py new file mode 100644 index 000000000..d6deea2dd --- /dev/null +++ b/datalab/tests/features/plugins/plugin_history_policy_unit_test.py @@ -0,0 +1,491 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +"""Pure unit contracts for plugin input history policies.""" + +from __future__ import annotations + +import importlib.util +from contextlib import contextmanager +from pathlib import Path +from types import SimpleNamespace +from typing import Any, Generator, cast +from unittest.mock import patch + +import numpy as np +import pytest +from sigima import ImageObj, SignalObj +from sigima.io.image import ImageIORegistry +from sigima.io.signal import SignalIORegistry + +from datalab.config import Conf +from datalab.control.proxy import LocalProxy +from datalab.gui import historysession_ops as hsess +from datalab.gui.main import DLMainWindow +from datalab.plugins import PluginRegistry + +testdata_path = Path(__file__).parents[3] / "plugins" / "datalab_testdata.py" +testdata_spec = importlib.util.spec_from_file_location( + "datalab_testdata", testdata_path +) +if testdata_spec is None or testdata_spec.loader is None: + raise ImportError(f"Unable to load test data plugin from {testdata_path}") +testdata_plugin = importlib.util.module_from_spec(testdata_spec) +testdata_spec.loader.exec_module(testdata_plugin) +PluginTestData = testdata_plugin.PluginTestData + + +class AddCallRecorder: + """Record object-add calls received from a local proxy.""" + + def __init__(self) -> None: + self.calls: list[tuple[str, hsess.SessionBehavior | None]] = [] + + def add_object( + self, + obj: SignalObj | ImageObj, + group_id: str = "", + set_current: bool = True, + new_session_behavior: hsess.SessionBehavior | None = None, + ) -> bool: + """Record an object add.""" + del obj, group_id, set_current + self.calls.append(("object", new_session_behavior)) + return True + + def add_signal( + self, *args: Any, new_session_behavior: hsess.SessionBehavior | None = None + ) -> bool: + """Record a signal add.""" + del args + self.calls.append(("signal", new_session_behavior)) + return True + + def add_image( + self, *args: Any, new_session_behavior: hsess.SessionBehavior | None = None + ) -> bool: + """Record an image add.""" + del args + self.calls.append(("image", new_session_behavior)) + return True + + +class HistoryPromptRecorder: + """Record prompt evaluations and suppression state for multi-load tests.""" + + def __init__(self) -> None: + self.suppressed = False + self.calls: list[tuple[str, bool, hsess.SessionBehavior | None, bool]] = [] + self.decision_count = 0 + + def maybe_start_session_for_input( + self, + panel_str: str | None = None, + *, + load: bool = False, + behavior: hsess.SessionBehavior | None = None, + ) -> bool: + """Record a validated session-policy evaluation.""" + if behavior is not None and behavior not in hsess.SESSION_BEHAVIORS: + raise ValueError(f"Invalid session behavior: {behavior!r}") + assert panel_str is not None + self.calls.append((panel_str, load, behavior, self.suppressed)) + if not self.suppressed and behavior != "no": + self.decision_count += 1 + return False + + def add_ui_entry( + self, + action_title: str, + target: str, + method_name: str, + save_state: bool = True, + ) -> None: + """Record the nested creation evaluation from the main window.""" + del action_title, method_name, save_state + panel_str = "signal" if target == "signalpanel" else "image" + self.maybe_start_session_for_input(panel_str=panel_str) + + @contextmanager + def session_prompt_suppressed(self) -> Generator[None, None, None]: + """Suppress decisions while preserving nested context state.""" + previous = self.suppressed + self.suppressed = True + try: + yield + finally: + self.suppressed = previous + + +class MultiLoadMainRecorder: + """Exercise the production main-window boundary for local proxy adds.""" + + def __init__(self) -> None: + self.historypanel = HistoryPromptRecorder() + self.memory_allowed = True + self.memory_confirmation_count = 0 + self.added_objects: list[SignalObj | ImageObj] = [] + self.signalpanel = SimpleNamespace(add_object=self.record_signal_object) + self.imagepanel = SimpleNamespace(add_object=self.record_image_object) + + def confirm_memory_state(self) -> bool: + """Return the controlled memory confirmation result.""" + self.memory_confirmation_count += 1 + return self.memory_allowed + + def record_signal_object( + self, obj: SignalObj, group_id: str, set_current: bool + ) -> None: + """Record a signal panel mutation.""" + del group_id, set_current + assert isinstance(obj, SignalObj) + self.added_objects.append(obj) + + def record_image_object( + self, obj: ImageObj, group_id: str, set_current: bool + ) -> None: + """Record an image panel mutation.""" + del group_id, set_current + assert isinstance(obj, ImageObj) + self.added_objects.append(obj) + + def add_object( + self, + obj: SignalObj | ImageObj, + group_id: str = "", + set_current: bool = True, + new_session_behavior: hsess.SessionBehavior | None = None, + ) -> bool: + """Add an object through the production main-window method.""" + return DLMainWindow.add_object( + as_mainwindow(self), + obj, + group_id, + set_current, + new_session_behavior, + ) + + def add_signal( + self, *args: Any, new_session_behavior: hsess.SessionBehavior | None = None + ) -> bool: + """Add a signal through the production main-window method.""" + return DLMainWindow.add_signal( + as_mainwindow(self), *args, new_session_behavior=new_session_behavior + ) + + def add_image( + self, *args: Any, new_session_behavior: hsess.SessionBehavior | None = None + ) -> bool: + """Add an image through the production main-window method.""" + return DLMainWindow.add_image( + as_mainwindow(self), *args, new_session_behavior=new_session_behavior + ) + + +class PluginProxyRecorder: + """Record the Test Data plugin's batch scope and object ordering.""" + + def __init__(self) -> None: + self.events: list[tuple[str, object]] = [] + + @contextmanager + def multiload_session( + self, panel: str, new_session_behavior: hsess.SessionBehavior | None = None + ) -> Generator[None, None, None]: + """Record entry and exit of a plugin multi-load context.""" + del new_session_behavior + self.events.append(("enter", panel)) + try: + yield + finally: + self.events.append(("exit", panel)) + + def add_object(self, obj: object) -> None: + """Record an object in insertion order.""" + self.events.append(("add", obj)) + + +class ProgressRecorder: + """Controllable progress-bar context for plugin load tests.""" + + def __init__(self, cancel_states: list[bool]) -> None: + self.cancel_states = iter(cancel_states) + self.values: list[int] = [] + + def __enter__(self) -> ProgressRecorder: + return self + + def __exit__(self, *args: Any) -> None: + del args + + def setValue(self, value: int) -> None: # pylint: disable=invalid-name + """Record a progress value.""" + self.values.append(value) + + def wasCanceled(self) -> bool: # pylint: disable=invalid-name + """Return the next controlled cancellation state.""" + return next(self.cancel_states, False) + + +def as_mainwindow(mainwindow: object) -> DLMainWindow: + """Cast a pure test double to the local proxy's window interface.""" + return cast("DLMainWindow", mainwindow) + + +def test_local_proxy_resolves_plugin_policy_live_and_explicit_wins() -> None: + """Read plugin policy per add while preserving explicit priority.""" + mainwindow = AddCallRecorder() + proxy = LocalProxy(as_mainwindow(mainwindow), input_source="plugin") + option = Conf.proc.history_plugin_new_session_behavior + xdata = np.array([0.0, 1.0]) + ydata = np.array([1.0, 2.0]) + + with patch.object(option, "get", side_effect=["yes", "no"]) as get_behavior: + proxy.add_object(SignalObj()) + proxy.add_signal("signal", xdata, ydata) + proxy.add_image("image", np.ones((2, 2)), new_session_behavior="ask") + + assert mainwindow.calls == [ + ("object", "yes"), + ("signal", "no"), + ("image", "ask"), + ] + assert get_behavior.call_count == 2 + + local_mainwindow = AddCallRecorder() + LocalProxy(as_mainwindow(local_mainwindow)).add_object(ImageObj()) + assert local_mainwindow.calls == [("object", None)] + + +def test_plugin_registration_marks_proxy_for_live_plugin_policy() -> None: + """Create plugin proxies with the plugin input source marker.""" + plugin = PluginTestData() + mainwindow = AddCallRecorder() + option = Conf.proc.history_plugin_new_session_behavior + + with patch.object(PluginRegistry, "register_plugin"): + plugin.register(as_mainwindow(mainwindow)) + + assert plugin.proxy.input_source == "plugin" + with patch.object(option, "get", return_value="no") as get_behavior: + plugin.proxy.add_object(ImageObj()) + assert mainwindow.calls == [("object", "no")] + get_behavior.assert_called_once_with() + + +def test_plugin_multiload_decides_once_and_suppresses_internal_adds() -> None: + """Apply the batch policy once and use no for later additions.""" + mainwindow = MultiLoadMainRecorder() + proxy = LocalProxy(as_mainwindow(mainwindow), input_source="plugin") + multiload_option = Conf.proc.history_plugin_multiload_behavior + add_option = Conf.proc.history_plugin_new_session_behavior + first = SignalObj() + second = SignalObj() + + with ( + patch.object(multiload_option, "get", return_value="ask") as get_multiload, + patch.object(add_option, "get", return_value="no") as get_add, + ): + with proxy.multiload_session("signal"): + assert proxy.add_object(first) is True + assert proxy.add_object(second) is True + + assert mainwindow.added_objects == [first, second] + assert mainwindow.historypanel.calls == [ + ("signal", False, "ask", False), + ("signal", False, None, True), + ("signal", False, "no", False), + ("signal", False, None, True), + ] + assert mainwindow.historypanel.decision_count == 1 + assert mainwindow.historypanel.suppressed is False + assert proxy.multiload_state is None + get_multiload.assert_called_once_with() + get_add.assert_not_called() + + +def test_multiload_validates_inputs_and_explicit_policy_wins() -> None: + """Validate batch inputs before yielding and prioritize explicit policy.""" + mainwindow = MultiLoadMainRecorder() + proxy = LocalProxy(as_mainwindow(mainwindow), input_source="plugin") + option = Conf.proc.history_plugin_multiload_behavior + + with patch.object(option, "get") as get_behavior: + with proxy.multiload_session("image", new_session_behavior="no"): + assert proxy.multiload_state is not None + assert proxy.multiload_state.panel == "image" + assert proxy.multiload_state.behavior == "no" + assert proxy.multiload_state.decision_applied is False + get_behavior.assert_not_called() + assert proxy.multiload_state is None + assert mainwindow.historypanel.calls == [] + + with pytest.raises(ValueError, match="Invalid data panel"): + with proxy.multiload_session(cast(Any, "macro")): + pass + with pytest.raises(ValueError, match="Invalid session behavior"): + with proxy.multiload_session("signal", cast(hsess.SessionBehavior, "invalid")): + pass + + with proxy.multiload_session("signal", "ask"): + outer_state = proxy.multiload_state + with pytest.raises(RuntimeError, match="Nested multiload sessions"): + with proxy.multiload_session("image", "no"): + pass + assert proxy.multiload_state is outer_state + assert proxy.multiload_state is None + + +def test_multiload_defers_empty_and_pre_add_exception_decisions() -> None: + """Leave history untouched when a batch never attempts an insertion.""" + mainwindow = MultiLoadMainRecorder() + proxy = LocalProxy(as_mainwindow(mainwindow), input_source="plugin") + option = Conf.proc.history_plugin_multiload_behavior + + with patch.object(option, "get", return_value="ask") as get_behavior: + with proxy.multiload_session("signal"): + pass + with pytest.raises(ValueError, match="before first add"): + with proxy.multiload_session("image"): + raise ValueError("before first add") + + assert get_behavior.call_count == 2 + assert proxy.multiload_state is None + assert mainwindow.memory_confirmation_count == 0 + assert mainwindow.historypanel.calls == [] + assert mainwindow.added_objects == [] + + +def test_multiload_memory_rejection_does_not_consume_first_decision() -> None: + """Defer the batch decision until an object passes memory confirmation.""" + mainwindow = MultiLoadMainRecorder() + proxy = LocalProxy(as_mainwindow(mainwindow), input_source="plugin") + rejected = SignalObj() + accepted = SignalObj() + + with proxy.multiload_session("signal", "ask"): + mainwindow.memory_allowed = False + assert proxy.add_object(rejected) is False + assert proxy.multiload_state is not None + assert proxy.multiload_state.decision_applied is False + mainwindow.memory_allowed = True + assert proxy.add_object(accepted) is True + assert proxy.multiload_state.decision_applied is True + + assert mainwindow.memory_confirmation_count == 2 + assert mainwindow.added_objects == [accepted] + assert mainwindow.historypanel.calls == [ + ("signal", False, "ask", False), + ("signal", False, None, True), + ] + assert mainwindow.historypanel.decision_count == 1 + + +def test_multiload_rejects_panel_mismatch_before_mainwindow_mutation() -> None: + """Reject an object from another panel before memory or history changes.""" + mainwindow = MultiLoadMainRecorder() + proxy = LocalProxy(as_mainwindow(mainwindow), input_source="plugin") + + with proxy.multiload_session("signal", "ask"): + with pytest.raises(ValueError, match="during a signal multiload session"): + proxy.add_object(ImageObj()) + + assert mainwindow.memory_confirmation_count == 0 + assert mainwindow.historypanel.calls == [] + assert mainwindow.added_objects == [] + + +def test_typed_adds_report_memory_rejection() -> None: + """Keep add_signal and add_image return values truthful on rejection.""" + mainwindow = MultiLoadMainRecorder() + mainwindow.memory_allowed = False + proxy = LocalProxy(as_mainwindow(mainwindow)) + xdata = np.array([0.0, 1.0]) + ydata = np.array([1.0, 2.0]) + + assert proxy.add_signal("signal", xdata, ydata) is False + assert proxy.add_image("image", np.ones((2, 2))) is False + assert mainwindow.memory_confirmation_count == 2 + assert mainwindow.historypanel.calls == [] + assert mainwindow.added_objects == [] + + +@pytest.mark.parametrize( + ("registry_class", "panel_str", "panel_attribute"), + ( + (SignalIORegistry, "signal", "signalpanel"), + (ImageIORegistry, "image", "imagepanel"), + ), +) +def test_testdata_multiload_selects_registry_panel_and_preserves_order( + registry_class, panel_str: str, panel_attribute: str +) -> None: + """Select the registry's panel and preserve progress and object order.""" + plugin = PluginTestData() + signalpanel = object() + imagepanel = object() + plugin.main = cast( + Any, SimpleNamespace(signalpanel=signalpanel, imagepanel=imagepanel) + ) + proxy = PluginProxyRecorder() + plugin.proxy = cast(LocalProxy, proxy) + first = object() + second = object() + progress = ProgressRecorder([False, False]) + progress_calls = [] + + def create_progress(parent, title, max_): + progress_calls.append((parent, title, max_)) + return progress + + with ( + patch.object( + testdata_plugin.helpers, + "read_test_objects", + return_value=[("first", first), ("second", second)], + ), + patch.object(testdata_plugin, "create_progress_bar", create_progress), + ): + plugin.load_test_objs(registry_class, "Load objects") + + expected_panel = getattr(plugin.main, panel_attribute) + assert progress_calls == [(expected_panel, "Load objects", 2)] + assert progress.values == [1, 2] + assert proxy.events == [ + ("enter", panel_str), + ("add", first), + ("add", second), + ("exit", panel_str), + ] + + +def test_testdata_multiload_preserves_immediate_cancellation() -> None: + """Leave the lazy batch empty when progress is cancelled immediately.""" + plugin = PluginTestData() + signalpanel = object() + plugin.main = cast( + Any, SimpleNamespace(signalpanel=signalpanel, imagepanel=object()) + ) + proxy = PluginProxyRecorder() + plugin.proxy = cast(LocalProxy, proxy) + first = object() + second = object() + progress = ProgressRecorder([True]) + + with ( + patch.object( + testdata_plugin.helpers, + "read_test_objects", + return_value=[ + ("first", first), + ("second", second), + ], + ), + patch.object(testdata_plugin, "create_progress_bar", return_value=progress), + ): + plugin.load_test_objs(SignalIORegistry, "Load signals") + + assert progress.values == [1] + assert proxy.events == [ + ("enter", "signal"), + ("exit", "signal"), + ] From 72c029fa37dca573ae2c4fee8ce9dc74d56a7a27 Mon Sep 17 00:00:00 2001 From: Stefano Pierini <s.pierini@codra.fr> Date: Wed, 5 Aug 2026 11:46:33 +0200 Subject: [PATCH 068/108] Fix: Correct formatting of PlotPy library references in laser beam tutorial --- doc/intro/tutorials/laser_beam.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/intro/tutorials/laser_beam.rst b/doc/intro/tutorials/laser_beam.rst index bd997fa56..63c84600c 100644 --- a/doc/intro/tutorials/laser_beam.rst +++ b/doc/intro/tutorials/laser_beam.rst @@ -109,7 +109,8 @@ it beneficial to apply a threshold to the images. Several methods are available to estimate the background noise level. One approach utilizes the "Cross section" tool, which is provided by the -`PlotPy <https://github.com/PlotPyStack/plotpy>` library that DataLab uses for signal and image visualization. +`PlotPy <https://github.com/PlotPyStack/plotpy>`__ library that DataLab uses +for signal and image visualization. Select an image from the "Image panel", choose the corresponding image in the visualization panel, and activate the "Cross section" tool |cross_section| from the vertical toolbar on the left side of the visualization panel. This @@ -123,7 +124,8 @@ reveals that the background noise level is approximately 30 lsb. select the profile curve and right-click to open the context menu, then choose "Markers > Bound to active item". -Another method for measuring background noise, also provided by `PlotPy <https://github.com/PlotPyStack/plotpy>`, involves using the "Image statistics" tool +Another method for measuring background noise, also provided by +`PlotPy <https://github.com/PlotPyStack/plotpy>`__, involves using the "Image statistics" tool |imagestats| from the vertical toolbar on the left side of the visualization panel. This tool displays statistical information for a rectangular region that you define by dragging the mouse across the image. This analysis confirms that the background noise level is approximately 30 lsb. From 513a4502976914ef551d87ca6a836fb7a95ddd2f Mon Sep 17 00:00:00 2001 From: Stefano Pierini <s.pierini@codra.fr> Date: Wed, 5 Aug 2026 11:47:26 +0200 Subject: [PATCH 069/108] Fix: Clarify behavior of image modification options in laser beam tutorial --- doc/intro/tutorials/laser_beam.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/intro/tutorials/laser_beam.rst b/doc/intro/tutorials/laser_beam.rst index 63c84600c..42e39e913 100644 --- a/doc/intro/tutorials/laser_beam.rst +++ b/doc/intro/tutorials/laser_beam.rst @@ -91,6 +91,11 @@ To pan the image, use the middle mouse button while dragging. operation sets all image origins to match the first image's origin, which means any initial differences in image origins will be lost. + Both the "Distribute on a grid" and "Reset image positions" options + modify the images in place, without creating new images. For this + reason, they are not registered in the History Panel, which only + lists newly created objects. + .. |distribute_on_grid| image:: ../../../datalab/data/icons/processing/distribute_on_grid.svg :width: 24px :height: 24px From f30d4b638fa3b5b917b669e74dd680cbcb26c366 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Wed, 5 Aug 2026 12:33:39 +0200 Subject: [PATCH 070/108] Doc: Complete History Panel documentation and accuracy fixes The History Panel reference had drifted from the implemented session model and left key workflows underspecified, while French terminology and screenshots no longer consistently matched the UI. A full documentation and runtime audit now describes the actual behavior and fixes three user-visible inconsistencies revealed while regenerating the localized captures. Validation covers six targeted tests, Ruff, Sphinx EN/FR with warnings treated as errors, all 1,360 UI gettext messages, 306 active French documentation entries without fuzzy or empty translations, and a clean diff check. * [NEW] : Document session lifecycle, all 11 History commands, tree selection and navigation, replay, duplication, HDF5/.dlhist persistence, deletion and reconnection, and auto-recompute across the overview, panel, and settings references * [CHG] : Harmonize French documentation with UI terminology and regenerate localized English and French History Panel screenshots * [CHG] : Correct History comments and docstrings for recording defaults, object mappings, replay selection, duplication, import, and compatibility semantics * [FIX] : Show an empty UI-action description when its callable cannot be resolved instead of displaying documentation for None * [FIX] : Preserve localized operation titles in N-to-1 history entries * [FIX] : Make tree double-click replay the current selection without restoring the recorded workspace selection * [NEW] : Add focused regression coverage for the three corrected behaviors --- datalab/config.py | 4 +- datalab/gui/historysession_ops.py | 22 +-- datalab/gui/historytools_ops.py | 7 +- datalab/gui/main.py | 8 +- datalab/gui/panel/base.py | 13 +- datalab/gui/panel/history/chainmodel.py | 11 +- datalab/gui/panel/history/facade.py | 5 +- datalab/gui/panel/history/ui.py | 6 +- datalab/gui/processor/base.py | 2 +- datalab/h5/history.py | 16 +- datalab/history/action.py | 69 ++++---- datalab/history/session.py | 12 +- datalab/history/workspace_state.py | 14 +- .../common/history_model_unit_test.py | 94 +++++++++- .../features/common/history_panel_app_test.py | 1 + doc/features/common/historypanel.rst | 137 +++++++++------ doc/features/common/overview.rst | 22 ++- doc/features/common/settings.rst | 43 ++++- doc/images/shots/history_panel.en.png | Bin 0 -> 63172 bytes doc/images/shots/history_panel.fr.png | Bin 0 -> 61790 bytes .../features/common/historypanel.po | 160 +++++++++++------- .../LC_MESSAGES/features/common/overview.po | 12 +- .../LC_MESSAGES/features/common/settings.po | 69 +++++++- 23 files changed, 513 insertions(+), 214 deletions(-) create mode 100644 doc/images/shots/history_panel.en.png create mode 100644 doc/images/shots/history_panel.fr.png diff --git a/datalab/config.py b/datalab/config.py index eb98eab5e..b984fa665 100644 --- a/datalab/config.py +++ b/datalab/config.py @@ -298,8 +298,8 @@ class ProcSection(conf.Section, metaclass=conf.SectionMeta): ignore_warnings = conf.Option() # Automatically start recording history at DataLab launch: - # - True: history recording is enabled at startup (default) - # - False: user must enable it manually via the History panel toolbar + # - True: history recording is enabled at startup + # - False: user must enable it manually via the History panel toolbar (default) history_auto_record = conf.Option() # History session behavior for new inputs: diff --git a/datalab/gui/historysession_ops.py b/datalab/gui/historysession_ops.py index d7d04d658..2f123ae53 100644 --- a/datalab/gui/historysession_ops.py +++ b/datalab/gui/historysession_ops.py @@ -147,10 +147,11 @@ def add_compute_entry( save_state: If True, capture the workspace state for replay. output_uuids: Optional list of UUIDs of the data objects produced by this action. When known at call time, prefer passing it here so the - bijective mapping is initialised in one step. Most callers do not - know the outputs yet and instead wrap the compute call with - :meth:`capture_outputs` (or call :meth:`register_action_outputs` - explicitly afterwards) using the returned action. + action-to-outputs mapping and inverse output lookup are initialised in + one step. Most callers do not know the outputs yet and instead wrap + the compute call with :meth:`capture_outputs` (or call + :meth:`register_action_outputs` explicitly afterwards) using the + returned action. plugin_origin: Optional plugin origin descriptor (see :func:`datalab.gui.processor.base._detect_plugin_origin`). ``None`` for built-in Sigima/DataLab features. @@ -245,15 +246,16 @@ def register_action_outputs( ) -> None: """Register the data objects produced by ``action``. - Maintains the bijective ``action → outputs`` and ``output → action`` - mappings. May be called multiple times for a given action (later calls - replace earlier ones, e.g. after a cascade recompute). + Maintains the ``action → outputs`` mapping and inverse ``output → action`` + lookup. One action may produce multiple outputs. May be called multiple + times for a given action (later calls replace earlier ones, e.g. after a + cascade recompute). Args: action: The history action that produced the outputs. output_uuids: UUIDs of the produced data objects (empty for - ``1_to_0`` analysis patterns and for UI actions that did not - create new objects). + ``1_to_0`` analysis patterns and UI actions without new objects; + output-producing UI actions may provide one or more UUIDs). """ panel.runtime.objects.register_action_outputs(action, output_uuids) @@ -316,7 +318,7 @@ def add_ui_entry( Args: action_title: Title shown in the history tree. target: One of ``"mainwindow"``, ``"signalpanel"``, ``"imagepanel"``, - ``"historypanel"`` -- attribute path on the main window. + ``"historypanel"``, ``"signalprocessor"``, or ``"imageprocessor"``. method_name: Method name to call on ``target`` at replay time. save_state: If True, capture the workspace state for replay. **kwargs: Method keyword arguments. ``DataSet`` instances are diff --git a/datalab/gui/historytools_ops.py b/datalab/gui/historytools_ops.py index b34247827..e84c0e8a0 100644 --- a/datalab/gui/historytools_ops.py +++ b/datalab/gui/historytools_ops.py @@ -53,8 +53,9 @@ def make_initial_state_head(pstr: str, clone_uuid: str, title: str) -> HistoryAc UI action is prepended, standing in for that missing object creation. Its empty workspace state mirrors a real ``new_object`` recorded with ``save_state=False`` (hence always compatible), and its ``new_object`` - method name places it in :attr:`HistoryAction.UI_CREATION_METHODS` so - :func:`build_session_chains` treats it as a genuine chain root. + method name places it in :attr:`HistoryAction.UI_CREATION_METHODS`. Because + it is prepended, :func:`build_session_chains` treats it as the first + chronological action and therefore as the chain root. Args: pstr: Panel string of the created object (``"signal"``/``"image"``). @@ -130,7 +131,7 @@ def resolve_chain_selection(panel: HistoryPanel) -> list[ChainSelectionPlan]: def collect_referenced_uuids(chains: list[ProcessingChain]) -> dict[str, set[str]]: - """Collect object UUIDs referenced or produced by selected chains.""" + """Collect referenced/produced UUIDs and all captured metadata UUIDs.""" uuids_by_panel: dict[str, set[str]] = {} for chain in chains: for action in chain.actions: diff --git a/datalab/gui/main.py b/datalab/gui/main.py index d4d6e8a2c..68d36881b 100644 --- a/datalab/gui/main.py +++ b/datalab/gui/main.py @@ -2263,11 +2263,11 @@ def browse_h5_files(self, filenames: list[str], reset_all: bool) -> None: @remote_controlled def load_h5_workspace(self, h5files: list[str], reset_all: bool = False) -> None: - """Load native DataLab HDF5 workspace files without any GUI elements. + """Load native DataLab HDF5 workspace files programmatically. - This method can be safely called from the internal console as it does not - create any Qt widgets, dialogs, or progress bars. It is designed for - programmatic use when loading DataLab workspace files. + This method does not create file-selection widgets or progress bars. When + history recording is active and the new-session policy is ``"ask"``, a + history-session question may still be shown before loading. .. warning:: diff --git a/datalab/gui/panel/base.py b/datalab/gui/panel/base.py index 91d701e19..e46290abc 100644 --- a/datalab/gui/panel/base.py +++ b/datalab/gui/panel/base.py @@ -1401,7 +1401,8 @@ def deserialize_object_from_hdf5( reader: HDF5 reader name: Object name in HDF5 file reset_all: If True, preserve original UUIDs (workspace reload). - If False, regenerate UUIDs (importing objects). + If False, regenerate only UUIDs that conflict with existing + objects (object import). """ with reader.group(name): obj = self.create_object() @@ -1429,7 +1430,8 @@ def deserialize_from_hdf5( Args: reader: HDF5 reader reset_all: If True, preserve original UUIDs (workspace reload). - If False, regenerate UUIDs (importing objects). + If False, regenerate only UUIDs that conflict with existing + objects (object import). """ @abc.abstractmethod @@ -1905,7 +1907,8 @@ def deserialize_from_hdf5( Args: reader: HDF5 reader reset_all: If True, preserve original UUIDs (workspace reload). - If False, regenerate UUIDs (importing objects). + If False, regenerate only UUIDs that conflict with existing + objects (object import). """ with reader.group(self.H5_PREFIX): for name in reader.h5.get(self.H5_PREFIX, []): @@ -2629,7 +2632,7 @@ def set_current_object_title(self, title: str) -> None: def __load_from_file( self, filename: str, create_group: bool = True, add_objects: bool = True ) -> list[SignalObj] | list[ImageObj]: - """Open objects from file (signal/image), add them to DataLab and return them. + """Open and return objects from file, optionally adding them to DataLab. Args: filename: file name @@ -2741,7 +2744,7 @@ def load_from_files( add_objects: bool = True, ignore_errors: bool = False, ) -> list[TypeObj]: - """Open objects from file (signals/images), add them to DataLab and return them. + """Open and return objects from files, optionally adding them to DataLab. Args: filenames: File names diff --git a/datalab/gui/panel/history/chainmodel.py b/datalab/gui/panel/history/chainmodel.py index 2ad6e49c1..bf161fd35 100644 --- a/datalab/gui/panel/history/chainmodel.py +++ b/datalab/gui/panel/history/chainmodel.py @@ -157,13 +157,12 @@ def remap_processing_parameters( def build_session_chains(session: HistorySession) -> list[ProcessingChain]: - """Return the session's single processing chain. + """Return the session as one chronological processing chain. - In DataLab's history model a session **is** a single linear processing - chain: every action of the session belongs to one chain, the first action - being its root. Session boundaries are decided at recording time (the - "start a new history session?" prompt shown on object creation), so no - per-creation splitting is performed here. + The current History Panel read model treats every non-empty session as one + ordered chain rooted at its first action. Recording policy choices can place + independent roots in the same session; this function intentionally does not + split them. Args: session: The session whose actions form the chain. diff --git a/datalab/gui/panel/history/facade.py b/datalab/gui/panel/history/facade.py index a6a178247..d0b8a57c7 100644 --- a/datalab/gui/panel/history/facade.py +++ b/datalab/gui/panel/history/facade.py @@ -89,7 +89,10 @@ def replaying(self) -> Generator[None, None, None]: yield def is_replaying(self) -> bool: - """Return whether an external replay or recompute is in progress.""" + """Return whether the replaying guard is active. + + Cascade recomputation uses separate state and is not reported here. + """ return self.runtime.execution.replaying_active @contextmanager diff --git a/datalab/gui/panel/history/ui.py b/datalab/gui/panel/history/ui.py index d47664c29..a9ba57983 100644 --- a/datalab/gui/panel/history/ui.py +++ b/datalab/gui/panel/history/ui.py @@ -145,7 +145,11 @@ def setup_connections(self) -> None: """Connect history-tree interactions to their owning components.""" tree = self.panel.tree tree.customContextMenuRequested.connect(self.show_context_menu) - tree.itemDoubleClicked.connect(self.panel.replay_restore_actions) + tree.itemDoubleClicked.connect( + lambda _item, _column: self.panel.replay_restore_actions( + restore_selection=False + ) + ) tree.itemSelectionChanged.connect(self.panel.navigation.sync_panel_selection) tree.itemSelectionChanged.connect(self.update_actions_state) tree.itemSelectionChanged.connect(self.panel.navigation.update_state_widget) diff --git a/datalab/gui/processor/base.py b/datalab/gui/processor/base.py index 875c8111a..be9fb1296 100644 --- a/datalab/gui/processor/base.py +++ b/datalab/gui/processor/base.py @@ -2257,7 +2257,7 @@ def compute_n_to_1( pp_history = build_processing_parameters(name, "n-to-1", param=param) action = self.mainwindow.historypanel.add_compute_entry_from_pp( - name, + title or name, pp_history, panel_str=self.panel.PANEL_STR_ID, pairwise=pairwise, diff --git a/datalab/h5/history.py b/datalab/h5/history.py index 23c7d20b4..590c8b61a 100644 --- a/datalab/h5/history.py +++ b/datalab/h5/history.py @@ -71,6 +71,10 @@ def save_to_dlhist_file(panel: HistoryPanel, filename: str | None = None) -> boo def open_dlhist_file(panel: HistoryPanel, filename: str | None = None) -> bool: """Open a standalone ``.dlhist`` file into the History Panel. + A pristine workspace directly restores the saved signal/image objects and + history sessions. In a workspace already in use, objects are restored into + new groups and one imported session is appended for each source session. + Args: filename: History filename. If None, a file dialog is opened. @@ -100,12 +104,12 @@ def open_dlhist_file(panel: HistoryPanel, filename: str | None = None) -> bool: or bool(panel.history_sessions) ) if workspace_in_use: - # Workspace not empty: import the objects into new groups + # Workspace already in use: import the objects into new groups # with fresh UUIDs and append the history as new sessions # whose references are remapped to the imported objects. panel.import_dlhist_into_new_session(reader) else: - # Workspace empty: load directly, preserving original UUIDs + # Pristine workspace: load directly, preserving original UUIDs # (reset_all=True) so that history references stay valid. panel.mainwindow.signalpanel.deserialize_from_hdf5( reader, reset_all=True @@ -260,7 +264,7 @@ def update_imported_history_ui( def import_dlhist_into_new_session(panel: HistoryPanel, reader: NativeH5Reader) -> None: - """Import a ``.dlhist`` file into new groups and new history sessions. + """Import into new groups and one new session per source history session. Args: reader: HDF5 reader positioned on a ``.dlhist`` file. @@ -312,9 +316,9 @@ def deserialize_from_hdf5( ) if panel.history_sessions: panel.navigation.session_increment = panel.history_sessions[-1].number - # Rebuild the bijective mapping from the loaded actions. Legacy - # (v1) actions have empty ``output_uuids`` and contribute nothing - # to the index — the heuristic fallback handles them. + # Rebuild the action-to-outputs mapping and inverse output lookup. Legacy + # actions/files without ``output_uuids`` contribute nothing to the index; + # the heuristic fallback handles them. for session in panel.history_sessions: for action in session.actions: if action.output_uuids: diff --git a/datalab/history/action.py b/datalab/history/action.py index 2c1f8f3bf..47e6ea0cc 100644 --- a/datalab/history/action.py +++ b/datalab/history/action.py @@ -80,7 +80,8 @@ class HistoryAction(ObjItf): An action is a serialisable description of either a *compute* call (resolved via the panel processor's feature registry) or a *UI* call (resolved as a - method on a known target -- ``mainwindow``/``signalpanel``/``imagepanel``). + method on a known target: ``mainwindow``, ``signalpanel``, ``imagepanel``, + ``historypanel``, ``signalprocessor``, or ``imageprocessor``). No Python ``Callable`` is ever pickled: a compute action is identified by ``(panel_str, func_name, pattern)`` and a UI action by ``(target, @@ -92,8 +93,8 @@ class HistoryAction(ObjItf): KIND_UI = "ui" FUNC_EDIT_MODE = "edit" # Name of the function parameter to enable edit mode - # Methods that create new data objects. During non-persistent (output-suppressed) - # replay, these UI actions are skipped so the panel object count stays stable. + # Object-creation actions skipped during non-persistent (output-suppressed) + # replay so the panel object count stays stable. UI_CREATION_METHODS: frozenset[str] = frozenset({"new_object"}) # UI methods that destroy data objects. Replaying these requires that the # captured selection still resolves to existing objects (see ``replay_ui``). @@ -154,11 +155,12 @@ def __init__( self.dtstr: str = get_datetime_str() self.uuid: str = str(uuid4()) self.schema_version: int = HISTORY_ACTION_SCHEMA_VERSION - # UUIDs of the data objects produced by this action (bijective mapping - # maintained by :class:`HistoryPanel`). Populated post-compute via + # UUIDs of the data objects produced by this action. One action may have + # multiple outputs; the history runtime also maintains an inverse output + # lookup. Populated after output-producing compute or UI actions via # :meth:`HistoryPanel.register_action_outputs`. Empty for ``1_to_0`` - # patterns, for UI actions, and for sessions loaded without output info - # loaded from disk (the heuristic fallback then takes over). + # patterns, UI actions without new objects, and legacy actions/files + # lacking output information (the heuristic fallback then takes over). self.output_uuids: list[str] = [] # Plugin origin descriptor for compute actions (None for built-in # Sigima/DataLab features). Populated at registration time by @@ -172,10 +174,10 @@ def __init__( self.is_stale: bool = False # Snapshot of original kwargs before edit-mode modification. # Set lazily when the first edit-mode change touches this action. - # Persisted to HDF5 so that the Restore - # action still works after a save/reload cycle while Edit mode is - # active. Cleared by ``discard_snapshot`` (definitive commit when - # toggling Edit mode off) or ``restore_kwargs`` (Restore button). + # Persisted to HDF5 so the pre-edit values remain available after a + # save/reload cycle while Edit mode is active. Cleared by + # ``discard_snapshot`` (definitive commit when toggling Edit mode off) + # or ``restore_kwargs`` during parameter rollback. self.saved_kwargs: dict[str, Any] | None = None def snapshot_kwargs(self) -> None: @@ -248,7 +250,10 @@ def effective_panel_str(self) -> str: def copy_with_uuid_remap( self, uuid_remap: dict[str, dict[str, str]] ) -> HistoryAction: - """Return a copy of this action with all captured UUIDs rewritten. + """Return a copy with supported object UUID references rewritten. + + State selections and metadata, ``obj2_uuids``, and ``output_uuids`` are + remapped. Other UI keyword arguments are preserved. Args: uuid_remap: Per-panel mapping ``{panel_str: {old_uuid: new_uuid}}`` @@ -256,7 +261,8 @@ def copy_with_uuid_remap( the Duplicate operation. Returns: - A new independent :class:`HistoryAction` with remapped UUIDs. + A new independent :class:`HistoryAction` with supported UUID + references remapped. """ new_action = self.copy() # Rewrite state.selection @@ -330,6 +336,8 @@ def __fallback_doc(self) -> str: ValueError, ): return "" + if func is None: + return "" doc = getattr(func, "__doc__", None) or "" return doc.splitlines()[0] if doc else "" @@ -466,16 +474,15 @@ def replay( Args: mainwindow: DataLab's main window restore_selection: True to restore the workspace selection before replaying - a UI-kind action. Ignored for compute-kind actions: their semantics - depends on which objects are selected (e.g. ``n_to_1`` aggregators - such as ``average`` require their captured multi-object selection), - so the captured selection is always restored before running the - computation. - edit: if True, always open the dialog boxes to edit parameters; if False, - use the parameters captured when the action was recorded + a UI-kind action. Compute-kind actions restore their captured + selection only when its translated UUIDs remain compatible and + resolvable; otherwise they retain the current selection. + edit: If True, request a parameter dialog for supported actions with + editable parameters. If False, use the captured parameters. uuid_remap: optional per-panel mapping ``{panel_str: {old_uuid: new_uuid}}`` - used during full-session replay to translate captured UUIDs to the - freshly-created ones. Defaults to an empty (identity) mapping. + used during full-session replay to translate captured state UUIDs, + compute operand UUIDs, and supported UI source UUIDs. Defaults to + an empty (identity) mapping. """ if uuid_remap is None: uuid_remap = {} @@ -522,8 +529,11 @@ def replay_inner( self.replay_ui(mainwindow, edit, uuid_remap) def translate_state(self, uuid_remap: dict[str, dict[str, str]]) -> WorkspaceState: - """Return a copy of ``self.state`` whose captured UUIDs have been - translated through ``uuid_remap`` (identity when no mapping).""" + """Return ``self.state`` with captured UUIDs translated. + + The original state is returned when no mapping is provided; otherwise a + translated copy is returned. + """ if not uuid_remap: return self.state translated = WorkspaceState() @@ -695,9 +705,8 @@ def serialize(self, writer: NativeH5Writer) -> None: if encoded: with writer.group("kwargs"): writer.write_dict(encoded) - # ``saved_kwargs``: persisted Edit mode snapshot so the Restore button - # keeps working after save/reload. Group omitted when there are no - # pending edits. + # Persist the Edit mode baseline across save/reload while edits are pending. + # The group is omitted when there are no pending edits. if self.saved_kwargs is not None: encoded_saved = encode_kwargs(self.saved_kwargs) # Write the group unconditionally (even when empty) so that the @@ -787,9 +796,9 @@ def deserialize_outputs_plugin_origin( action: HistoryAction, reader: NativeH5Reader, current: Any ) -> None: """Deserialize optional outputs and plugin provenance.""" - # ``output_uuids`` is present only when the action produced outputs; - # otherwise leave it empty and consumers fall back to the heuristic - # matcher. + # ``output_uuids`` is serialized only when non-empty. Outputless actions and + # legacy files without this field leave it empty, so consumers fall back to + # the heuristic matcher. if "output_uuids" in current.attrs or "output_uuids" in current: with reader.group("output_uuids"): raw_outputs = reader.read_any() diff --git a/datalab/history/session.py b/datalab/history/session.py index 75542cb7e..f2f1d1153 100644 --- a/datalab/history/session.py +++ b/datalab/history/session.py @@ -57,7 +57,7 @@ def copy( def copy_with_uuid_remap( self, title: str, uuid_remap: dict[str, dict[str, str]] ) -> HistorySession: - """Return a copy of this session with all UUIDs rewritten via ``uuid_remap``. + """Return a copy with supported UUID references rewritten via ``uuid_remap``. Used by the Duplicate operation to build an independent session whose captured object references point to the cloned data objects. @@ -67,7 +67,8 @@ def copy_with_uuid_remap( uuid_remap: Per-panel mapping ``{panel_str: {old_uuid: new_uuid}}``. Returns: - A new :class:`HistorySession` with all captured UUIDs remapped. + A new :class:`HistorySession` with supported object references + remapped. """ session = HistorySession(title=title, number=self.number) session.actions = [ @@ -109,9 +110,10 @@ def replay( Args: mainwindow: DataLab's main window - restore_selection: True to restore the workspace selection before replaying - edit: if True, always open the dialog boxes to edit parameters, if False, - use the parameters passed when creating the action + restore_selection: True to request restoration of captured selections. + Compute actions restore them only when compatible and resolvable. + edit: If True, request parameter dialogs for supported actions with + editable parameters. If False, use the captured parameters. """ panels = (mainwindow.signalpanel, mainwindow.imagepanel) replay_map = ReplayUuidMap(panels) diff --git a/datalab/history/workspace_state.py b/datalab/history/workspace_state.py index 702f4f50e..f99391b1d 100644 --- a/datalab/history/workspace_state.py +++ b/datalab/history/workspace_state.py @@ -18,9 +18,9 @@ class WorkspaceState: """Object representing the workspace state at a given time. The workspace state stores the per-panel selection of objects by **UUID** - (robust against reordering, renaming or interleaved insertions). For - informative display, it also retains the data shape and title of each - selected object at the time of capture. + (robust against reordering, renaming or interleaved insertions). Selections + remain separate from structured metadata captured for every object in each + data panel. Informative shape and title lists cover the selected objects. """ def __init__(self) -> None: @@ -37,8 +37,8 @@ def __init__(self) -> None: # value is the list of titles of the objects in the panel. The title is only # informative and is not used to determine if two objects have the same state. self.titles: dict[str, list[str]] = {} - # Structured data signatures of selected objects, keyed by panel name and UUID. - # This is the current schema used for compatibility checks. Missing metadata + # Structured data signatures of all objects, keyed by panel name and UUID. + # Compatibility checks use entries for selected objects. Missing metadata # means a pre-Gate-2 history and falls back to UUID-existence validation. self.object_metadata: dict[str, dict[str, dict[str, Any]]] = {} @@ -249,8 +249,8 @@ def restore(self, mainwindow: DLMainWindow) -> None: mainwindow: DataLab's main window Raises: - ValueError: If at least one of the saved UUIDs no longer exists in - its panel. + ValueError: If a saved UUID no longer exists in its panel or its + saved metadata (shape/dimensions) is incompatible. """ if not self.selection: return diff --git a/datalab/tests/features/common/history_model_unit_test.py b/datalab/tests/features/common/history_model_unit_test.py index f84406807..b61b4b8d1 100644 --- a/datalab/tests/features/common/history_model_unit_test.py +++ b/datalab/tests/features/common/history_model_unit_test.py @@ -9,7 +9,7 @@ from contextlib import contextmanager, nullcontext from types import SimpleNamespace from typing import cast -from unittest.mock import patch +from unittest.mock import Mock, patch import numpy as np import pytest @@ -23,10 +23,13 @@ ) from datalab.gui.main import DLMainWindow from datalab.gui.panel.history import chain as hchain +from datalab.gui.panel.history import interactive_replay as hireplay from datalab.gui.panel.history import recompute as hrec from datalab.gui.panel.history import runtime as hruntime from datalab.gui.panel.history.navigation import HistoryNavigation +from datalab.gui.panel.history.ui import HistoryPanelUI from datalab.gui.processor.base import ( + BaseProcessor, ProcessingParameters, extract_processing_parameters, insert_processing_parameters, @@ -242,6 +245,95 @@ def test_history_session_default_and_explicit_titles() -> None: translate.assert_called_once_with("Processing") +def test_ui_action_description_is_empty_when_callable_is_unresolved() -> None: + """Return no fallback description when UI callable resolution returns None.""" + action = HistoryAction(kind=HistoryAction.KIND_UI) + + with patch.object(action, "resolve_callable", return_value=None): + assert action.description == "" + + +def test_compute_n_to_1_uses_provided_history_title() -> None: + """Pass the localized operation title to the history panel.""" + history_panel = SimpleNamespace( + add_compute_entry_from_pp=Mock(return_value=object()), + capture_outputs=lambda _action: nullcontext(), + ) + processor = SimpleNamespace( + panel=SimpleNamespace( + PANEL_STR_ID="signal", + objview=SimpleNamespace( + get_sel_objects=Mock(return_value=[]), + get_sel_groups=Mock(return_value=[]), + ), + objmodel=object(), + ), + mainwindow=SimpleNamespace(historypanel=history_panel), + _get_plugin_origin_for=Mock(return_value=None), + ) + + def average(_objects: list[object]) -> None: + return None + + with patch( + "datalab.gui.processor.base.create_progress_bar", + return_value=nullcontext(Mock()), + ): + BaseProcessor.compute_n_to_1( + processor, average, title="Moyenne", pairwise=False + ) + + history_panel.add_compute_entry_from_pp.assert_called_once() + assert history_panel.add_compute_entry_from_pp.call_args.args[0] == "Moyenne" + + +@pytest.mark.parametrize("column", (0, 2)) +@pytest.mark.parametrize("selected_row", (HistoryAction(), HistorySession())) +def test_history_tree_double_click_replays_current_selection_without_restoring( + selected_row: HistoryAction | HistorySession, column: int +) -> None: + """Replay the current action or session selection from either tree column.""" + selected_row.is_current_state_compatible = Mock(return_value=True) + selected_row.replay = Mock() + clicked_row = HistoryAction() + clicked_row.replay = Mock() + tree = SimpleNamespace( + customContextMenuRequested=Mock(), + itemDoubleClicked=Mock(), + itemSelectionChanged=Mock(), + get_selected_actions_or_sessions=Mock(return_value=[selected_row]), + ) + mainwindow = object() + panel = SimpleNamespace( + tree=tree, + history_sessions=[], + mainwindow=mainwindow, + refresh_compatibility_items=Mock(), + replaying=nullcontext, + output_suppressed=nullcontext, + runtime=SimpleNamespace(execution=SimpleNamespace(edit_mode=False)), + navigation=SimpleNamespace( + sync_panel_selection=Mock(), + update_state_widget=Mock(), + set_active_session_from_selection=Mock(), + ), + ) + panel.replay_restore_actions = lambda **kwargs: hireplay.replay_restore_actions( + panel, **kwargs + ) + ui = HistoryPanelUI.__new__(HistoryPanelUI) + ui.panel = panel + + ui.setup_connections() + double_click_slot = tree.itemDoubleClicked.connect.call_args.args[0] + double_click_slot(clicked_row, column) + + selected_row.replay.assert_called_once_with( + mainwindow, restore_selection=False, edit=False + ) + clicked_row.replay.assert_not_called() + + def test_image_creation_routes_to_image_session_when_signal_is_current() -> None: """Route an image creation independently of the globally current panel.""" signal_session = make_prompt_session("signal", populated=True) diff --git a/datalab/tests/features/common/history_panel_app_test.py b/datalab/tests/features/common/history_panel_app_test.py index 917132362..96b3bbd51 100644 --- a/datalab/tests/features/common/history_panel_app_test.py +++ b/datalab/tests/features/common/history_panel_app_test.py @@ -22,6 +22,7 @@ def test_history_panel(screenshots: bool = False) -> None: """Record a representative session and grab the History Panel screenshot.""" config.reset() # Reset configuration (remove configuration file and initialize it) + config.Conf.proc.history_new_session_behavior.set("no") with datalab_test_app_context( console=False, exec_loop=not screenshots, history=True ) as win: diff --git a/doc/features/common/historypanel.rst b/doc/features/common/historypanel.rst index 5d369b438..5234813d4 100644 --- a/doc/features/common/historypanel.rst +++ b/doc/features/common/historypanel.rst @@ -21,10 +21,13 @@ list of either: A recorded session can be: -- **Replayed** in validation mode, without adding new signal/image outputs to - the workspace; -- **Duplicated and applied**, to create an explicit comparison branch with new - outputs in the signal/image panels; +- **Replayed** silently or **step by step**, with an opportunity to edit + available parameters. New outputs from computation actions are not added to + the data panels. Recorded UI actions are invoked through their own methods + and may reproduce their side effects, including creating, importing, or + duplicating objects, unless an action has a specific replay guard; +- **Duplicated** as independent processing chains in new history sessions, + with the required signal/image objects cloned as part of the operation; - **Saved to a standalone history file** (``.dlhist``) or **embedded in the workspace** when saving to HDF5, so that the full processing chain travels with the data. @@ -38,6 +41,27 @@ A recorded session can be: Gaussian signal, compute the average, add Gaussian noise to the result and run a Gaussian fit. +Recording and session lifecycle +------------------------------- + +Actions are recorded only while **Record mode** is enabled. Turning record +mode off preserves existing sessions but does not add new entries. + +The Signals and Images panels each have their own active session. New actions +are added to the active session of the data panel they concern, so switching +between signals and images does not mix their recording contexts. + +When a new object is created or a file is loaded into a populated active +session, a configurable policy determines whether DataLab asks, starts a new +session, or continues the current one. Plugin-created objects use separate +policies. A single decision covers several objects only when the plugin uses +an explicit plugin multi-load scope; DataLab does not infer such a scope from +a sequence of additions. + +These options are available under +``File > Settings > Processing > History sessions``. See +:ref:`history-session-settings` for the complete labels and default values. + Toolbar ------- @@ -100,7 +124,8 @@ The toolbar at the top of the panel exposes the following actions: - |record| **Record mode**: toggle the recording of new actions. When off, no new entry is added to the history (existing sessions are preserved). -- |new_session| **New session**: start a new history session. +- |new_session| **New session**: start a new active history session for the + current data panel. - |open_history| **Open history file**: load recorded sessions from a standalone ``.dlhist`` file. - |save_history| **Save history file**: save the current recorded sessions to a @@ -109,38 +134,54 @@ The toolbar at the top of the panel exposes the following actions: session (keyboard shortcut: :kbd:`Ctrl+Left`). - |step_next| **Next step**: select the following action in the current session (keyboard shortcut: :kbd:`Ctrl+Right`). -- |replay| **Replay**: validate/replay the selected action (or the whole - session if a session row is selected) without changing the current workspace - selection beforehand and without adding new outputs to the signal/image - panels. -- |step_by_step| **Step-by-step**: replay the selection one step at a time, - opening the parameters dialog at each step so the user can tweak the - parameters before re-running. -- |duplicate| **Duplicate**: copy the selected action or session into a new - history session. The copied parameters are independent from the original - record. +- |replay| **Replay**: replay through the selected action, or replay the whole + session if a session row is selected. The recorded workspace selection is + not restored beforehand. New objects returned by computation actions are + not added to the data panels. Recorded UI actions may reproduce side effects, + including creating, importing, or duplicating objects, unless an action has + a specific replay guard. +- |step_by_step| **Step-by-step**: process the selection one step at a time. + Parameters may be reviewed and edited when the action supports it; supported + actions and their dependent branches are then updated or recomputed in + place. +- |duplicate| **Duplicate**: duplicate the processing chain containing each + selected action, or the processing chains in each selected session. DataLab + clones the required objects and creates independent history sessions. - |remove_incompatible| **Remove incompatible**: remove all actions whose workspace state is no longer compatible with the current workspace. A confirmation dialog shows how many actions will be removed. - |delete| **Delete**: remove the selected actions or sessions from the - history. + history. Removing an intermediate action splices it out and preserves its + downstream steps as an independent chain. .. note:: - Double-clicking on an action row in the tree is equivalent to **Replay**. + Double-clicking a tree item triggers **Replay** for the current selection, + using the action/session semantics described for **Replay** above. The + recorded workspace selection is not restored before replay. Tree view --------- The tree view organizes recorded actions into expandable sessions: -- Each top-level row is a **session**, automatically created when recording is - enabled and a new application context is started. +- Each top-level row is a **session** associated with the Signals or Images + panel. Sessions may be started when recording is enabled, with **New + session**, or according to the configured session policy. - Each child row is an **action**, with its title, date/time and a description - summarising the parameters (for computations) or the call (for UI actions). + summarising its parameters or resolved call when available. A UI action whose + call cannot be resolved may have an empty description. + +The selection of one or several rows determines which entries are targeted by +the toolbar and context-menu commands. The context menu exposes the same +commands as the toolbar. -The selection of one or several rows drives which actions are targeted by the -toolbar buttons. +When an action row is selected, its result object is selected in the +corresponding data panel when available; otherwise, its existing input objects +are selected. DataLab then switches to that data panel. + +While Record mode is enabled, selecting a session row makes that session active +for its data panel. Actions that are not compatible with the current workspace state (for example because a referenced object identifier no longer exists, or because its data @@ -158,27 +199,7 @@ captured at the time of the selected action: This information helps the user understand the context in which each action was originally executed and diagnose compatibility issues when replaying -sessions on a different workspace. - -Session replay across workspaces --------------------------------- - -A full session can be replayed on a workspace that no longer contains the -objects originally referenced by the recorded actions -- typically after -loading a saved session into a fresh workspace. In that case, the panel -**remaps the recorded object identifiers** to the newly-created ones on the -fly: - -- UI actions creating new objects (e.g. *New signal*) enqueue the freshly - created identifiers; -- subsequent computations claim the identifiers they need from that queue, - in the same order as the original recording; -- UI actions removing objects keep the queue in sync with the live workspace - contents, so chained creation/removal sequences replay correctly. - -This makes it possible, for instance, to record a full processing chain on -one dataset, save it, then re-apply the exact same chain on a different but -structurally identical input. +the current selection. Persistence ----------- @@ -190,15 +211,17 @@ The history can be persisted in two complementary ways: saved alongside the signals and images. Reloading the workspace restores the recorded sessions. - **Standalone history file** (``.dlhist``): the file embeds both the - recorded sessions **and** all signal/image objects referenced by those - sessions. This makes the file fully self-contained: - - - Opening a ``.dlhist`` into an **empty workspace** loads sessions and - objects directly, restoring the workspace to its recorded state. - - Opening a ``.dlhist`` into a **non-empty workspace** creates new - signal/image groups for the imported objects (with remapped identifiers - to avoid collisions) and appends new history sessions that reference - those fresh identifiers. + recorded sessions **and** all objects currently present in both the Signals + and Images panels, whether or not an action references them. This makes the + file fully self-contained: + + - Opening a ``.dlhist`` into a **pristine workspace** (with no data objects + and no existing history sessions) restores the saved objects and sessions + directly. + - If the workspace is **already in use** (it contains any data object or + history session), DataLab imports the objects into new signal/image groups, + remaps their identifiers to avoid collisions, and appends imported history + sessions that reference those fresh identifiers. .. warning:: @@ -227,9 +250,13 @@ reconnect to preserve the processing flow. .. note:: - Reconnection is only triggered by deletions initiated from the - signal/image panels. Deleting an action directly from the History Panel - tree removes it and all subsequent actions in that session. + Reconnection is only triggered by deletions initiated from the + signal/image panels. Deleting an action directly from the History Panel + tree behaves differently: the selected action is spliced out instead + of truncating the session. If downstream steps depend on it, DataLab + preserves them as an independent chain by cloning the required intermediate + object and reconnecting those steps to the clone. Deleting a session removes + that complete session. Auto-recompute -------------- diff --git a/doc/features/common/overview.rst b/doc/features/common/overview.rst index 496028793..bb9df13d2 100644 --- a/doc/features/common/overview.rst +++ b/doc/features/common/overview.rst @@ -13,12 +13,11 @@ Basic concepts Working with DataLab is very easy. The user interface is intuitive and self-explanatory. The main window is divided into two main areas: -- The left area shows the list of data sets which are currently loaded in - DataLab, distibuted over two tabs: **Signals** and **Images**. The user can - switch between the two tabs by clicking on the corresponding tab: this - switches the main window to the corresponding panel, as well as the menu - and toolbar contents. Below the list of data sets, a **Properties** view - shows information about the currently selected data set. +- The left area contains the **Signals** and **Images** data tabs, which list + the data sets currently loaded in each panel. Clicking a tab switches the + main window to the corresponding panel, as well as the menu and toolbar + contents. Below the list of data sets, a **Properties** view shows + information about the currently selected data set. - The right area shows the visualization of the currently selected data set. The visualization is updated automatically when the user selects a new data @@ -28,6 +27,15 @@ self-explanatory. The main window is divided into two main areas: DataLab main window, at startup. +History Panel +^^^^^^^^^^^^^ + +The :ref:`historypanel` is an additional dockable panel that records signal +and image actions into separate active sessions for each data panel. It +supports replay, step-by-step replay, duplication, and compatibility +diagnostics. Sessions may be saved in standalone ``.dlhist`` files or with +the workspace in HDF5 format. + Internal data model and workspace --------------------------------- @@ -63,7 +71,7 @@ The following actions are available to manage the workspace from the **File** me Data sets may also be saved or loaded individually, using data formats such as `.txt` or `.npy` for 1D signals (see :ref:`open_signal` for the - list of supported formats), , or `.tiff` or `.dcm` for 2D images + list of supported formats), or `.tiff` or `.dcm` for 2D images (see :ref:`open_image` for the list of supported formats). Interactive object creation and processing diff --git a/doc/features/common/settings.rst b/doc/features/common/settings.rst index 4cba364ee..b56085b16 100644 --- a/doc/features/common/settings.rst +++ b/doc/features/common/settings.rst @@ -8,8 +8,8 @@ Settings :keywords: DataLab, settings, scientific, data, analysis, visualization, platform DataLab provides a comprehensive settings dialog to customize the application behavior, -visualization defaults, and I/O operations. The settings are organized into five tabs: -General, Processing, Visualization, I/O, and Console. +visualization defaults, and I/O operations. The settings are organized into six tabs: +General, Processing, Visualization, I/O, AI Assistant, and Console. General ------- @@ -138,6 +138,45 @@ The Processing settings tab controls computation behavior and default parameters - **Ask**: display a confirmation dialog (default) - **Interpolate**: automatically interpolate signals +.. _history-session-settings: + +History sessions +^^^^^^^^^^^^^^^^ + +These settings control how new inputs are assigned to history sessions. They +are evaluated only when **Record mode** is enabled and the target Signals or +Images panel has a populated active session. No policy decision is needed when +the active session is empty. The two data panels keep separate active sessions; +see :ref:`historypanel` for the complete workflow. + +**New object or file** + Choose what happens when a new object is created or a file is loaded: + + - **Ask** (default): ask whether to start a new session + - **Always start a new session**: start a session before recording the input + - **Continue in the current session**: append the input to the active session + +**Plugin-created object** + Choose what happens when a plugin adds one object: + + - **Ask**: ask whether to start a new session + - **Always start a new session**: start a session before recording the object + - **Continue in the current session** (default): append the object without a + modal prompt, so plugin execution is not blocked + +**Plugin multi-load** + Choose what happens when a plugin explicitly groups several object + additions in one multi-load scope: + + - **Ask once**: ask once whether the whole batch should start a new session + - **Start a new session**: start one session for the batch + - **Continue in the current session** (default): append the whole batch to + the active session + + **Ask once** is the UI label for one decision covering the complete + plugin multi-load scope, rather than one prompt per object. DataLab does + not infer a multi-load scope from a sequence of plugin additions. + Result management ^^^^^^^^^^^^^^^^^ diff --git a/doc/images/shots/history_panel.en.png b/doc/images/shots/history_panel.en.png new file mode 100644 index 0000000000000000000000000000000000000000..7aaade100fcee603a36d0aae25acfa03f09aa829 GIT binary patch literal 63172 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 E2FhwT)Bpeg literal 0 HcmV?d00001 diff --git a/doc/images/shots/history_panel.fr.png b/doc/images/shots/history_panel.fr.png new file mode 100644 index 0000000000000000000000000000000000000000..813407000b6f6aa96e0aa70e6d3991240cb47904 GIT binary patch literal 61790 zcmcG#WmFtn*EQO>y9Rf64+Pf)cc+mc!QI^@Xs{r`-5Pfq*Py{&1Hs+pcFuX8@xJ4J zKkohWjZr<iy1HuD-c@U_IoDikN2w^uq9GF@0{{TDk8)CK0049&0009(gohjvoXX*b zd?7i?>AC;_=>2~`P$|sl!~g&V;G>kdhG*7sr;jVKW$W2niZ6J7d-03fP#cXqJJ!_H z48XmtB7^7Hst<Y^xY7W-tv<b7@8aw}ur3}7R1SbmL^~9u%uJYHLl!Dzv~_G>lHC(1 zt02NogJ)pPZHUd*OWIl8G03{Nm%n;4W6O9KTb*h<<}YINWhujJzjNH`x6tHM$7F?G zy#*RfFa_e@ZP<90+YstMKhl|KtdaiNkNg@T#VU>o3)vDc5=v?RIhTTq47>5~A#qHp zLCO5o|FqyKH;eu6(RUb8djB>>wL_^Y|Ig*(pFjLhqx3$-%p5qS&KkqN_NbL};*aY{ zN@H~G$VpI5osFT*gbN6-;)1{D;)U)|va@5Do11@OH8VB_n3<V<VGW@`q*`Oq>mZyX zBCT^NjNcfE`gr}=+2Z_gi8}X{f-5IEX1TJGWwrR1iJ~2=Jrny-?~EFtd+un#sTxdv z=IXZPS3?jaMlmNnRIRUyAAKaR>M6^qvBWgM<25WhJtW_)z(wfqff*uOL(P$#(Wa!J zkP8A~;^5#gjyN=_XlaEv+AI_|er?|HC$^mY5i9g!aB{SSxUum3#wZT=m5p(*y9$qx znY~v^SEL*89;RRz%oACMla}D|g@f08AaH~k`ZBtw@PJgi2%3Wrac)ticj)pZ^UuPq z!57*51MRu)>o9ilDlIY^H24t57fWVukq__3d8s2?#Yd&=+_msUo<@|nW6;nT7@3e) zYIK`WJplIxhNSkWXj>_9=pDE7`srD8PWmmyghjC^xf8LII}#~X64QpX4EI)8)nIqD zzB8ps7>%D9dm;B4H*UM18ATP}eA@_Reg8Bj(Dn9)p<K+>_~Ys7>N1Y76QXW+2f?(s z{!#mMNzDboa~yZXnc%DLwKD(M|G7j_tmlDP$Gru`{0s<~;VI>6y(Cjue*_SwT*^Dv zl@h`)k&{T=M#!pVIPla(6G)__putyyEC|Jl)Pk_e+)`SyQDMT7s5k@wu=FKWKU}^) zPV$IVY3(F$L<9vvjdab_acS5zls+lIKnzMQDLHbveDu?Yn?<vhvW^ec*R;~oiw!0) zL}y*ZlU?^zO2C$cXlsT7tvuT`3EVZ^tktbnYnDY2;(K`)PRDyD%q+6BP%!v}>qi%u z-#SB9#2stHOEE;!5T&F@sg{9}QJm58``anTJ6!zoa}DnHv+H-pzxWCJcf=FY5I($t zHFe6&u4q(+MAI2YLL7F8P!I73Qv5%ELGtEXi<&w0xAK2wtBV*^*CVGZp<oThhdc)4 zZ_OfsmFuG7yqrmw&wVOoxopN~LB2M-0eBcNxfA0<yJDj0NX~B`;T!d0Q<$}>*hR@L zl^z`17GhpsUqREOuQB@^j(gY|On9i|4~T;@vKLzs<Wz*H6Ds3KR9ESBr7u>BXs;L3 zvWYpFndh}*sVqHr8JQQyK`{3#Bi9|@m87SlO|FbNrrg~QQ=&tP+b4z;3bZ)yPc2^n zeVZyCz7oc5_u!$4ycW6Gl8iKHfXI35CWbHp$kPPB+5kl^-1+KCqeU}^+Sk%q!+3TN z;4JnNL&lzIAR_b3bPW}I*IV(u(sN%)?aYJhF7T7DoG7+}k*XeSRRZ`E99@l7h7_xi z#7&~U%|+OxA77s2-P;iJIX5b__C$z@g^@9y6>?(Djtq=uprCAQezfVTfFCI>f7<ro zpCg8@GQvKBh(yB#G|eWWorNLQj!MF`^$+ohWPf-s6K704t1*hl7ULUpo@uOYY-m@? z%ggi0T&~9XVF06PEInr%zTAp`r_E5Zl%1xz`Al#sy(m9{vhXcoSEr@&C~H%gO|&|d zl~?pBOHY3o5-Rwczji1b+y&ZQnI>vi`$W9M+5&<0BSk^)#spr^dMz}8eW5bXZ!Pac z^#rs)yvD<4@!hp&D7_yK0;i>neP9xSsDL-HZMIECjMMeQW5XP+W~l~KsYdzNrmX9` zyMoF})c5b}_rpx`Y1qGrk8yXEVhStfh@F7DzDvZ|J;I(`r$UtqkWXYXF*^<&u3!t^ z?$@;Bs#%JsWMWv@3XsmlWLD<eT7g|q>OL*XYCC>FbgL#Zhbtl^Y-M|99bq0kzvrl{ zcg_t*F8F4~FwQR1V>obsuixBf%z@~IkFhRxc0hP5az_##u6C!^a9wP!<FY^x`uq_t zJp9{Hvu5*Z99&G=X13@H*8b#xXh|T&Z|09N%g2>0e<z$O94j{`)b(9GaC9s$`kZ2X za(qBNUL@M#bUB5Ke5Ep<C7F*c^1Hp$tLf)5UGgb0j=-^kY0Dp}d~Dr13v#1$@kP*$ z$P5#)U=g<rsAuC&f=qv1Vj-ubUA7y_T(zzK?<s&l7s>qu;0;tAvbAb02zt_9H?~4o zSl~I0taOy1Hz3h(cz55z>`(A)XJjFA$|tx+J=P1+pHkuB;f|-P?+<RgO`I3L=0p1u zFDQJRy8Oz@6#BL$1e$q>Xn0t(V96@t6BT9Ol9U~kfil)Ic)|nf(IM&qqW5)q5pjW} zJv2B{#*{F-p++Qimv!gE)bYk#m{Lz?8$*ltG=UN<O!~p>zFQ~)p6AA+hu-^ZHmd4A zN6A;Z23@e$jYKuCk14pb(G<V=AdhU)|MDA_pVjvsaabciyq_04-87a?KPSSiZ>&Gt zEdn&1TC8-NJ|ht=R7>kehwDKQXeR^rwzJI=)ZzIau=#WI-G__EfcOlf><SqtKSp?T z#du<gHl0pa#DP{Q)VLB0wY02NWO9)fN1~jk<|(Q4j!fMc)=5jzRz&d08`=bPi^G|I zulvG6^UiG%^Nd=}XO)V%UfaE;bK@K)2#y_`o`%a5^aR7z0-t9_8t3>2P9%vj7Hmd2 zRoY?A>4!1&q4#A}6LRjy`VJWO<%Rkd{OzU5@I_Uk+UubOuvE5|VS7(6@Jj4A^<xk? z3eio)@i$wuB7ncy0WB6+I9u@5@tdoASY7&#r<c;RHD!`UHa4RY2yrDGuqI4bRFSO; zYWaN3%qT!xE0xuutPfEmId3Eh7|jYw!4G3Vj-|EO;|TI_>$!4}8Q62fPvCi8U!81S zbFWmzQ}(gaFU$jXr|oI^=RmDuVh+#<J)~!Lq6%x+@UX9ZfcidTi*n>vKTQ+)EeEM9 zqN5x`#R!BLAMlyl$3TnCn#ul?a#2!X^V9@ya1TX?5qm1Det405+JpkFM)%TW_y&UK zYu7V=1Mp9e97k<}^8Wl>vGy!Hj7r%oWxz@|tOg*xlEg%m5PsOyp@xYq8Zi6EE9ff% zo@Lp%e6OZ$C{AO*okx!30M#um0|YvsAFl4#&io@16Th4z!Go@+nM&(4TSVXJSki~3 zS3GNWwbF$Ez6IM%!Pc86K`b5ImA!AxzPM?VhC>w(a7i6H+WAv=&m9J?Ifp|pcN_5= z&%gN@%gz$x_@@?DP^y$-juvX@Q)It<Ve~a3_g(*yJR3#vTkvDl@`|hA0Lbv?W^P?B z9`}c@Bfw|qrMIhqa9vyZm}tj#C4|WcayoU^pbv)r{Q?bTVi1DRRSlpv{B;aWO+#P- z!qaeumiAK)!TR4V0DipQ8KA}%H-YP-tMj<pF)`LI;Rap;T0Bv~2R>v=MFkA(hJiJ! zug0Iol;KQKP7L;rm+A>gNe80wn2S5B3gn{;!cQIp-0rqp^%WMEd~n&b9$Z$p-95eD z4HDo{-F+hR&*=dmuZl{6a#79Pl%Y{Wp80>keM<?cefj|n*d=}7oW-Fg?0n1VDb*N0 z@kKwJhWbhfe(%!jj(m#HvB$;Eue}{(XlNMA9`G=Be^V2X-Cz}ymai|b(v;eG5a4h? zC6ejTzx_;UfEF(E^Lht|VI0j=-hu5k&lH=0zTVM9Etc2Z%+rkp2%4AK-cF%h1)rWx z&CjP|gCC}+v3$>8osv`W={s|K`|k-wJm2n<k0da!!V0BMGW5)WKf5bxWC$8QNJ=7h zJTldhdo$QBWa!&}Z!4WsUK3^i!BuQHtHp{?%)zJ}r#FzhWd>#Nx((a)rgnI#xxIYP z`@G$k=4f^a9|yeH%zhOuXp;(Infs|*lb@K9LL0j@lBZRH*G%85flv0{?Qk|Zc#c_j zuG*kAxVDz_z_sm5wiutIjr30*{=Jk<S>Bw!ro+e3{*!K2dC>0NwB$Bz$fqJ14lwR8 z`wl;aP91Lf@zhxaBb%(TufXo9u1Yus&gZIj#v0YE(r+%J>8P-wUg+{^TKT>v!-lk& zh?_G-^7pePB4Lsd=tb4l&Kli{z{ED{PX7X!=FfB6pU$~7mMV>Nj5Rzx<YJ?3jgz6u zuLxVJ%cpe$LDQ^mTK5hD{OlN(k3)`kYaTmQ&Fjc3ISg||tRlA;Lbbo+;!UMB@d(3v zK2ro{9Z#9@6QV++!Zb28-SzL%)U`e-1A*kJY&E^WjR)>$k+b9@DNL8_LaC}Gb_f{t zJWdTFxjYM`M@4}~%;a~zx)H}7bL}BqZ9fm(8?A9C*`<V~B)#RdzYQh5Y@GV)IbG^# zE%C(Eu4ZwF`)n<nCgY;!al~g2V|||WoCG6_(={D1F%yLrU-AGp3m#`De*@K2g7S|O zc)>@@NXK4pz`S5&=1=7pu`91aU20dFzWd622JhOFE-$}H7pV;xd@wD~cV}8{aiV4& zgTp{W%d4nB@$MvpgM+KZkb^SY+bR%Fl+##^ODP$8iBv7)(0W4~X}V|xruc(h3L4lv zM3Pe5XrRyhRT6TGw9ZT55;DJ0*Z#hm|B1&ubM$7E%P19O<Xr`u{?T*rLwW~iPzUm@ z_YIy!fk0`mp)}MgB4B?os68g+phFFDcs=J6^3}PRAuHWr(OuVNm~@N#?QL?TUbqPj zJBZ+^W^=n}Y|2JE7Zm8%DzMbo<vCY90}Tk5m6_fV3X7(VQEmOqNeE)caOp|Qp(qY1 zlwt*6SB1X5P8EVY)3adNfbgGRePfa@l`!3EFFCAJ1?AImi=~<bg=_<~LboK`E_h<} zzK87{8Z+7lTrS*CNKWnq_`XU5y59uvX<myO8LN*|lMQ?RyxhS6CT>e)3ehkyLQDuD zeChb%+GwP!oq2w{YVr-~{UOP&c^Fxx(Ag_xFqSEh3pHemMska$&)1PZa`66MpslSf zcg|W>EA=(yFe%Ctv!;cVT`@Lh!XRi%B4Ur;s*Lm<Dc<YkcnT4UXCCkOVLwr%LH4hd z0@#6VV&0SEOv5s#o`5^$xGf9-^g#C{JpNA4aYaj&D|Yifywiai)N4yAY@q9<7{{=& z_(!Zu=UJ68Bei;U+@O7p8uAkFmzEbT_s=f2U#t4=?^`IWhs+Duc6N4>8u}z9ac=@C zuqn*PcCo+EDL*Fok2PcC?3FkURh=QPtP9kWkhdSXRkptvK3|?F@2rYh71cUaKk+um zFA8)sad5DR(jE(W(eX-DgTdq*FQ*>r79*bt!&z`$zB6VmBhf`pZ_+@k_)})Q*MB?? zjaSdKQgEs*9Un_18`HP`#cB=H2bHz95R;kdX7coDw9aIhy*H=jOi~`D_UMrYx#qW- z25)#)QER1Dil%CnRvv}?Ru=*4cGs1kC)>?91)?dD+^1QiPJhx2^RYtWv9X}z<NK<{ zrKRre0h7#{LgQX>N0kS00z`O6i}SCa_03Ia>*j3v72xTeOztHXIY-SET(bUJKztfO zUdyB3YS9TiV3lxEGTxhT{02O9>$Bdie)NWO<UbF4HYYu-g>Vsn<R9BhvbVMTtwfz3 zic2>VK17@Y73bHBadlE=rcl)>0wk8M#TgOc6%0Ik2#5#}y<;1se&+i&?jw?LAjP@< zLP0M?tjmQZV3?{0XnAb+Pp;GrtW*Bf2R1aTJMa5eFx(Ce>q5v;@s0vvm<dA1d_Nqn zjPH%5IUQbqNyf!9+xsNku39x%QM5Hl8%)6kvHFwNSN~PYmEzHnAP9Nm2zZb;@G8}+ z(K7hD^#QEYhnr54F7~5WV_~cyt#5lu#N#a<E-eJ5kHB=WY!3-lp}sUl*Ls5#CBO1f z;D`S{H6W1L%xhTJA38_x0Sb`I;((h2K0>_h0>*4-A^E=5R6qe}-{XM%cZEweDYw2e z$)6Ymnh+`|Dam9p43>On{PgJ)HkkxIHy0Nbs#7#06H~@*l<7m-Ht;*U5$D*qG_m!o zV49uTIOl~={zfff9)i-WfGn?`_+HI{VaEMKE_j75=v|}gP^KDOuOKG_x15N>D*%;L zw3*D3U^{wec=Lu(*l`CoEFHZ{(j7cm!1Wj*5t;bpUIhaaW6xA9@vj-SU<x%^wfx)c zYBt~MYBpP+`Ea!K<I^}&sJv1{U1C0leZOrfF3lv4dG6@^cv*D3WaL5b;%V&UlmR8& z9YUn?X+u}C^870S+)Y@mTMqm$)!P%%F%oU{UJD7@H&Aqd=itn1{}^vv<)}KcOqIMd z>?pnWL1JR6i|`>m?+ocY%D*{#`}jEN;u~2_=S!DXSO2(0ax|xB+iGC+&X5|Y6gVs6 zCS_;;brp<DLK-eugV{$--Qs+rw>oqKw4itT&D6rG&|Hd!s<hqbKq_mZh=k7yj6Rn4 z($TrbV$snGTG3+b3zJ{i60L`Y0bk|<J>YusSV~=>Rmy@!5&?twz(J`yf!Dj<eGZOR z%)K#d$EQ(qfsFvt&Jy<Rp|@MAPssJ%fZ>sG7%_-0#uW=Op(i7Dh%^&6P_BtbK>f58 zQ7}}_$|P|siNRRS<nCvMc;;0?*7W(O5VA$mNBv4Yi=>`X4{zu=7{vM+@4<JUH+-Sn znF)DtnM85pV@n+iH&HJuCXBV=V9Y{Yg)KGZ(q!~OpBe3E4#GyXgTw$3dXL4L?dQ*q z{??|s2-MSyjt_X=;pX#V#zg%2Fk;5tdM~kFB#xT}4oWN<WzXF>^&%zJ_Ct!&1uz^E zi=8%>y@|{fECh{kQV1!2o1hz7<SK@;@P+M}7Pozwh%1bXw<yd06xk;Aog}^gM$~X% zN{Al>Qj00d(FuIJRe?!OO*1j&3e4&Bg$-!gl-zu=U9Eg$c$&ZjB%oY(xZ&=5w>fp1 z;x?~#LdCy{-kJVMf;)DqAsHZ#zuCTT&(?9jLPo_%D$1eYN-UJJqrmKDCM8`gG`7>M z(hEBdcpeH(8-WYdUiYM?)#9)S?m2G{VQ6C(o?qVbKq&Fxt@Uj^f`Unj?jfy9>?aoA zT&0=fLp=shP{@x5ngsHy%8)4kP|7i`sGOmw$;I5+G4s5Nbq9zI%$T>lnAza|+IX#v z-|?tv+`6QlU;gmn!`BM!8q?a~vm4hQV7!asV)@*mZmq&;U7z8>l55F!S6|w<7;V2_ zd1djp007-k;?qQcvFXi52qQz-r`_BU2HnPYbk#`KsD!05)ztg<Z%}l<8VYlugNU_z z6qLlWf&JRBDo`;5?BNiO=I+j?!L-h9q-QohKGu7=6F{sUm6^p7)J;?8a;2)L7C3+s zt!khWxHZkG!43@exRU1(bS2%vQA2SyHpTvXnlsAM4u0KG?AO>lZ{7E=Nx-jpK~PyF z=L$YPh{1AbA7w>7PpX=yJnz<Ynm&JA6w!3zgs@e_pZ&1JO(+0-cCG8Yz4tzUu$SXW z<(mXeP{}&ug5&YSs?gZ>SF)8+Oxmdwk#TTHFig)6u649wFAK}BCkq1E5OlhEPwoYb zTf3w601R3%8w@aUvCuD2#wN*Z0$y~n%r#CJuMm;ewG9XZSbeSK#e%q{kC@KJ7BAXf z_eh^zq!)kh?uykc6o5dE#TCJIckH<h?c@tK#bh}|fYJ5#z?pCAcVqh_f^SfD69E)U zgSc${2QP0lOT|R*#7=8-B>W@=r(K({NZv^~N?C`ko)4f6Pfp58OCJw#^q+&rUHcW| zB6@5Hoa~GVySh+RYE(>IZJ~#he+*7_OJ_Z9vKk!V4JcX$)+Qb$?R1o|nV2^c6`0|8 zzDeE+KyV<lQ2GQyP%VMJSQ|F>afEa-Dc^ALBebHXFPuI+ZO8PE@|IC>;CA2K+UT5n z#N-#N>*-JuEdblYyHy?|R%rB;EXq2;m{XDK7?+yeZ4$W}Xsa10vjhNXYj><XP0rsh zg}>B<(u@h=dyE}r2#n<5q@|^GnrxREln`T(Vg9O$e-$>)E-Py)p|=?do;R!wsX2}O zHYY5vp<8iYE{+p(WxSM61G-i?;A$`Vs+s=2KgQ?Fa9LL`Xiq>b6Wsx5gLj0zDX;Pe zLKg@e3YZ0wqx)u7n^Y5CZ_zoORD!3@qDtBKeLT&96p<R-MFNc_>;~QS2<V$-LuB#- zuauJq_X0nJ9RVfmh3mbX&l42ROfIUfmeyJXMBY#E;TzdxzzX$+ODCT_On_#(@<|9+ zO?1lp?qA5%*O_LOW}G5WSqIdr#O&Wms=t<efMdQb$~ew*s&swDBIom?`eKq9@CA`M zJ3wOo;95a%TNU_6`jq@ul9w}9<d%^R6On?Q-3z?+-BEP&!plE`dB5Ypumg3cAf&~$ zjkrhb`0+lDyeH+VD>Ob6S$9=!z*_U*2Xnyp&AW>)NWpSn8JRP{*&m`#d~P?7i~22z zb2?p-HrDGA0))Jr%jY78ySFL`y?qYrbt2Zgf`a-kCW(G9y<M(ka&ly#?d~BTHI-n8 zn{3`|vcbz1|L_P15S{oToEfZ#b(QigFWIsO+>rX>v0V*ger70k62BpJn({~A4;?VO zzae|7Kk*g60kv<_A>fG^A~(p$%Hlkpt72G;s*Q0^ZA5fci*8Ds`5+<v`W!ExdU+|W zqt^;cOPhx@&z!muiZ|wf-IbP%Yw|_<eQL5Sxd{!T#P{S%hIx-I=&n{90*HJxKycQM zQ6xRR;0hMu359q?n3JKnqS-yMM2e80ri%0yj-Z)AI8Hy?J&qkzc%ybfJAAz#cWk&O zeaa3)Ys)4FX(dhZ;X`wdU|=MQwmNlcNDsxj*FGuW*w&l&K0!=Zw;_@=57nmj1qR-l z+0ot*Ej&#YSl(Rf0N^JTNleE4!L-yFAaT3#ic^l-yb9Bu^Y(11p`l^?a5*d=DQo7M zjNcYH2z<LFcz#e0h|X3CI$qkQlfrx_F^W3~nNm&s8~rvzaa(*<_%`;faPnhgwWZ0V zFkt5w!HK)OoopQX^B)UBC$%CG8}Isc77+i<)j0ih1pcH6+46vQ+BtB8jVSTTgNxgW zVsUj%%PsJciB^uZ>TLp*BECHf4=HHG4D%4?9`{QpXSYONNQV)&m?I62#&8;CAmA;g z^j@-|<sbJKC5N7TicYi{emG+0R(B^tgoVBzckmC<w{H!L38m=dzuXvD8CbDOrW4ez zHt6~OtK^%Y`@=YYNedq=XR~URZav+VA{tWus468;JMe>_NZn{%E}MnrDgpuwA}Z`( zGNgJod>ww0L0vj$t)ZnQQKV+#)rj9p1?(Id8A)g7_FE_W8XsYyzQ4Om0a3=ZYm5el z<$j}IVZ(BYGBPlT+1aty)#KDt!a+l22{;9x`oJavuGIdUZ*xJ(cvSj7vuyuYQg{DX z8m0HKva%{Z68m=ym><<OG(v4($^Vm%9Om(avEu_A+&sRkLKVk!iMYIUzV{VD#lR@2 zt8*@{ko?IxIyMFsSj`!nPOYGzK*7&XK)`MU3*bPdUSfY`d&_xyAs6*00nl5s8?+>> z6XC#e)*PIj$(oo@uIWcMh%XR||3t%Q)l07Hu*xU=KhvE*Y$;X)f*^TEUBYlI5!giQ z`=e;c%_w#givE-QOm|C8Nio?OjAdYEj$s!5Z~D_zs|RHnk6CMTT9!Oke$hf6TpjW< z+^kxX-hjc*YZtoWi8&z~n3ln}-TJMplusP<Dp*r_GxrKhW2D)`ALDKjeNrm6c(9z_ zaY{G7z?D6Vx3ZqRr@4>J*pK_JW4qd`V>UEay%exgt>k+~M$C1dCV`36hq62a$#{xE zR6#PoYgG~fM*s{A3|9QNsO3J;THo8}`5ymWW&v98yR6knpC34Wz#CX}LG4Y;Ycpy@ zD!NOAE2a-lQ&H5iBHyN9e6n8<yPU19B`5`LJGGvV$v)?=|CqcUf!h@niW7*>^^fl5 zVpI}|h)qJUAYu5Rj<Ir@x6jP!kbt5`X0+IKza4`WW|tggYHIn+P!yAWi&G;6d4s4I zQe;c$CO%fm{I?=%7-x6!rtL5F0@qddWNWBtz(+b{&U`K^+NdkCkA=x{L5o3%3j=u$ zd0qQR9SvszTSqmbTu)Vp*9x@1IU&hm&)r1XUf3#6QFhxJ!*={8QT?s-gUTn7IC}*5 z*#MMvdZXU1*kj}E+XC6z&NB)=(Myu^e)&a@NvvZ5XN)F?N{Nl0anIe>Z{6ke=QCZg zz2^m>Y>G&)@hv}u+AkZOIuU)9(x2RG#P-o=1CBTX-R@tfPby<H)<j6w5M5785h}u@ zpJ;}ps3g3dmR91o4{k+BR!J05qppyY+fSclYlSrsAsvaSZ>t>=FBJt;_TsRgNSY6p zdi=K*;Ktv5rCjcACUiw`^8EwJt%rR--44?Sk0hb@syVXLk7>fP#F7N`K1vUkJLtww zw}PjHaub{ZBK&7HgCbk`h=w>7rXSS#Ap^T7ivATo7cht8`DH^`pw3IQ{7$-y56QHN zlY=8L=XsYt$!^-{^Pa+&{Kb)dGVzz+AqSH5?z0O8M%N*db27HQze;Or2#}V296!4V zA08d40>Lny#CKayN5yK8T7loN^nM4@ybTqLH5Fgyl6<5s*W6EyoCr6{Ylh;KZYhm` z?05}}J>>Q85GtB?is-eZ88|*Yew*A%d>j{8976v6_-G}Oi%fjC7PB#5|8RUz**j?Y z0{}d1J0l-(Ki(WI9r_(IxA>}N6<{!YR)o}?0suHTke8Rc9jBE}7HE2I7oC*;uC96f z+uYcGFVeEn#rqSy6t#$xyVuk;f<Lqc*3`EbU+!(T5AJHwIe(N<&HKGEFgqU=-J}`8 zOxGv|r^l2+eK8oBicqFnVY7`pHxvNjJl(mYtjyc3Ba-+M`LsW{Mu5(Y$q!Er3G#d& zry@jL4htM>5d8qT$a8|XK6mSONj?J(LP6FiOq6~M%(qYF^n7{ME(lGe+wp$}*I%+r z+lC@Fk@p6a$hTfgrhZJ2t~f@nxLa+AUu&+x>@dOqET;#RRpSUXkz&XFS#KxLe)b>W zDqKlEEsAP#6Y<+!kY4PvX4T@X{UK{RV?@5OzqZ((CKPeRXGV=~TEClhYCb6n$i+ao zBgIas@D=H+Mw;DPcS{VQ$8^xYf#sXK+1mW&Gd&)92)2tjAd2*~(~{&znZWTopnfe( z>R-dyE~+6g+LA|Wm=n`n6LGaqF8P%YFXpk#B!MYqF%_{sr3iy@e2j~>0^`@YC3}8Q zUJ=-Ka&Wv#)`hWkmnQXVNZ(SIvQ&b!$-|whGFb{aaaCSj_s&bM24k%>i1YC30CQFL z5#-=QFUU{Y|2yIi+3&Ht(@pHmq2Sty-M3aL@YomH==v6F?xIOtJC>=)xudhv3N8SR z!7y`fY6d1Py{}MtmTAhvk(+E?9!wWZ@%e)z`{7i~hC56*%;Hijsav*?ind4OT4y~@ zrs>{vD~#I;`T)=(|IfF49HGM|%Do~5`L%s)UXFG3ur6xK6oMPChC7ql6Z4vOzieXK zFHclm0}9k8z3Gs0k?3gTffG|3`@%P`;*YcLeG4eIm2^VT;+W3X=exy%*QBdIqrnKL z(uU+h{lx6+>mr*!?q&V36?1Ucjjp$TFr;$QqGY4bnFRUnEh$N^?Gs_x4i1(p9dCwy z>6k2#Tsd?s{r&OTcf;ZX$b<MO%_km<*QZ^5@lH@fTe|js?BceLjg8l5nzcH#nn;tz zJqmTV^KM<z$jGSwC8~v?&`O%qUXB_$;+9kjxaNNBE7oukls$6>EB=$4tb0PqeLL2e z7l&-wHz^yNAC}By2BZ6-+`gY%Ioe)|SJ`y`+bDmr=P&J{wp!@|ANE@hEt4H?WvXO( zv>&S@0hYkqBfhX(QILyI=zs%ujZlx;)$ZhUYbOx`e+0|#=^R-M;}Xw^YQ4yW+}S%` zWs#^*GPAlJ^2NVz;E9r#NY<;E$w(W+c>h+=^>jm?T~KP!36g*>=;$!GXEEv!*tUd- zG`*Hvy<xo(mWQd!r=5!%tyn8}Zl-4BM*+BuYkflHklWz|GwW=K+xmNs@<Kq?Ea55r zc5Cyupe>GQRQuibpO8D_jV>iy*uV+W#c5r7CsBb0h!;OGd-){fF>A7tC%M?98<TT} z^Yqc(RMxOi*0=Kdc()>U<u1>~j2zwGpK!!eiFCQ?-Ez)ZpGe}B#eSTixF^YS6U?2v zJ;ANV>EhRrxhK<mZMx<82kAMP?=_XfvC<TWSHm&uhkjH!=Cvpzl(rQx?(Wf}2SSnK zSY$rY*QEXaA3`Q3m{eQy9|tZJg!{Fqj@zi>aj9_1N=qZHV`GP2{^m{q08I#WQ#UgD z5pE6Pa^z)|m7yDFvf|=B3ff`mArLAEEhb}R#;g3Ag*I@*p{s!uy#G7X0ltr;#q)v+ z5GJjeAF221@A!Q0go}q)H2M<wZ?P4H1^WM#U~yMbcK$8QGVPif4?~7vxbSC~s4#iR znUOMWTG5n<6xSX3HeV?a-!B1R_YHz6BFlO=lrOKY!rqm^CNlL;GPeyPQeBmmM`L9P zLDfMSk0jADjwL{@k2qzOYRmh3=?`0gfX}V%GRml4o8XE0U!ryu)BUi+Z3q`kQQQs5 z^r@v1NQ?fbcmJOSVv}E4yUvTqyQ0ZwW!KL{L2!e@>;2qDU{Yb_8aPMPw+43vBc--* zSn<M;x$(&zFquBtvg4ul{d33@<@ZzdcBIo6V0ieO|F!M`cnQl(bYe415jZr#=Jf^5 zb8At(Mfsj=-%q?H9u&F}@49$9w&rQT1Kx_Y<lDSx(s{=``*Hpi^!l-IU1D8z=F0Bd z-4~wFSM-~DXW^8U{sPyp9UH~-{t&d|zUouchuqApCVxLIGl7wlP>WwQ{)bsj?^<Q% zpK?s8!_u`-@)5YPX!ad&KX{y@2RZkZaoRyV!fqqwWXSnL*PEAZ1)iNAWMJ6h#PnR^ zD1eM1_nokt=VnL9{+;kkIfEk2E)}uuQ@~<^6>FdI*}LiGioPab7twr^=lx8;w>yu+ z$eInv`!&V+rPgjWO||N^pUuhb{dCgov^Sd4g5v*>N!-$WIt4@Z<)|{fiF9hLlD6XP zO=H=9_>Xu5T27QP6lEmp5c6yH6}0m}2`JB9G|nRm7T5CQE~`hz5Lr*!t>b)~Q7vr( zLG;+PCm3C*z2lhAsDsutF%*5JYmjVcBmQ2s=&7p-sbb}J$J0)jNE={!1WNeb1)t06 ztXq*uZYoXhFtWP>e8X&-bC+WoztHzLi}z)W{^O|&Hsn0p@##W;A-lkTHS&jN_oZL` zMC`9nsw9|=9(cW;BliR;H4GGBY3xujY_>P-j~6f;)qy;(AtUL@+LL?iJ8-)$L0wz4 zs3~*Ay#R>c$ArOVAngK(ePjt^l(0KM1|z01akZ$$tTa@-#ad>vCm**bV#=J{;-BQ| zy96-@onhocFI#@?h*@`b@t=r>PZurs19K|~U>b24vQ5}oVh7On`TY@if2MK(<_M}g zCVK-nrr78@D=DS^^%vy@VRJ4V1$O00P5q7UL#)|x7hX<pxE{c;MBrgA;#(Ht$z@Iy z_0`l^`J0FA(qnUH6h9ykXBVJSp^LtW>W%FO7QJEief@5x`t2UWwnvmybCI%jBg(^( z9ie1mctTyEBJ=HgrvvE=9R0-mF-H<=B_oH@+K<gS5C*DjaEegVc}s*&E>hWYcD~i; zdD6I`rpL%=a{+VV_`RBG^^oaZ##aK`u>rkjF&0}WP+!KjtIb7-S<NTEuEQK;v>ZmX z?9mAA2Va^$^V<lFguyhC3RFDNy-5Abc*X%ERI1dG!-$9yJT!4#uH=?>FKdjp_vQz1 z+`s)KTEL;OHZA9;-SOyIPyy@*Sf>a>=gO*ZuDsWE-b~2OfMdUi8js_&<uq_Bls6o? zmQyx4u$^)%5ybwI(0SK+@e3#=ieT0K=J^$`fc;tjIxQ0NhXX-o^IJDQT#T*h2|Z#k z0Q<a56T9gTK?BPxjDGIE!?2xDF0ftv-uD$?LpkkRY%~qL-E#<^*_^F8_hKU-;n-Y8 zo2pq0CQyQ+v{CVVphOvZ*8%zhb8VBeSIP2x{@wP#wTc1FVGrwKkej&hL93?Q+I7<@ zkIi@K6OJ(=RXvt6qW8{s8hWTGAXU5wF<l%_yfE#BU&`Yko$|0Z%l1JgWBPDmU%B-I zA6&qe#;->5!A9c3JEHXyu{>ZOCd&?ZsG_%XG$tFv9&xRmnxfNVQUzkd={PhzstPQ& zCGu0yL+3anXsU-?m`=BLsEd?rh-^s0`IG@hxpkr8lwp)ITZ634b&>YNH_9I?vAUfP zXl3%v1p0*;B>FNnbD#J)?@S_!B!l_hZ;U{kUx6if_Koi=C{1hPOp}M_2Z&b%8%ZqL z<3&A~IjLWmF%Kz+lCl)o4)v%A-tKo97B<l<U4!K(m!>Ozk{QN$h|Q6y$FJ{r9!IMq z@V}61)t!NOHm;=50`iXAWt;mEWq&TkV68ax75|Z#ezSY}#3H_FU)T#q9SzBxUHXc! za00KR>U+s=WQY<Z?*m`Z<oyYPD}oMaReET}t@qY2ov6|`+mYFoZU<F`d**VHD?AgK zT|QzO(1oVyv%9}0`*2phHT?AZsBl0laJ^l*n?#X+#ITIFhBG5S%o^%Zi`bbZ+6APW zfxC;Jit+Y6w<p<@DZ@?AyTyS`{7!>6Q&CbvKX(&}^9tn%&u(iP!3-B;BN0jFc!Lqe z!Xs$=w58GOA4aAJab#G+t3>C}4`bM{pjWKKTutZqh%ezfG3CJ<Rh!^<OQU1){-OR6 zc}Q0N0qngj!Ox&}IgP7S@pVyxl1GXQXzbWZ#4iGIXAf<?G0q2F)TpgjeYc5pGK}{q zlYA0Xz<E(lENQPl!bP@Q<AIRgar&g!4iFT>+pv0mn3x^v^aG^2RKo);ByXNqYR+RH z*(Iqbk04fSJ#%Bq$`>!%iQf^ngYaBkFiDp@IbsB0ZaF}Rmqun$#{4cV_dMcHF5$^C z?NIv4cunH-Np4H@9Gf{9j&gWV;KYk4pU0pD)RcDKyD-0ffp_V=d#d0pcwPX5vDGz{ z>H_YZA~Uh_n`A#9G*jN{0`Wy25(cF`JfVBAV`EamOCff;L9kO*P}X}lhB-9sX#0p3 zOu#7RDrS|#V?d3&^8}qIN5K6L;=#Uax|cv8BZ#Pc|7h!bieM+y+qdX?5~0d79Yar+ z1JW@Md+zo$okUE%y5#RWl7T1|e-TGQotCU`88RorpRIJa^-~V-f7C>*X&2&ep?|1$ zJd3P|Gkh{h-XJ#}m==Dt{W=WK{SoypDjnoMqH0)g;r4g_D3(I1IKNL%Pd5-GH}a^@ zUs6FZk1MR(E2$keaikIw*h7@m?SU8o08+&8G_bMvrVU|FfH-o|xcvNlh5G-BVNwGB zQ)m9a#3}{-YnV%)zimRc893elcY*s)b<`&G`|RJ}s|Rs8y63lKW%z^S-u>GY)kj-W zf7eA+la+C$0MuHm@L%Ndgxr09&H^Q{65|~|9eoD5b#Iu2K>fk5wat9aSB@A55ZWHd zfzaN?EHPd;p0AyS>V6?lbmnrEhR8;U!RcNGCn7pTiX4l==ZN~_Iu5X_^YaX{P5B>j z>;ewY7m0Ig>)%S0RlaXs3+38yikt0w_ZmwM&FgiW$-)4G9%O8AivRH7P{{vNn@<xv zG>4wkghf}Y$5RtAy%21emCh+-o+|HN@e`WZe$O=n4df<Z9Ey)m0FJG1x||n%2d|Gn zA|qzwRQn(>PI*+hgp?+YLP&btg-+~>JcQyV*Pm}=gh9Q!Xom68$Me|A%6gBbar=>} z5sxyadc153SeYq)kbchsPP#>OOGuk^;CD>*(6<UmpX2@X08cEqI1v#unbthPbn>k+ z&7tD*Mxy_31vg~ma`^EmCnBsw(&h6V>xjU16f#FD^#$l}GBB}&$Tb5+o6g<Q+J-Sm zL~Pla<0QB6%&X^l1BF2{1>)+c6*)uefC}RC3$G{)E4$#b0fd&S<1Tn1ni%5DY)9P= z(4`xPU`yL5Tv0HEom~jAjDRWfmYm(*bZ@?c*`4m%lwOl_@GlsjkZ>Uxm<oNAv3WxC zceabH4YDxm@)#RfRx{^b->0^@^L1&+8u5jf@7unx8pm+<{h31A7dNxhKJ?`QWlv_G z(KQUN5?DKgtWkFwDX<2b-#t67$YK4*RK9$0Y<$YK<Eh0L4nZ52AzwBm1Hh*fH9DTv zx>O@oS-HRr-f(eRaOA0uk>kil-NKg{f5Q5GBXh6k?(`6S#Dtf8iBXZMKi!YC<%m)m znQnKJ7sl`8anp@JYK<#ps2z_nH7Dg!QaUHeEVypg%zXVFVa-Uaq6TeF>>z{<G(ZTD zM01^zkej!T5bpYg2czn<w-D2df`dhRS@w7NMkM2A?OD*u4C=QY^mL-Uo5qki+r}xI zo#9+94AzbVr6{>i_%PP4f%6B!8&u23ah`$DYN96fzc3;;kkY*+J{C`Dg;a&O<!oLI zlq=y>9=$lWJc9t0VHx!Xnc4mVU-KJkm;cn7$;(q4po>1EgYXyNh17gT7mo&p(|WKf zzDpt2{WDXq!rM>VP?%Df23ni)$E&0ZMo`rYv>b&uS^YTw9DaxE4Qtdvwnup`DZ_JW zC1;pws|agsh$i*;W>*2RR=D1Ca2aivfnH{dd%E7{&MKo0*sOUo)i_qYr5^t>LBIDj z`3VlR5VOM67|LHbNb`Z6;-7^mKZ#E}u9QC9Z-y`uG*#KzTd|_+&`2It+631w(K#yu zR_*G<9hLbzI3!L}FeP}7V-Ii!LaF-^hNC!aC!0)c7=R&YN|{iQE~RIie9QQ$&ssUB zcici;U!{u4vU$wmr|@$kVe{6t4~5*jt>x^LZ(<-YRs#zsj~!s->rMSVv(a1X_{HjJ zcOj+{&7venB6uM1pA|NoHTV7WB0&h`z8sC;o0@8=7f*!~-~o%l_>SD`y6OeJpKG*u zbk~kS^&1%A4X6UEjcWWH5c`in*s6A&ib6G5n0P;o)n`;+uj`O`x^z8P$8#+mZEElB z>nmv+;tt<_xYL~}Mzm>J8=F~~u*YdIv9|+B>T)&Nfz;lCUQ_q!)}z?@iy?VVOjrpq z=JI~<fQ{ylhJ`j1RuSrjh&qCJtEYR@V>FQWgL|Dl;;|4W0iC^axgpta{PN{xJquS? z*W#mpl=Cn9BlJ1_qbbZ#07&5?YTr-C*kq2rKMpeSWt7t25-qr|%Bs}6k3%=0bbfJ& zI~MD<yR$+{00&|SpeT;{86k2#xULQx@Sl)3@gIdfJ*Th_jgmHfp-*53XQ(*pVRoL; zxO6%yp9?cF_W%JBjP`eYUaB)69vkbkC9F!G7`)3HnB}m9`{`?KQx5T`Qyjlih5`RB zP`XOm&k69?LevY)E)oTXuK8Lsb9N>?K|y-Yc_!fZ$P*qBVcA9mi9Ip@iLv`Twy*#E z@_c>R|Mw`N^FLwkZ#2t^te&G9u#%QuaC*qUsep9;7K7?9SPd4Io?jPn2{60b(ik|v zOYfH13~|NV1a$-}7{XY!yTl~hMv-jNTEM?&py46@64!KHM&!+f_&@hEY1^J@;=7Rl zS^RBEt%fKTp2$8ACZq}mU8nVgu7STzszR-GYSA7$)hDa~=2wB&qUOj<>n=0%t^sJ6 zfS7x6YAbL`yZBb7rC52q1c^IqHJEH`Jl6MhU+`ZiWr_?Mo4-uuoVT`ccgE)mK_kUt zEzjb(c-p!vQ8Ji6Y&=Ig>hYdBf%|$i4nT!G=QNKKiFoB08TGHht$dNJ{=G?6kX}EN zf|jzdj~q&s@7<$VOFQP~@vQ@pD@&>rD^)P`DJr!vs%j7<;z6X?Zr@FM^4BO0>r(CF zC0>?fQ1%69wbjN1Hpp$?A}8Pbu=YD>+DZQf0bbwt4a55Zr~g@2mNa18XCK4=8P4`k z;_2PuG=+}3ZqERln{{ASACzHCln^@T_&02Fl1)(lJ$HC&176cu81vLzA3LKyO6NR+ z_?crcJsp`4(IRpk)z9P5zJqX09cXQon66kGg!aNSds_&y1kF{UHOhz2=gSgru<M~T zA<yq3+9^9TtaZD~S$Qp0ll2>YUVxwm5-Z4<f5l3GRHmgWFJ&_HF|)-y$^%AUAg^ri zDY{<eYTorPsAzG2xP>2i&o4yE(N<MSD|C8Qv$)LgcStw`f7u6>uJz57L<A8G0AsVZ zUP5_<Z4iY(kr@zz6syO7>xewEV;wO$g9vfY$~HKebVNx!@QZ>5j_=#^zCd4JURVL9 z=DLjmu7J;V#Cm?L`VUr~$BQ#FhzqCaJl2hl`UABVepX8Z{#UL(P@ZA#Za4Rf5_pJJ z33Fj&<Ws|LrauLmEa;!}=7=|&tTD%b6==0ehPvRt!#LL0n>tvIjgw(*cy9f+u<;9x z9dJgbv<pEVg1l)%TS*hZX03y`d;v<k5K-P-o5>z`{Qk3SA>ZYL?9ckFi~pp;l8PFm z8oOGh`lddmXFDF~8E?;NSCQ$}7HRhIbNPP&ojJKk9#)E>_N|~{(0A>IhL@Wqn{EW- zgSOdDPJ5@V?2sR@Z1Pd`D3Xe}CW^d--EF@>F$;dPZCDf@pmn-8m*#HJYpGIX)Jvcm zeNg`RTL15yf#rnL0ZvSDxTaV0Ld<_E&pgJE50)+SplB<+=^LRx-|PVZh|wmH25qRw zpgF8I@;G&96IP&t(-U1D+S5dgUqftP#8;f4(N6BUh>molUnTNNfH=|Ff5O+Bs8BGj z)WRYb^O3s6GLkF8t{Kj#nOG)*A-E@b6(c|Ut@S_49p&)rxoOTntes07*CQkLO7F&u z6uafESxVJ^zQm)q{hTT{5^-h5D^&FDYm;8Xd1Lz~l+E{9<k1wo>eD8zP!zKHp{BI~ zt*?y?5D&ENUf0#9sAyF;Dy0*RWrU3@@=;p(;4nzJB4Uc#HUgBYYVVv@XS6qIh?9{~ zITGUq6k25C>z*aVPCu3p##2;O1Vu}`knD?kyHIBbMAEg>PRF4J`u;<EsdU@Cb6p;` zJU~D{RyrOpDUrtCRko3gvJ7axtQ@?HCJrEpGmjpJt)}*>seT{}37hD><W`eJ-_!mw zv9a6Z);{ueWBL?Di%o{gFD#~Cc5{xVnRo_WsjORln-IrffbZ!gx;$@a^~Jqs+C*|8 zRe<>eT6(rWVs+DBPQYK8LD%4YYz3;DS4QZ*5ncHdQii1mL}?1;Cu%|`U@=;cZ^CQW z%h+;u?M{^|Xzg--U<LR(w(F9cWmmz7)_KDHZJgE0{r!~5QM7tXCWIwpT33^!H{)d# z&zJ6RK$vAqm7Lk<#&^=1`ubyE<KiY<h5upx>5Qm+t}R5<_SWh3!Sp0rEqqOxGen{u zx82Al{pmXVYyT_G=r#Ko10H*;sjP$rkU-MMkgA-||57L~Wr#`N{qUl(f|`G!!VNN= zFe?pGnr0IA_zxq8APIHhjGFwvGaf>^{{JqcRf~H!ArQPuY)k4?iH+xuDM-bd#1YTA zC`iSw&SD(Sy={u38s|*cobe6<S^qA_r818U^Y)eamQG}vN47CGYY?{mZzz<=1#v`H z$H#A18v2UdRaP@Uw>ImM#8Us|;n?~Sz(WyZ_ud*~MsA^(^CwC2){7aM<Fq!s$awj& z^X8s#blr6e`UN@&JZv{bf-|$vpRz$qg1yT$I+lMYgkJZ7@h_S~i#%BE>XvxVF_2Q8 zp+wHuST)i~+AXuq4Wy_ge&E;f^;qQs#Dgt*58p+B>)%!uZIqm=&gXSuY)R1x^TGy- ze6z>heixN$?pM?rk4vxwfRKq|&>`Cxd1Y@fFG}7-PMV<vL~y1F>g)-{*8yc}dOHe! zb=2=m%doSX5i2keEygGRI!={X)F`$wcv{~U>*)BY-}op{^53|k3=VXxg{f<bMfcWE zIr_n!C-RC<Xp5uG#12G#E2uBSV;bX}xhT^&yA89d)pUa9?zwBKei_xL+~P){=POf5 zfK6m<J=?o*8mzs}hPJV<)zXM>i)U_c3)>WW!_18A#!6SM7-;U%g2^8l>bppfj<?iS z0VlHasG^TX$7Ahh<uOoO_fFr*iifV@{;O4LmNCXLnpVq}WK5KukNVN<QRc^=%y%%F zsmObGTDkeP*oV)RpqCgC&A4tkK$;Oa@O8ro7RMOZnewj*ll^Z`ZO?2P3+vO?87LhO z5hMYdHa%>o>GOR2B;&jsj;7<C5jbgN1j~N-JQ=8<_Wsr)<AWu$q105F7I%+a)rzo{ za&h1H;i>6pHtNZBM4lU=yG$tB?HJV-#Hdy7o~U#@m-1`NRHVQDLWd3xcHpJ|+yZnU z13Q3BTgW$6CLPt?RXzjLxkj!UiLK$uz^dupl=WS=u{CZgLmVS#SkYHu<Ms|dcPI5K z2Y5~gDLXB3d@WzanC*<D^gpQ?sd+6;uqFP7lEyR~io7(C!Es?5;p(k|_@oj-AQ**S zU=<?d?5`(mt%}l#&ms7HE+o<J%UI?pK=y>+z|&^zq>ojGR1a6X2uqKsPkFb&3klnU zrHPlZtIk|`;Q`)OCZT<2vZZ6crgthint3w1`NUD~e(0|MdDq*4*;vkkr)4{z@2Tl3 z&RpD549nbA9QO7=R=4<f5ql!%B4}khEYpS5%FY^XWn+t@*Umg5L^p_-RuqCGQ(;8p zfx@etNzV%T>=ptq5JL{dU@dmkM%<%24j(uQUpWZ;wMt}UQO*HDqdKvQmS1QU#f(iU zIv~BwAjIIQW7nQw{B$07Pl2EnLR$GAin6Nz)&e**BODw;t?X^NB|M$Cv5c|?t{^Lt zWYZ(MaO)g767kwG9cD8AL_wIj^kK%vZul_3OUv-4ApMMR-X#$&!c<9pPvQcMLYdF8 z6qNiLnspkr6tN0se&#p9R18(Q7yh1|w39Mf&k`>{Un)m;#Xv$`<@4+$Q9xd@iSzC( zl&GHDds*ixWhQ1as<Ngahd-<-G(|Y9X+jSbbkfvqV<(~hEd?j+)1OtVorVyv&N^5) zR1h!mmW@YGpY9cnf4N18#5%;+gg(0!<s{^q*YqGRu+WcI{YA1i6IaJSf8i0uKXj#o zH;FJdsG4pTKB}hT83+4Y?`PftRAC4~khF2?4o)}<Cut(@d8m{r&Gces(K}uBG_Xp0 zD9gy+^7~!OFI5Vbp}}0T5#DwgHX9;q#>bC<vs$8UXs;L|IAn(e-id4}rJ)nLt2cYs z^2IjE@7b;A9;`KZv<9>N#Z5%Id>8D7$1GwO<%yW{CgeexRO_?9>5nm(L~Niqham4> zA58Bm$=fKlpU`!lp3SDyvD%Lvi^M7zanNHNUf&v#EzqY3xX?4G+aR_~`NAJI8f7*U z^I0tpqAM&wrwN$V<FLgLX!(Oz5M@6EE4XKsNtZZg=`WH4{oXqrL|*sDGy;*dR6auJ zP5`3b8aBDgm)avJ8wNWaa%j1Zs(NC51fR~j<y;5~`f`j`f6?j&^)35@$&dD`5%f?D z{6(Mr=i6Gs?*26JgZzfU009cbo&HTa^{9SzD*~JMH+t{IM-=-_YgD_04LW`Fu*tsO zE#7sHH?yA-5OU8GOZ(S+YG~>~OLR;*Tc3m0F|Y-n%=a-@2yD=S`w;mz-0kyI(nKfD zB4F&C9tp-WL1Z$CleNw`tAIkBewvp?VypP=B5X?Sk@qp$F@y@SQ!<Z+mYDw&2PX32 zSL#NV*H~@K>!-)p%=@95!+8nZry`IWbwC3I8aLvDJZc6fx{W0x<l}GgNm=k~Yzf2s zrVdlWlOl0(uzAr63oV5$O325BS6jFJC6l&9?MwM)K!rW?P-*`0#!d+V@%8wQkD1fd zWaWSPp0$)vv!dFh+)(I((w4_0Izb3|w3fAthSY+`oz{J(k8u)WpUxBYuJuu%{8`wF z73v&o^{v$ZL)>4$#Pvphzv$rZ?poZPVns_^THM{CFi3GI?k>e$N-6H{GPqORp-6F; zQs8V#fA9I{JtyzYO>T0NCL}}IvuDqK*0a|4`&ny?dmUlhFvnt>%$}9d_u7(ol-Pcm z{}l`~5qyPKhu%QExcS@jTT+UrS=s*-A7h(7hy6_pOd=EeqA6Z0Do!lb|G+P0iDJ&s z7;pP?h2WPB=d+=Dy45)aUhQi8)%#gG4lQ;tXcsR@9v6*1sIN&<169n@T56snOt>bD zp<Kh1ng4ZamVvHv2s1-r(iDrfp8|fhynV9fic5{j&vZbUDJ_5f(xa&s&1P2tCn>ZK zq)am&_r0-G0fww)7k_n31PH%hyIn(-fubjv+|qx1dz=0ntv|vQ{QLM|`HTCo?(wb@ z2knd85$*i$)>Bl?!7+Ny`yYFO^Oq?;IWh&-s`v$1(x}OvgbI1*kOqu_T<u{7Ko!c< zPT&p%){X=IPuaF&6{e-S5}m5|Y!=a3jSTZyx^yEneAXcZS(Soe6oo_|+O0!?LqhP{ zk1egzNHF`FVD^h4tEd6|5XA0G_%Gy#bc&?yjE(P;*Bv$2YJ<+KqT?rjC83^wT$qux zj90O;H}urD=vQWrny}yyXWtXDw|-6i#UPldH9eIF$lq;Up!wZwG*lHLfir8}4Z4A2 zj#`b6OHS-WH@CrS<#=fjajBq+JrouY^lj?iZ~NEPU|qmx3FB7e<XIBnV`tj*JAC=M zXszOEA+N8E6gBfLA{F&#C4Wx^VQS@cZlI8$euQNQjE5vDO4VGFORuH$6e*EN%6YEZ zs0i=0>j_S={V^*ss1go536xyeRCe5e$UDOETcS-F<TFF3v8=_Dx}jEUCrKKx5OFCp zD%NKpSv`SPyerfDdymI&Y{l3X`+oP^M-gaHrF0RVbH08}XOLMQ2CKFdMicP&34el? zX2vni_t|PfO3lcHQl)O|s}jaekm%3RY%WPo-J(LOAn{r2EPtX<dB-~u`)t@Mnog>c zTU@cdaDW=O1QRv|NO`7k1N;(gW2`qKrojO;8Aj!`Z@8#}GcL*d1lNujm8{T(-n{v2 zZQ*FjUm?Byjbj=7Vw+)oR=1bxjtslda5Q`&)Cwo=*!J=w=XlU*$s-&dgHWyag#|qV z9d3P}pUcfksR3Qlv=tt!lCDVGcsCne2`29upyrax=nLtPS0vJhO7~#2XX%Q{r?<Mg ziscBt2y<Fb+zvP6ES;7lN!miD-q%J9-Nhdp&eYlpwG1XJtZ>~#qo<+hGGCS_ZNi81 z=DB@0#Wpc0bT)ro35RDZ%?G5X<+do1B?lATFGwkt6J#r;k!SfqHGG<;?8TNn2PU4s zHv|w4>}(I-aOWgc*MXYz<k3@S>Hy+m2l)P+ce}+0u1^O*=zku{cbh+vSzYq?ndXoQ z3liGvJ8DgsI7u=SSK;FP%1Kl}qDC>D8_)inSV>o7P5x*{&`i&u^$w@-ow7xp`wz_| z#*<1QTV9fao`|rf<_326&iC<gC|dIM{OIA${Z6m#{R02whw8coOOro@RL47Bb`+SZ zONOazyXOtRE~`aS<7ZFQ6q`|KTN=+RAX#a+_jQ|_j-JFIIDEyNsyhY|;(hs(y&(Nj zU&1(_+z@HL6ia&Fu{MD+<hCQ7pmuhZ0#O?;f}pN73Bd??0mu*eS14rLpqKo|)_LCW zxm?}=%5$Jdi`6C7V~5=;|LBfFoHxmil0mQg>9~P9#^(w0Z`+p~zo{{@dR6PrVh_5P z_t5nb(#w<j;rxb(>`hrakWg{ZmQBdb1au=U_@xP7s$eH=U?Gm0Ld_uJ<TMC;Q5vG~ z@N~;V!(a%Nx49juQ?s){8yFAFtQat(=BJXLOZYk&trOzVb_rTKBS5#;{~G`6BQpSt z_yS?XKTll8{a#}33ivJ_?sxT#evj*YZ1-8yuzTxdu{;f(H9@UeCO^U3c@QAUCRa<% z9NZbSY*_49W2BBU-q1`Wb2?5*F{imPW#uz6;F%Quu3CA|3sZfb8kJ8#8XU^t(@3<1 zAN#A<U@_7{Gq@W$Fy^?D=))(menix|?cFcM0*b_`7xZb?v{{}MnNTDZD_EbHIp&=E z1mH23%%$21&eaqZ90T_g??<F?3S#$Y4q^O97{jObeK<2tsqu1Sd;B5|3wgS_qHazK z-jRRTTe+TEnGr-fmY_Md3Jl?e<s3^U82Whyw1I_Ly;IPk(N&EQzu2-xXtv3ItY=IX zpesRPQ?miGBhZI-6fcza_jOW~-lXkU_2qDM#Uy2Bnpb7c9Y#pnOck{Q0jcN&IyumQ zN~2-lv2%FV-F0LTtc1fNq!Mb=@#15+{J<>MS}^Uzx?h$y{p75X-}Irx*AhHrf6sR) z#DQl^6<W(2y;)G4UkJ&%8ZkQc?*?asO<3Jar9Zu|4oHN#oFg%iK+x&>eQ2Y>TiLx` zQzh1~uwui^<M$iAT)pL8Owe>6P(FPXf2nb^N~LepeW2u4>kjUryf$ibcg*z)?(#Ia zs^{fC>Fm1=tsnK}kON4f?LQkR!kTcJ8mGMA<ci21gKM<(--YbMPQJ1TH5_o_m?`0% zGgMq!0TDQHhc;eHwDmVZi)eYVWQJ$8wAdG!+85mmQ8KSBs8HM}y{ox-Zu#TIC`{Vn z^upm}oC|g#{>v0aT+3fVFC@d+X~hj_L67Gm0>>}I*DOqOhzXI_{yYkz058#66d=vq z8`Sme(*TAO$ZH*$irf{WS+`2~lPjqm%|bwaE>+K3;_HbRFItD|riOeMJhPu~lRl&C zztysu$cqG4!-!m!RP8jYeHvAWoPk~g#R&%#e9{tuUE?|STN`G{(;_27!@vPwB-BjO zp2%y2ZwHd^q$EEgfjYF1Hwek;0Ef@%$6n4BJ&`*oI-@$ijK6EvXk%$WYhv5EqjCjx zrClzBcHJJ(hQ#v*K+VA!E#}eHyMHwe-flCCz;|;@`h{<G`1bM0v`WJxMJF_jK?+0f zJGS<w7vSr=eJ{<j6Hw8mf;h^hSmo_lLV$G2Xl=QeTQ|W?)`%Yr2o9R>t^S%bA=~s8 zsZ9!bFf}r#=}4f$DB=Dw&$*95#lfq|CQ?XGUQrjrm7C07u^i?v6TPr!aR9IMJ@L$$ zWkpW+md{j)cpAY;E%WUl6UJ^e)ef#ql@!BmgZqKU+7-WXaYbNl+a3-$pnyd0W}Lk5 z=WD;@(qWRU=i>;PnfL1_-~@^29&`!B1-h6RVo3Jc;*BsWgpsl63%o`rnVGQonZQ9H z6BUhPQ;{<tB7i@-*0u1ai}huGTib+MIBkd~=-I1%7Om`aFgj(3EzUqEJe?{u=&U=E z;REP)@4^Xh?Lu`d8VVaqpH8f<qPVkiwLUwa6L)lC)+mfQ42lANlHwz(oU>iH?ag>q zV7gW4{74JZFX<<ejT?htlG(q@bf7yBONuEcMh|!mR$LCH*4>^5&M*0&IUtUSg+<qe z)x+}7RhA<GR&tCKZHVKmqbCaj`1gMvhnAcVXkd;Z_+SnpORNA(AUz0fhk0vd{uQ?x z$E#iJ;@2AfIORqVT^QEWp@Lq;BAS7s$<T;B7Q#7y>`J|(s(we;oW4A6^7hr{e^<rm zZSp#<_FVe*V^-^RXe?Rtu}8a0Z%}U=ccL{zQzxxjf01HBRwfc`5KkkbpA=lK&kw); zpoudoWGH9}m<&BTh;<c`y4*NpHi4v%9l2k9MW=O_H0wu1<bKHrLg;iKg2CddqJE7$ z%BCvQXr9C}*5zOI0>MAmvx<z=)gKFwRuLGo!@WlZ+Z{A?SAS=$3W^;$of|H4R<Udr zI=VG!dg=bMD<vOmP*<olZeXHJGgP!G-bq|lCpX`M)alk0f0>P*U%z|k<=O|cEUYd5 zX~AecuXSq<c))2H&jmLxtX>%Gcy=5q-3X}cuU#$hZEOH@I*j=+L%1m<h61c$F>JuY z#l|gZJw!-If*MW67w|tzTcQ8?9JaV~l_<Pbly9&-@CKzIgat9Q+n!VRnA@rP=F$qw zIt(xDWR&dN@dh}?9BD@p)p{nE)P}Zr7de+Q5#Gm9zQLa{)4)=!n(vFq3OB(qCxc52 zBPy0Z2RRH%YkQCkrS*0c!oK0cbZkqkWgez0$w&=WaY{jJVxObyOtrOjusfnsrO!Y4 zS?IZA2)!#R;ef_`9NrT3)<NTOuPt0}Wi>9)tk$|E+^U3kSOK?XE7?j9`7$8fJ`iPR zCdt)%pn@G{|HX^ehW|c}euL}T=;F5!8XbW~+6hj@z<oa=>hH-l-%}t(;lUq#`S7_t z;gY3&m~fNbcZ5|8q0~(Hv-Ej3!EzGA%0$McZu)tV6L9HhdsgSQCA!i=UtY{KI{A}R zUUU9DhB1FFQ%&0=tZE<UVOGm&q8BZy7}#cUr92;utWhgnYPToDNZeb+Q5I>>GWKG~ z$x?E|fHpy*{Wn)C)r%$!_2mm4thDUpzw3T3$&i9;M&syH0VB)>r6d}6a@RV87`PAd zeWP&fQ3;`^+bnPJ78AIoNkkQU2X{pvAkEaSvt>H(eNoD?uU%#rsg(k$T_;60X3@ux zlG05pQ-K2V-kfk22dJ+nHCRj&HQk~%EsIVRDT~HVU(&AL#uWVR!?`l8ln5htekl%o zFxhoWRrU-lANlA!fdV&OT*~uLEAacKpKAGzOy$X_0y@Je2@El{kL=hm2aGLVo`2&C zcJSNMLR_~92;o6y6fRPu?M|ODaw8}%-gA(dJ%Pclne}^~g?NCHmCNq}Ujm;zZS)Rr zkv&lB<?CdSn})BfAemkv;d%>kwOcN74ovVXF@MdF?nAJ(U4oVN_lpsuz?yJ=;bY@j z*f2X7%4F%75pJrLnV{987`!<zMk9ja8lovJ42KH&Y>C~x_l`(nb4(WV8#On**LXrU z41fNzzgKj=+*RXaXN*>$SUAg>7A_7R)QyT3w##fmP@ID+Jyq8*Yz%dnQg+|5;I&<x zeDG_0mP#{GX^Jzq%O6vAA<J1R{4iG3X<ir_l6-ZQmb-Xm%de_nC8$(rs+z#2_`}o< zAEQ|@nbC>I;W;J92RjZvfqr<i&}!r!$W!{gfb%g@FEgY<b`y|9mbVHGU54?@g$513 z4ME26CH#<0?I(S-SSn0}9-LIJ*V?r2{1g>o?F)8KxCt1p-o7|OY0ByhyrjG?@qG9r z$i~iodbafr)UmZ?y47;i_HbQoJ_Z7@>$P-D703@L|D7Be4GobYO(h|CDV<omKJ4l9 zf`)^i|3MsCG{{e!J<#R1!l4l9&%e4nA~f*x2>R?<{<b%OCd4k(+;GiV#`vrKQ-<XI zFCNJL;#oZp@qk&3{;^tn$ZCJActEIWeJtzJ;<6r6?P@L&)(8KukIRM>5*2$`Jmb`! z>b75W9ky}y(sY?87_&Gm@}_OUrF&fBFV#bN#P93tUur01q8UtQ&k>j2Yy+8)$b4QB zB;;&scl}kUnj#5>Ml{=f%q!xpEuuqJk>qku2ftVXTlqr^;qPG$PTr%Y*q)!4fSa;Z z7ZUiHv)<NwPT=Pp4DtwB$>)nMzqT0k*;6YgxXWSiPas+3W2Udm!CjeY5-}w!DIeVA z6bhMBg_@U2u5X@pSggsjJoh430e9agTqTm}o>zr=YLemTxq^qCZgP-_n3k++ZZ-bR z=$w^;pvKXPPYQRWf1>Jy?OgyOAa;ptU>b8=hr#T*htlO&Dp6b^8H+N*H#Cj|Q41?U zu%og}dsWm#+bP*$KRE4}#N#xIW;+<lr(1CMLMb0iaPCuJ-%PIMGc8#U9@k<H(0!|e zrjymZ5ROcON>(O$Yw+q^DUnt@jxv&zHY{@Puye{arGKcuc;7ftUz@aa5r(qK=L;y5 zo9PZ1u9jv#j)OqMY{VFvKlvf&OCX<Y#SEQ<A}>DQ?C-LNJgLtRu;)xmRwV1O*fcma zuk0$HRx^ZY$29p~b6O9Ug9n3=TF<%Od?)8=HUn@=l)d5ERANNplsApwg&U_=P{!E# zqrwpma+-{Al1tQ(l<{UDP5YT!K-X2a5JViVihKc|zq{dA5oyv0|5G%~46lw>qYUCf zpppNFSh`yy%B~aTeV3q;TSVfwR};N4;au1O=eTDY%nOO`JB#31&xVh%#jMIbMuE5@ zsLrm8#b65}8pA(Kp7ak4h3!&UZR=j1xyV;=2GcW{sKD_)aANQmPU7lmy3%`4yu^K8 z4g5Y_yHHhO9Nd9<jpdQ1$4c6xAfKY5TAEplV6y7M$8^W@+Hp^lqi<?X26OD++Lp=i z(C^#?B;2-U>QqUPSAi=mlYavK3bmp;SJBRReDproM}(M4iy|`pZ_E~@mfv^!cRwJQ zwaUd9pnY|)NciPInWd&igA#|8Ei2EAsflg&1=Ysdc%q@*gJh0}f6Wp*Jpg6tG>F9Y zk7azpz_jO&)Y>!%GNVs8K1Ox!H2ZrfofFaTI-v{sk>|HHEsBn)D3?A3;zmK#D;5@| zX!jXOyp|!}zCZl=7V750-I}HvgA|wFm(3Y%#vDyI^q~Y&JOz@TobfS(K`b*UAA=xS zKE<F4riy#6l`2Gnae9j{uYEg>RJ)69{9n{TfhGm#Q0t(<EkoRzD+Tg=A$4F{s_nus z94bDw>%c&HiCszTQLD<Hmw(Xfn67ZQ7d|3O#4BHh@yS4xI3sc=bt=)24{-28%$g-d zn}R5;n>-WyI`CyW%Mn!R-<9O#k|&Hueq?~wj=wsozonM{OX2C@Opi3EbK`yMfgxM~ z*(c+XkNuchqZI#yMKyFBnv3@3&+R=M7X>T%2s#*XbUh<L7?xTZH~*EbBvhz>I0Lf; zLas&DNighazl0dhw;37~Y>)s!h+I-_pa=JBH44q-oE8=6x^K+m_GW{io(ed#<3<<1 zn4|<5tjQ&X6@=k3#6;EF+aDwZ*Ho9;hr2uen1nzC@1mBY2`mtN1$j-@Q9-xm&^0f} z1iW2;0Ern#Y}eEW-^z#|LWiVTo+bZV(C)$Nl0-OTynDR}zp*{BZceXZslGJf6KphG z?!L-;`sda`M^A49n4Saj85$ZIbUXFDKL*C(LV@&JTzw1Vv*Mn&<RktOX;bRLYun1U z=_^bZKT+Q>UNd#PZ{1#|!NI|(&jGe!7M7##TgT*jn)U~r*WpLz46}Lp)63*dpR%~W zlMy2S*H&^AAQ?n4{$H})Gx5J>4-2^eui3+||C>F0#1BO0xi1L2qE&M%O(^X4BG3P) zXJz-Kn()#@;kwWU5_MdVT!f+uk<poRsJ<WMvNr7sua&&!Hc=m0bB_OUryiVTYVd7! zi`!Gg;vM@F!06fmB#Lnkv!%PQHVhn5&{Piya~gwQBrF>L@`~_<76`gntG21Fwpwi1 z^b!6$CE1>ap<;8AMB^o>QGK`$%RJw_Vnc+5txQ)tUD=?IO{JehQtzSt%4+4cbE#1u z-tp%2-n>(p@YtZW`{RaMQWm-x50zwK+Um9Zr!jCiSl_C#y>@ijI5*Pt>x!Fn3q1T# zUH;wl)t*<iSomfeYlQ7D`!WyT#luxIc{lmihflJfO;RwlzZa9n?K#X|2-jbfXL^_~ zj!qwL)iHIQ+sR8v{<|<}*>_aKwQz6ZC@sm|ZB#!O8n3CuQ4&FA-z|ACh{v%=6`?4G z<Ia90SGt6)i|ZiL42kKQqLqz<-P9*8Df{#C>&d9UdtRBwSeb(y?4>Xou$KU-^1_QB zR6aRwvRJ2e5o@@X6I#}HiLS?qFE8;8v)YYFke`BNmEa+6-TIZVMT>mtcW0=5OxZYi zc2)Z>6uERoL3B0PdErII8^`vV*KsVv=XzXUb6G~-<z$9<78^xO^$J2V6UQ>Xc4|*s zS^Zkg?r!YTgMoTftg1U}Q(Ry1uRwe5l(M&Tlv5E`p#$PTM5Wr>xZN)C%tn>0?|#=D z9W2m4LRVV&G>y=R?$_&@@aB|pPCk$nDwZqD?+ZSMcILNFp&ixC3?vx`3|{e?0XxC_ zRg|~Ol-!4M8%YQ(ZNJ|lUv>+LEM-?3qthsZY6L6bGk@JRtWbT$OnA|A2P44hnON~w zVTSs`*Un}x$#=ykd=)mzA-e*abGl5_H`TqL;@C$-*5#-)|8E+-F>&%Vhk5nks-8qM z96gHb6~?RXH#1(GIJ_T2<m6nmuTh;#Uta&<4VW<8hXSGANhA7dlggDVt{wi+4CPj{ z?lBA@BxW0YJD%iw`3Xb3Y%W9+=hIHz3%d^@5t0O&+tl*G`?Lm`J6!T?O{i)H8p$SX z5~BUFFWikV{JY4%=0=r)n=PO3jp(5A&s)sEh}E0>)yMlZyt)BwtB7X3h%I8-9j$Qn z^RTvZ>Xz*H5Ymdw^rx_oGSJWpr?$9f9rEfasDDb$obBn9Ht8yL)dIH5SC4~{##3h} zJXd)Vl~}=KnJ|X2=||>v1$<q~275*M4Aa04c4b7kmCFu^!fFz|SgY9lQh`v|Dt3(d z91O_uj@uta+a4~<SM6A#%wkc`Bf_QcQNN`dk=MQRF;EL{Rk6Owz$Xl)f`0kA9zlMQ z#o(&k9Og|(Bc?nus40t`c%e>##eDI{pCFEKu+tH$n1VrHt@Qh_$fu}pR9;B|GP00y z8MIfcsa&gE4uD={H#Q|G#?@eN)QE`Tf0t#Axz9WJFb3H{4xeGJ53D>uv_~=v0cymJ zjhZF+HlG7F3G3$sR`}(L_v1Z`yVd+#dwXiWOP+`u9=qOUtJoL3Mmi|aFbkA28ghjN zCp-upYNoyp$FMnRR1Ut6#Q8TKF*#x2P!<a#)E>P{YkyXjJ#z_JNfYrsN9OC8AR@W1 zCl3%E0nJ+0-~20vds2ROD>w&Zw&p7ep42tjd|n4#x?AVY=bW;6h>Y$+i#1XVa$Bzh z3+|~0!#Khj_V`-cH7-AHTGhBJTish}YLC82u3fUVfax(*bB$J(_lIHosf<zJQXx6_ zW!=v8c5k|Pu{`A|ZL&$R^*T>;J#M`QfxK^my<N`@5qtc_uesAp79{vXu;H9Zjh2Wv zCP&YA#_ZkPLX+6_p<ivDGqjaI-XF|!gF1kLM<*A*l>dE`^v7*?Y@+8WV@polA$hO* zq?R4l=kkm~+A6pqV9E8raA)36e+*I3hzd4IA?wR`B4~M=@=Z?NOJFmuXJRsMGcQ`S zOWynURI?4deHId`u+MO1H1dD<3WetdmMDPy0>2c;L<ssDmV5Hn?^Yj0MgN>go=sx+ zzy$oQ?M^KayJMV%C_@mCpHq(LphfJOrYx%Ff#n@13e7}Sefvh=_M@b};sFfYIeWLG zE53g7OB?wfy9Re+=g|8X7gG~?b0OUAu^2YzH)7WRLMxyYBE{KH6-Q8OL`G<`@D`zj zQ_ONu1PAs{dDaCp2$@6KL@Z7SBc;bWPSs`?{>K93d9-j*5p<OloG4lMu!XfvZW{-< z#2)QsS6G8JE%>++!6c8t=>IlR_%JdQa^-E_DbFLSO-9K@ks_UB6QZgEyNyqCNwH;T zJ>QL*)ZzRy8)o;Qi&c6x78N<`smi|QZ#gsYZLkD^@9>Uo=jj`Da}jv27Z&pG5l%AU z;c@mNTeQ1HO{i3@yIy`>UoIgU5neEAcFbCwn)EVr<eV|pR~6ZG^9DL@`dZ$-T@S0} zphb$C9_FfZ`$Hl6PlnOQB~f<Jb%$zIz5KiZ%nDUbSqoz$r3IE8n|o&OG0ZR{fdV)O zu5?2_a8W>ypsd3v;jBGqcZd<WwHt2i12zK9%qzMsM~X7y&W%jNS3&bx_CiYEZGsp- zP(2kWY==cuX`aJpUa{}f@m7AK)g22alvSWJDnr=RWb2nZB7(Rl*E)ORiO^P6u{86j zr|l=aMkI@x`oDEB5~O}wQD2hG@R%x<4RZTNV=t4yIqOOA(S%dpdFRx&)_Leg?6XDA z-=QD}LlqcABB;0^q!<CY-P&8or*&#L5H6ZA)wvS(Xl$ynMVSBBp@;7YRvI5C$Mq$+ ze7rnGi9zl#49Md!3SX9E?j&b!z_jQeS~<HcBPv;Fs%Yci%dKZry9|6nGtix@)yOZI z#8)~_Ppa%-g6nO;fstfs4%AW#=#Q&loiv_Xp@JlX>3kjb3`sv=MVt2D&P^|7u~foW zw5?HlS4uQ>0)2b9$UZ%Sf&A#4k$o{+h-!K_wO4&)Hssz1q+5Bx&-q9tyKiTUZ4L+8 za?nxtq1*VUOWp%Xe34St%Gl*MYdTV&-)127!0*4nW^3DvSDqI7X#Zi|H?)}qgJ4C* zAl|-b(penE`b?#4f^iePvGxN7C&Po7HK-sU!AGAim1-!2#ke`<csTJ?O!oHrADwBB zromz^h_*al`?tswa{8#eRvV~?owcxH{9BXg!pAWX4uf$QZLs*Q{EP6MLyYidj=42y zuw-Qc$1GMZ9|=Z(PB#Yj43%j++TF7EtCN#B2Bq~Q<C-HH9w_-QVJE0LcEFy!&)~O* zEJUco{KsGs_}c!hy|!I1#*?@gGnmF|z7h?HmB|MSnCB{xH>Rg}1bn>mCR>nA4X5^| z{@vmD*ilJfLwwVyP$t(PQw@6G*==OKLuEyH&cIh6yg{#dP+{0n@sawV16K@NOV8sl zvqFO^;f}#QzzOj@;tZmD=*~+a1QTR<$i6)#s6oIy-kaZHB8JUE7zFhWcZ96hySXu~ zm!iw4UgSUkn&I3360O*WV;T>@dzKv7RNvIZjJ4$&w|HemENBp(iUE|^ls~RO)YoHO z;*j)WrbbaB&)SbLxFzD!Gu*Qz#9L1#hPT%=H+iFD&E1*cUNB;5_oSF;?AX_I3buT~ z1nM;Vh04x)A0V%m057AakaWhO!iM_CLRzxeI_|PG3oVTM3xlV=O;l`RZoiDqL$f=| zpma2zQ|C;*R!vR;DM?|4a~{oeK4dhqZCLm_V9@7;&*?eh9=-fCENy86&tFAJ)H!oH zOV5O<+0dCWeH2gMy?$~wU99f1jQ*4}Qyw7$XB5RbD}$kS!eiLwBs^>5__%ZjgVQxv zS#eb7_CK_s5m?5JyWgv0nIbTt7S~f~`7F^F&jpsSdyr@U1cU~=287bi;F9fn!T@uj z)jElR@K5m($8_nU5~;0G0Q%LR-uC~kDnQ)W{ja)x9lUBNrT~c&vi`o>fOPup-h_fP zjLdd)S1r4HwSoOGvH8zEwisqT%0CqdJ&55)Gt&DF_YjHJ#puFdWbm_l(9<cKjzt@M ze=iF-MmQZY<R_xKz!a#zxql_SbGm9b0^e7v>3dX7wYI&{cclXQXv~<$&9T31GwJxs zzV2`FG4dHr;Gec0(F}c_b6%<_JQ>{+l~9IPNz!$g<_PC=Z8f6U%3RkA*Okti-6xOV zDZU?U$vkLFJ9XXjQajgUt}vd7`Ym`Wa<^zUrn99v&{~arFc*kSWH$GZF5>ua8Dt93 zppnbTrA+!C7lo9Vsg-raP`)|HcVqm4BW^N4_nX^!G)$#ICzQb%wSGtZ3$1J_Lh=-T z?2E99-^Kn6??@whs+^u8FtOlVM%*hvOF!h}%*%0Oe7Da0CPoH5u4%5M<z){N!p?~j z-j@xD%oP`MBi;IUgLg|3v}po3$m)F^mU;Rq3<qw+^++5A@2ScVCE8B+vZ;X^s_-Qv zSd}MY3-`Q25*u;G?m7KeB3gT@h68Xjd#(BX_Uo^cUE|jgY+Ekjy$*-6AXC>Xz3kpc zNl+lM$MCF8_Vzm@uRj^lr@xBjj~fD?<O2Jc4#7(f^n#E+uAlu~WhrZba5F3#1i}Z! zxC`uD!&W064S<jdtR~<HlHP>4eKaazw3Dc;fsqrT|DQqHk-2iXce=vzoo=2mpJ971 zb$S7!yfuTbztjZBXtm#b+L5L~0`#UhBWVAAfdbk`0pEu<orbq>92a3I49V0L;zbvb zTtM}~8qW6%APh<K)n{N=_y11xak{m0ahe4mW1W7NI{d<)wRWz52i?Zu6~w>dUTy!t z|M0ML`rEwxv>U_QN9=y)olaYuHDln@%?<lW(L$y|hU91V5sicD`m35o;l^kxV9WH` zGwWYEQ*n=h=YNx~?7E3*W@7jS=^9Sa+7G1*ba|r-WM^IRLo|!O%lH*Q7f*$yDMRxg zI`?!W2Zs{h6iS+=hMf#AT47?vyY2FpP<AiL-bH^GXT59wT9?zS6S6-8$KPD<t7q$f zNC0bWgF(?+ZiJVb{3Rx#_~z$>q7W87vSHYx#Is2}d<}yb=!UgxmBFb1ejro?hVd!6 zYH{P{E(b6UI|ax(t?!Fhk4onJElc(X5ED%fuCNL8tjOjl5uL;WkT6nzQm#Y0wB+|+ zazWuUSFqXE<&bxiq#oi^R#7_bwn!xJ8?3C8{HO`GIIcWlF#4F)ato{fXQvsiv>!O- z6NqiU>)G}f5^JI-33`d4qJVBD5vseQfx)_&tt-L`!E=&L9189#G|Z8ldVQtkZF<pB zeLPu5%%JP?UNLSBOW7yMVJ3pDL?Gr<e`jlFdnylaQR}_x-b5T_^D}_I_cYDu=O?q^ z7uVt^cQl4jrm@Mz=a4vQi23!E*jS`_!7FbYe+fvQ-B59ApEnQXUKsa!gBijy<F>ic z29!gz-Hz`&gxC-CN+zq?aY^XY$P-HAjb|ELg=cQ(B&{g|zu*6vZS$#b|Dij+-6G<O zkoEXlf7eTr9JKmdrD8g=@1f%W=FZ$b?QT1P`Az8EYtIRZbM73(Vh?Rm`6m6wcF%Mx zQ%4;qUCo@8Px7^g%lz%DUiw24S!KmNPTqI5&7<|Y>``w@%j=`H!&xJn$_@8LAW@RZ zR^c9eFzFtQD)m>7Z1#3om6nGrLmY*{<o$GAERu<w#~YU9Q@<h%O3xiwPz~#nlq1={ zVfQGzg}Hs0#V3gWOqEEosDSL@+N{2kK);Ez1FdMIzf(B__*D(Fe1Kzx*j4NGdkJPZ z=5nzn+NpHC@qJ1$^&of$rF7=jQxl$`I_ebSghQtgn7rwXLk*gSGfH?!g+6ChWFmQ6 z8lkB^k^^j5zqTn5`?~%sO`2``B2Rm@ZPy-e)Z3SdB^P^lye?TI9>>TZrYKlX)!T32 z^d1j*AKJYyp|c)TgCWLUHE%gbR5Am|f_LlRzraEWlII=ajc6Kf#;OlCq7l_LqIE~; z;@s}SEd&bFSozTDKBZs^3_HD&VKe3O@1Iw$NW6jCG-_wub$;48JDF>=;I)&OG4qs5 zDR%j?dU^0XM`y`Ujg_W_;8uEFt>NtL3^{`lX4+%>$19*t8v5aR!=d1;S&DI8mC(S) znpN%b{*ZfWP^7-__JH5=fxUtG=t}7P_I#(IrKM*mi5&`*lr()Q_rGtAo;R5b`gdpM z<+K)$^I|v6H)qY>FzvS_?eIR3xwiAIF}<8##LT3`DSlY-c-jw)7Poidvb`Fc4<wM@ zP~uLevVj7kv6~%6AH`efHNDVJ-W22{7P_Zd)luAl0y0!JUnfK#*!Mo`JD$9{fkwzr z&YIFPdcF)DcfYsta+R$yT;Gq%8*vO5sftG;tM~r|DV-+|>N;h8PZP25RmAG<WPxVV zCeWQ$+n_|fgY5k_enoV#&^oxm+Z6?MjREJchiqHCSY6i)$>5UGUpZ10#V2q1?)iIV zF{5k<?$F$Oi~A;e^?~B%Xov!DXXQbup6gTMC}UdN{IBcs_pvkIcC{V+P^Lmh(9$R7 zlAD^=UEW*FUZY${8&<R)IXe_>;Z1e1rkScQZ0*;!EYwDR*Dgre_k1lzO%B^F`qNQ$ z8Ji)QN&>_G!+9cd4X5+xl$vF}R~S|-kjG!ZcAypczWJr(#TIUHk$AH7?Z<sj*|mtT ztht_dw=;8t)ZaeUwSK%WA?}`gfnF|}*>i|P__~&m!CpqlD}GOa+f?cfVzdN}ls<uu zQAIf9u>;FN-hVLQPf&X+S|cc*DcqT~djEM#LwCIG=3!{?R{ytkZNzegCyF$?JPw&x z@6x?=M_p|Yk#n>N*i~HNk`8Z*0ur<;LQW4+s1e;xtq{EIg+tdJUk|36QPW)cJe6=; z1Gc%ghOU1>sK+NMXXdsl6$6Rv!$b4TIqpFl3N`kFjFvX0s=$jFw6^%|`1K*<7ukoj zwe(_dV3eR|74mWF`a^azki-aezc&j@gN+&!xK_@-d1nJ=@1bntxaDk8s;FWyXT$*Z z<s{Qqox79mnA%287k(dE><3$H!h}Hk9z)lY+`3UQ(m!OM@9$T8XT9D*S7?tPz28`K zl;pz(DIDN@w``;YfiMXxdJ5-sVY#I+xr=v`zYFiSa7L!ddn8WfhZ-a5_s?FEL;38+ zBCpkWE;93d_))_(GIU_W$W}Gzt<@<gJYkh6z!7i;Gjo%tXLok9#z+RSUy*I@<5{gM zxFH2R=j^VGGiz~3G~^zle3~Ll8o`3=Hw=_IWv8V~JMhzL{@Ss~*K`oQ!yz7w**Qz# zSusi(xz=IfpPWsR(`N$uz>9A&d-66q!xyq1A!E$Pj|P__pO0UQJ$<4sF}0O_S_|*f z(=qMnW9sOPw7Q1SAkW5W8lZmLN?QJqjLEuzbcyuCF^U7~Tv%0@ny4ybD*!*7px}D3 zC4U)-Biyy^7npp?km3{l7#{4g_8V!(aOUdrS=WsjLvFn7rhW3zOUBRmUXyJK#SeME zbY$r@^*!6Q6}I$Dmd9e=n{5pbN>dox1LL-H)xxzhZGHOo)VxYoD4WLciyR4I@Vgs4 zUbv>9U*RU(=%0EO0~qA#n%hb46_6pl*}B(%+~9ra_P#y7S&8<F*tu_C9+12npzy9b zU2=vdOl;`SAN<B%%REi#%0Qy*A7W5@@UE||eJ-h)Fw-uO_r)QY(^YgYv)Pk57N%$J zmshWPU*bAaPi*#F$ZZsylXx1-ESd0;#O{avqV?a=bcrA06j!Idc(4#Kf8~02+E_Rm zs-=B{MOcxm!%{6U)BBJ;fW1F@+9Al2zcbR^1v7Z~^^BtJb93GxLNfcuMkSB|wE5Rg z{|bh(PVhYNr5LXPUkZiy&Zdl7h0ff=nAn|bLAEE5kK7Enh_19l{RtnttQ}m3Fa-+F z5bLjWdl6C0MR;y<1}B`E3x5UFrF3GQk{Fviu4#IOsgbFIj6Iw7FP@FsicV7}fO2VR z3~BKDAWdNBo1-W^c?uMreaTiN8|w=_`2sMVlK2K-4MYgPe7XC>+<EN^pU60!sN08I zO&_b01$~2Q4Qsjpq}r~@ycJ<5s!`+p&bo`DKWmtG8`(>Vr5K@~>vCQWjW;zUQIZp3 z=>72ey{G)=q?>{#>hY3YZ*%o==dq4E=qmV}!f`Rr8O7R)vO3PciI+$GdVMC)(sZAK zWJ;!}8MH&rk(v1luK@ns`b9#r9$ekn>MSJxNWB~5<uq&d+zFgEAF@GP?h>vJf0ziQ zE;o%MN1>N||Ag_+8iT^Ym&5Sl1_oAw`)PcVY4ufp6a&rV0M<)fkETuXY{V=qQTE>{ zF~1778cnlOz#ERr9z~wnbD~9$@H*f58<E_HY-pPeNUG~cDmZ)-Fw{lvlv<B%muC>( zh1De9hEayRru+!CCf|OEoyFokDc}`4lvw;uRPzt4_wP~|7Sea5>F$?;b)X=X5uM37 z>(o_s6VVjt0@kU6Hv$Mhw|^KIR1~&<`p7Be-3t+Ki(&n_Ls$LrM!c_SXg|sHDv@Qe zDu*X4?k5$pW};!(6myVh#qx{6-*m}}H=U>1iN>oD;8HOPmf`G;=~B5Qeq#+B^B(8l z{aMluXvN*z+rCt)Rs4;Z*G*v2`jkcgS;Nh184qI4lGZba<Y3t4TeAbzAWt{rZMs-U zk$UK+?E^)_W8G2rw+Q=$P197qE6EP_S=fUw_jX>2%aM5>?wmtzokN|8w8>{lDI}}~ zzzmY4Bp9N38l!3LXLM~hXhgOcP5DFjCbu|GIdkMV+y-5?wH2&5DPvfqz`<s2KcTtt zt^gvFW@XQ?i}0d$55XHXF5?8v<%N*2JNb%98I8;Y&ElQ|mG34+z#18f)>=><@|%89 zOdw7Q8f2(LDEGc1o=0H*b9~~xKBb-(xVN9x+WYt*|A+#-id|C=iz3#*o~D2UE3V^f zNKu6uogsj}NZ%6YTUMuxrZ8G^I*yP3VH$r&NB^g`(wKYSck`l;GrD!*tUrvK2Y=uL zct`|o$lVzGvJ;HWm!a9D8^a5jKl6`wk}W`Dv2n=Ws!OYO1L+g%qxb%U<aL%2T}~$X z&N>f*6YD<ybu-J47I6a$o3Mh8Xo<rg37}O5Gz`XJOn9ZtkY~wXzGbqv+l$1?{Dr7~ z+bKe@`j-?MIb2gPAh4GcW>QQ$|E2F47X7$8c6v&2f2+&Ch1DgDHLA-GJpXg!6>LzC za29YG9oP4<&8#RhtXP{JYnnypk4Sa9FpB!Hft=IXuX+RVyzQ#|qf}K7F(Zb5!`=w2 zy_hS{Ur8Aju!Gul6d-}?A3Luw%MTRw7OB3qJjx-qH)-8K`5*e^6*XdS3)%eCW@6&| zpyD`ZoO}#YnopryE%jrk%u6ut5!q36|JzNwLCK=F8)$t^43ZT=lYyq>%tkW`(1dqp z0(@7{YM`bQKu)+W>}rKq0;d%_fNfrJU2xJ%B|&}{<E~X8-Qb&Jh#B1f);L>m?GCr# z<b&lpjD5QsPxG_oy{x=!zecFQ)Xa$4WB4D+(tsD_Y0nSm*U+wT^E9_W9Fv3*A3zgD z{sAsa#89ZAwAA8Du()3ThANYaJd3da8~XpmV1SA;>fbY6?d2!#Q7dCY<*pg4XG;Mo zyP6P;w2mGIh!a(3c;_W{Qsx%df1esFfNkMXDn$7Nx{#F15M5y6y%7W?@en}ye3{5X zb`5%#WqNAI*Tc#A^mp|5DeA~*hPXI(ilBwq%9+W^rZ<VMk(r!P)!|IISq8zEOJ{e3 zn<XuCbwkchXTLdxKCiB7n6*YqlYCCgy3TQF<Fic~_x2;ussXFtrI8=BV9e<vQv`n` zThd#U(IG95G98A8w%?YtNU@7t>nx3QbBb{JB0xhmq~m9o3Ec|iW>pS))^g@Z;G7R6 zB3WePdh`Oh6ghhtX+zys9mN6~w`Vo6RQL(r0!qBflC3n?FgIB!w;vu<VZrp^|Ifid zmA{e)2b3cPU?C@5OY6PP7cB91T9sx$wjGeD*5X@%@XipMF(9ve8s=pWbnk*RbOk!> zziVkX0sO<uIIc!rsAqGtl3hpGZ3nE}gT<Dv69;5eT~3{-SSoT_KZcE_A(92JNWy<v z!3<Ns!b6s8bs#UQ05Mmkjj^Ym@;&>ZGcDy4y}Qt(@Rzl>S~F$28NjZ*)Fh4(b4Pe~ z?ORRr-WJ;^vq)e-q<VpntNeA=cL{x-yTSuWxRQljH36qQKm^w$ob44z+=<(2s-Xhz ziMKiWo<t)t*vrAiHtuC1?-k_!QWAePbSoB@#;JHH_m~{O#ag$E&#E&H_@<L7>!KFX z*0P`4{V9P@Z#k1G)B)L+v}=T`!C+-?f^K^F=#_xHVH7U|dczuq0-`Ff)XdCjEmyiS z#^$(mVj~DxWQYkC3x*W@D~C<d!-thk1MfXv^gnYmcU2lx(ilP+K)PWCFoZ=(qlg^^ zeTwN*Eo{g!Zi2S{mt2inB-d31QJ7r@(lOy2A*?O{e({r&C&NuSrCYG`6KjASkAxI) zATGHobDZG^tIC$}Y1K=?JgXZhqy;PSXQb#VP<|p!2u2NN_+w>$*kO_cYX*&+k8sJW zuj%OJDiL;ik@Lcef#bfC*;$<|J?mF|d<}!OtSZ0FDkT;mB$?NhR?yN7P?*Ei{o5&+ zwpQJ?s{P2;?YNcUstXa8rNM%8^a@lL6Ld`h6xMh(*7jPTH}As8`2Q_(k1v2HziWOQ z&+F6g$77{OL<k7O8hT0Y<D{U0Cnea>3|baTnsI#dI^9EHprD%uB~gPrD;MLo#eL6G zpyx=wD9x8Q_I*1-2^GoW9M1*vtPQ0mbPi?_mgaID7m68{PHi842p$5Og+Cz`hN*$G zAZSkvADcz-iXO8w4*FFk^K1oXpl~`>U_ot9&ylaFA{5B%g;ZehD^z*~tWN6dL$yrQ z;O-${y#2D1&|i(VLD}&p1qIh5ANv|^d2FrAJ;q~3)cb)nDJjYI_Ur{{?d+`Tlip|j z$GiDzbC3@()_v{QRKYXv7xLQIhz5Nm5+#FrXu)n<v?C5HIgR9z5{^Q$GdrnE$n*OZ z8TvnM7z+650_FBR^-F*Q2#-Hl>|6d%EJ;tR@8Rpc<AtllhHD1r2$njRuR<%$c0HOc z+*A-_|7R2wlRwI+um4JQze#_j#cA3@+TJar$|hAZ1VBnY>mN27{<DrSuhTj@I%g`# zs!Alk2oSy*)ve#KpnBG|5700OPCQLCgGw?7RVuO0H}Q_M_4Kk#=VdUy0S9+>KdP%0 z_a#HQL^S>76*OFb>o&u;JjQf5n3f=)zu0CGuHbB%no(Pzlm)mUrmvieXT$Fm;yVW; z!D$INfDmJAwVYXnKBK;MnoK5jP~>AxJ-oQQ*9cyisBsg+D5_h3c<V6~RpzD%X)B3B zVsGKwe)(rS02S|ucj0r%KTOgp*9iVE7h>?CF$Q=-H~38qEt1;Tt`WR91{M3aB8Bdg zm=s}TG(58vU$L4@UW08Vq0MRWoHPMvUQR)Jk5C|i@(s(hl|lUMM}Tpb!t|~ReUS5` zwFJas8@{b;Ex<Zg)`r6Q`eX<WfrbmwUT|as+A=^O0@^Y*MCRaX&9X)Ar|Hk>OU|Kk z)~K07C`{dsH$FW?37#LHK-yiv(7>yV?@_WW7$1-zq1CX$$@xx<l4j+p{-{XZwoxZ) zwKCS5c%8LZ*Q2O@rv%_E3FlnH4<#Sjp$Suiak1E&7pu<|o~J}%&eEpZ7sdmsEmv<U z^e)c#!e9q4CV;GdY1#Xd?p+C0o)~V_`%e?fIELzA$w&wjoV&l0qrLc?OqCAICkp9m zWNmDg*^O3|5+$$5Ttk-E4QqjP>!gLkGVheL0r5(j2&u~r*{uW*{I2!<ux?*ehu3d9 zk<sW0UxpWIiJ#`HiHPO!N@&CJj{l*bi@0jnE~*H32VL>eN<IiUUO{qjnu;ZIIZMlz zRt&PR=cyDVfVcwElul0Rnpm3ct#T=3H3z*?onDBws_BlJ|Ka_i=~io3l*>iA_$9{y zf%5866msyrFlkQ9C#%IGw7_HF3g;=^@J)h_*{tVQ<6W-l6g$WxF-xOmMgiZ`iiIM! z;Iir8{Qy&~M<-hWKPgx<cp(@g&s+>-cZdpK3-Cf%kgDIn^Vd~cEUmVpS*Mbm@F0EY zf;)2UMiYME8JzmLC;D+@0U)7qJEX&dH7E9xzJb_WDOAd&4kvqWKWnWpybKC-@0g<G zl*F>-shJ6S7#&LG>1ltpCr$#^K7a@>|I+FHenh8kU1=|S{c&kCu<I|~yP>da&as79 z4SK~PNt?zXsR0nxM7Ej%D7!c{19=?=l|}2S^_|#@AkZ&TYj|y6zLl*Mmg6aU5~)SL zxF<U>6qBU*uB(fl>VgVsr&hy=%nLyq&jZ;3%nL^~Sm-WIl4n#%D5GduHU|$##>i6D z%TyG)-57k!qC>_8D0yqM{zU+FuAmtGc2|ZM*O&FJ$IasB*k=f?EOgIosW=5$c>@X+ z>?1IY9Bsa5X%|D;7!tE}Ej1DJ=HZVQK}s}!v{^78?9Ryt33BMzCxpBH(+<(*e=I<b z4<H%G<K@68*2v!gtIH%O3rTrD77huNjw1DKXrZe$g{C-~WmrLv2}*kkZx@iDKt^-W z)z?cx;{8K!^AIg<7>;4g)M1B;7C!Gqh6CB>xbwxiI3g+#%?+`>0W=_K_C_AMfyS3J z!Sw^ugulQJ!0rPieL;tY%wC3b)R^f19>6yc*K=TQ<L~ppF!tvFScg+m!+d1XA<4O| z-g=zq`ag`l|0Cpmowl9J75n3^USsv6M~IMk)+-2cbusdkVS80~w`9<BuwAl(Ce&6o z_;oVES`eBiea#)eKQXyygQ43vM)U(6^%>Xza$&#)?8f+)qyojle}*4WdHt6IH>?84 zgYl}l>UAvSY6fj6WdFbYTP8RQ^8Gl?J8Mtv;KnPgut`DHx+hSCf3ci}NSv-kL&#A~ z(s|m1;PsnUZ>Jkgc(dQSqEoZ}&VLcb5Cpl62ukqKg1bJTIoago{ELX6=%JRQITb*C zG31~9{G6Q+E9^=CwJg}c!a3`>!@NVFybhb^+bFp}Rci@`Kx(bR9sYTE{X>tlUL$w? zWvT}a8=fs%BF&=-JDMr)kM)=K&ZYqQ&*Zz^`Q5{tqegJ$p%v?O{Y;~WT+I{KSspUm zVGxSs*uJ2*Y<p#Hzf>Q1$|^GI#BSGozj(lSTsW(b9vaPZZiwP^YxHuvVcx6~gZRF9 zXJx+5!O5esH0(rp>C5=@5HwhOm|ZVK2e5b?U<?LlYUAlY#dO-l2es?QYXv_5v{oU= z#b+#=7XG@2WF45F7y17^8%RX^|A`HB_tKi7ilIf*E7}MkNEXQZL|TGa<yNPB^2^II znpQJ;r`1GOS~E3CLImqh4X`L99l}IdvxMIG*B8ysOty;$I|R1ELqFu1fVVvJx>^wo zNuG<MjWr-;_WS;?O(vdpBG6xW;0q9Pj}3h^VZY<Fx`BZjlIwRj*ohgik=8Q!s$_Kw zGG`pZf+|VZ{nX<F9KN0r4iAHZXbl~ARRHh}71mJSJ5u8gkRSr=8b;CvMVihrNwoD% ze!Z;#wur@S7B$(4Zi8YUHICiTYXm#3-z<g+*(K7uFzZV|+fOSLK|2!Z&MQMWBQ-8h zXx_^hu@xwfn4=}_cbv~qsRfWfgNQ#=U4^H7SClj{GOGZdA8s|>SWre4fv$}KO7u$z z#%zFeUJ%2re8@-;Fa{j>ppcyP+!9z%A`SLy%%4E{%tPg313c{eN4J1utSQ^su;B;j zZ8v8K>_9UDGY5+t7XcN;&wgx?%3yIr3?;?avvtcne=k_b>u&Y-->RSQ7FTUdSYHbK z|C<Ix)4v^5KLH;6Oa=(+jq9n<!$3;{5kdHGA~`{buyqosvjpFxaPCBil>=K6*73#$ zBePDk<3N85J`U4?DiasvD5lR-1J2PHtt-4mGsIuqTO#tx?ufDqPX&BACd`o@J!3IY z&v?X9{AP)Tai?)J5?q~r?;x8RV};(QN<u2zMA3Q58LRmFtne{B{8Dur6ytfU4eVi{ z<6*Q1V%doH8ERfPVD1@;c2#M4e7FPotlqV*3MqtI=QjvorMVN!d?psyJgV)FBjzlF z^MwLq(y)B{q3oIpV^Cbx0kGcVBQcE~-jPawMEVsVbyD~|obX2F?sc8`_?O&NU#S33 zv?;+uwi}gB$@S5Q4KSJT?@5k1oT$YGj*+f*>bY&di(+Xhkcc_2mz}va-x7XR48U#8 z0Bcd>eml$Sn)1Rjl}?t%bxK>&FLAFu<<)8_tbM30Vcnq});i*^f!g3;Zs{v5=!7CT z17H!MIjVyJJAszZmwVHPvvN-oMEx*-`|bOd>lF_WXsF6Y6xG+2W7jL_i>mf6ykc%g zlw^dqq|U<sWIZfC(?PB;+p|PG;6bjZ8*rJTo^PLlzs;Y{U6>)kzEPn~J6)BpA()<q z=3$FLfA{*3*8|PRZQ)~|x4E<D-{vMP<W~Qf;&}P+Rhxf!*^G|n@0?HJw*c@5^lbH* zLBn8BIvnKr{rlU#*A$)sSq~QlF3YHXl<0_m1%VC4Q{V|r>i}ffux|#K#RkvKR<1ms zAMaNCf+@UY^|bt4eV${sD^Gx-E3=;(K#B7=-nBdlBYVtj{3o;bXRf@rzJRtdw!8v= zTe5N(N{Fs5-_2Ip9^m!T9hby@oBym6O#T>*_WY(3cG`E7@IkNx4Zl=nuu5clSrUn- z10m5?$<f^sKYxiXO2%hYgZO(7Ei!>Vo2Cg7y_6Uf!x?2)fEOW<*0((8>}r;EaZ=Ez zt7G9IAsVWSe3bkr0O`O$qTr$#&r^SiUdNoq=Nyu&vdIC>N6rHFf(Jvg>TX6VoXf?2 z;_^#YPQI#4#wCZ}lNT}7CnrA%0q2R|U3VXLU4QUpiEY9^)dPGu`2gc8595z?DYH@v zD2Xvle1>F`CpI$?X5`>X-KMcaOG`2CCc^!y@}kVs7BP*-5aX2>`F0R3!Z_H0k7h)R z!Vee}|0xw=k%f(Htv)M7?xOY_Of7|ScG3js*bEiM1S0aA*HGK>DBtVG{nSniy1=C6 zDC!24Z*TRVY`DOcbw6|ZP=72dN*qI=<1o^|evE^%`(Uhrj8TQZ8y9HqL{g(oa-NPE z5jAsb@249@wmpMiyiR|st`QtxXaqPAi#7%_-9(lr21bJsK~ETrV(eanMf*0Ds;-Ih zT0F{o!DHs5oYB@_K=YsQRIEVWVDf$&&_J3@-+X>kuhnb{FpdB4qASz6;0SVfWFJ^r zQo4(UKSqsqvCtr3KZtQ-MB0%Z;pBmcPnvrF802N)wcKT=B6`&>N`VGyg~El~h59~V z(|=E8^@k4|p<sn@ou^kL5la($knY>b=zKE(sZ_8XXq70bS)vrWj1Fl4aEb9ss4rFG zvIHxm1n}fe{9l~b$1z63d|&==zUA}5-l2S=28@QjU2MAs)w02b9}zO#tBv$7lHlZC z<Ni;u%<O-(?l#f+qs5$~&L$-P^`#|s7_8JQBnR0@UOxf&jlYSnsKPU666gAlXzkdj zMe|2tjr=dMkqGpi1`GGdY6S{TI(n8PgHde%FWTNRDvsz|`$U4fy9bBh?iL8{?h@SH z3GN;sxC9z^3+@mg0RjYf5AIG+k^Jx6JMXM{XU&KC*7PcBbsc%mInVy>T~w^2yr$Oe z`7qqx40HRb=iGpy`zh+DP#kW*TAyqW3)YWB3(2%PgAvb<V|Qd<pC11W``}hsrnH9a zaEE=}zsI^9{wDgfMRArWCHqsh=SpNB(YC(e2<$7^9gSj8^5Eo6#GnDb9S~P6m{-d< zgjdOmgWI0mfI~P;tX~U%J`o}J^7?>X=5))ZdyA171o|N56|T&CR2JoqE#@9Zf?SOg zP;37`P*k^WY%gHBie#%0rO*%6miMra^e*50T7MUfl$A+af3fLY*=A&5?)Gt1W{(1s zb>gc&ofeILkxo#_x(QqJWg=IsH+I&N#CZyn$2_aCHW!A6aWokMb4{m*l6Ga{s6Vz) zAAhL#`}@smkIu}59Dp~u!Mi*lu8hI4+EO*HCqn?rm<Lfu@1kyXuPiHUp_$Yzk$MnA z{wKW)u&E00K91<$0Gv2}6uMePULAAE@&(~n(#9m{*DZh8h<tz`AoVr44jB~PI7u+{ z2@~$`YoCw_YFGiZJlaVCC8V{IqyFu?<}d5AozuIVt$;_OP<hF_xK6zK0UkJ+@gC2w z>xtfSU>7tygpbD=e}D}h=p8X#Rl-|;o~TrBWZRzUx1P3|cZPS(8J>dWy;VeSV>_zA z|MAE$E)PLp7&(Z4dxQ`EsgDN$hTkGmCZ+6H_z^ux0(J{Ic|wSE5@U@I?+yWuo@sgg zr;X?6e={0zf30fIFyI#fVYMPSMz2iP4gOqPp0>b~=T8VGN7~w+OM?IH{siqB{`y~u zhyQ<I!2doQ09(N`0XvtPdFKcwmAEW)N7>}FNR=Zm*UU{Ql9wTKB)yZ1+p&-Dm*4%z zPv^xiR6eEQj5?%1ymk;NA!TU%XX~KD0WfhQ@y#vOtY(WmgoIB|)`a1!4fRT<<<2{6 zqL2ZJdd#`(Kup(Sr{bhzCi-%=7V5l<=*tU`yU|qdp11UMK2l0=;I{2`lfLBKU(zQ~ z@d&R#plsmrL!%!^m%onoPxTG=W%j`FH>~kh&aJs&y!5GmbQszyd(`>iTh$Y<Bk*T$ z;P%KdOUU)JCH3u320&&R%ri_LU2i76Qwwk6T2_1Z0`}(4Te@Dd630p3Hbit^U#|`P z{ccDvp<WKK=^}-k-V+LDWUv>*y%N+v)Ehogh$YX<U8<JS29G2wTv;Av<CHml!vs=j z9VS9(J|uFYv4WT><*-ezwcu3Jc=4kw{(2l-F0}#^Y0+$oOZKMkB`#IT>obn2;651G zX&RDjhK9I$l|_GWE`YLUqRNTTo;yyy5N>(hL523svN<j8YtbP3<__6IjavhSvVs#G zJNQdS)|Vy96=n5sP|Sdh-cjO0EEjR|*Iqe|Y;{;(AW<3}up-%(;?^IIg=k1M?t1?} zL3S>fuW9ES*yq~e#5(g_SlLW-K?}p^Jx~y;K&EJ}F>bFAf#`-QbKCkRJCH@H0A!IW z(xrI>mF*4mmhrsjjblp#1TfTrI*tA#5x0GrZR#-1(VRAr@3awxLhY1DM>ynNuID=~ z1lUBzf^;y(okoum5a^>&iNJAU7e8~;Sck0uxn_PM6#bHOAgYSo36pNIRYs*l%@nsR z7OVCh*-7<D+p!QOX<VuQrPk^IUN^<oaj$?t&12SLyO-}B>dUsLTF1-6p`H!JD+8Ch zT{szQ9LGH(wj#Y--uKDM)!T(k0(mMOau(QI?v!1Tqc|i30zX7CKGH{nb%Inl{{}A< z^3QoY;t_8seY$k>wSi+k#J)s0BF~tz$GyT8FV^m^HZ+IWdpG9^foB;n?82MxSxRSv zf$z4CS?uu|DIL*Pdx4)t^=K?bss{jrrW~)!|N8+6I4CNs>;waxq`{JqFFh-&hHZUN zNXV)Xcu%>q-kE2>IsBXQ)O#SuJY2jni#6<9JbKwXKOw8%-gLkQ#Y)^kh@dw)cExbB z&$bGh=uN>%1nY)a3h`V0_4pR-Z-z8IrZB&EesIs2c}X;^KuO|$Ma|KIcO@AY@C(Vj zK|dD4C6$6W*z3LtV?<cYZh<>pzXb0itvHUDh3T59Ym?tWBN-jMiP`)1gZcevzVGIX zO2Vm401dVYh2+@Yhg-(mmIT+T*mxv$h8S<%ld|T{N8y5{Qy?Gys4f5fZHrO+q2JQ= zX2#5e&tq%T{IAkS!sb;yYyeTW9Sbti*2iu(z%v<Y3K6zW&kurnl$7E}OLB5Fq*m0p z)f+`Mma*t?xYj__y+L;H`uL5m1sOUVN6h`+9ay(UMl4&e8x&04;5x;uC8&Qly)X=# z*J)QZ^}P8h^=84%q!4+fwEqD^@T0rL(iKMrJ6YD-feu_y`Qr~^x$LR%8@XUn^NEL{ z(}MpUfT-V1-2VO*8F`flyrBtxBk(sPe<bi#h0%~@Konmcc<7E`^==%e-Fi!;X&B*A z)cq0{9gTQ!s4-CGMPgR)YWWWu=?a=j^?e`ahmbkfFcw&nm+#Tc*&9frKuwLu4(FP2 zea6Fs+Wq2sI_YHNDuqzf-nN8E{r=GjX@=!@!Id6)yVtrWG0~SRi(`WY?FU4TbNAdC z`Q_;NKUl;V%LjrqD{>$-z3q$8AoW*%KgN+X?0vQlf!H%dY`T%>fb1`6YGCUBO6o(N z1>b<IGt?0S@|Fj2nEGdcA)Hj;w<>z^)DSky1P28{wlPSuUFb1FMc;%vRv1r5Q_iDY zKhd?+T%zHVU};49+EZmv1e5C@f+mD|kafBh9<}EPbC*)TF%&L)bWPgitfgBxu^r+Y z>GPOCX+-il@K8W08<1-r)X=l8VHVdH%#3EZ&r(Knhj$#f`b++gG}~qTyvH1)VaFFE z)fU^pYv!khz%$SD1*3c9mpl=fvz2raD2S);;GB&uk%!9_7{IcsP53q!VqI-JO?MR2 zyvF@mk~l+kCRXOdny;Hk|M%zw95Av*3HVO^xWxJcKqua?ASOsW`wwgOOeof3f^2Yz zoOy?`$toIMr-gp}Zt^=>aAUhD+vm<|p%h#j<1nXXw8AlIeZ}~W@l68bWHiQ_-Rmup zuIt+Cs|LhMg~o1kN%FiQZdYl5P>t#1Oqb~}{P3k>-bB`pLpMjBNMQWfm|Tb7Jy5;h zTL<MHdu<LJa1+bNZ1gWBSlCbL7=X4<+;Zrwz*{X~X$mXI^<x%yMk>pL?0Ta%fk4XH z5*b^ytEvO6u!DhJLr<%t4XqWTI_@~tHC-t>TdkGjUG*`>4qN6&M9o*I4?DC;=u!7C z)JIQ6_7Cba5F!~zFNhGM#Y=#)NA}Wk=K<0LYKK&x0&@XBf7ZIAf<w|sv96pjR40{1 zegR0hmRY>mX?XTK<aA?u7F;rH3ee0sIcB%eAyeACA-IW|y&eXV?wfo+588&3K%bBy z!gjh1g9{c<a6L!S{k_|@?zI8z?IvC1cI@-*|0CGPY^Zu|E=OF3DpH}4q-&dDayvh5 zj0?GG=xJQ1doL2QnZ6lrtt545R*mp@XTWGD9zm9=t!LqVsi5_sW09$qsW8bc$B;!q z)8I0yhI?zJ&UqEqg>~!kHXecdN9(SQDv(8UeSrwxzHhWCAdJ`_vt^=q>G^Z^#RhAd zYu;`5%UQ@&SlgjolLAwVs-nW$6<VYDw`vl4GjY#n>`7W1_ck7#LPOo+Wvr$hxyKtj zYTi%I>M@@%EgSpIO1H*SF^=(KoRQu-y%!K1F=aZ<!RqlMZ=eM*rr-AwA>AQ0-QcCW zMaK^i9!QIwABeLZ=35CMupi&p=ng4DLO?-lzBQ|K*KCR;cMz{KE4;V^qypeiF<+AE zv~$=lHnE1$h28!K^;d{PL~Db1s(x39gsg4vERm$4=nT7eCRwAi*@HfcroENm*ZbWp z#IhS>*qiE@blNY>^_))?c3&(^V27vzPXzZCPifGS(wVhh8J-<TXJ`*sPIL{iL9ztO zS@@=yvam8Bxy+Z}qMG%9LF%1+c1g)zj(qLxFp9P&h%NSv=c3lap3>6Ct}?{oa4a@~ zFL)v~9pI4J+p|uxXMCeaW(2UdcTGzEGeEyM3U$Q@uKO--(h%P4XeP{<eoiy;5HJx} z|DjO@WcB{UpfSz`MN7YxNUOW@Ha*|Gdinf2wXr!2w7ay+Msh>pd7&?M*7aFkvZa;% z(I<}9frMMlq`KXKRxJ;Bb0)3Bgl&{`1=xxokNtE;YwZ+Q{TrSRU_GSh@HMzhNoy~6 z3#FFM7N+eHK|uAFKWlf2x#bOBx#L4~ueAG4$$#NHe8m8X-TuE}fSPY~GU~Axu8KX1 z3E!YunAy~JjcPMY@9r3#n0kp<v|KURvyIOF(bF;@B_C3}<>*Qj)lO0%hKr8NU`Z`U zS~UN5vhIv0?g?c3&IEGSjSIv++(<900YUiBI^16s+!beZWA%-DqFw67H?_xH?q|&E z2ijZ(olwUD+%C^nP|Z!;h1O2h-48_+y`R=T@5-i7h8-=upYqXrr5W*G=iBhweQOd9 z6J9g;azc2O-pUBzyI&!sTSo}+rmKIIi&vd2MMBe1`faVz5FEGJn%B5V@e=_W{UjR( z2=>(s=#qb>G%v5LL2XN?=0+!)Gvm;?EpqUm)~SosreO4qtvKCX{r1oL*>)Gh%lf&U z>3@ozCBkSE;fkO8(^TY&-1t?sD4;b)Ddh&Z;s!-<9rZ(144HCJ$d}@zefYCmhU84D zhelow{x1aZjhG-T060Hi&4TVWB1Ei+!G}g2L*3vBu)QVnG1{I;4=C{ZplK03+gC=T zA-THdKk#1}lNTR0K>ukb{tx;uE(dsR38GzIcTJ4kN=-PKTe+TS-3C d?hO)HnK8 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 literal 0 HcmV?d00001 diff --git a/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po b/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po index 26ed9899d..c333120a0 100644 --- a/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po +++ b/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po @@ -12,19 +12,19 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" msgid "History Panel in DataLab, the open-source scientific data analysis and visualization platform" -msgstr "Panneau historique de DataLab, la plateforme open-source d'analyse et de visualisation de données scientifiques" +msgstr "Panneau d'historique de DataLab, la plateforme open-source d'analyse et de visualisation de données scientifiques" msgid "DataLab, history, record, replay, session, scientific, data, analysis, visualization, platform" msgstr "DataLab, historique, enregistrement, rejeu, session, scientifique, données, analyse, visualisation, plateforme" msgid "History Panel" -msgstr "Panneau historique" +msgstr "Panneau d'historique" msgid "Overview" msgstr "Vue d'ensemble" msgid "The \"History Panel\" records the sequence of actions performed by the user on signals and images, organized into **sessions**. Each session is a chronological list of either:" -msgstr "Le « Panneau historique » enregistre la séquence des actions effectuées par l'utilisateur sur les signaux et les images, organisée en **sessions**. Chaque session est une liste chronologique constituée soit :" +msgstr "Le « panneau d'historique » enregistre la séquence des actions effectuées par l'utilisateur sur les signaux et les images, organisée en **sessions**. Chaque session est une liste chronologique constituée soit :" msgid "**UI actions** (creating a new signal, removing selected objects, saving the workspace to HDF5, ...), or" msgstr "d'**actions de l'interface** (création d'un nouveau signal, suppression des objets sélectionnés, enregistrement de l'espace de travail au format HDF5, ...), soit" @@ -35,17 +35,32 @@ msgstr "de **calculs** (FFT, moyenne, ajustement gaussien, ...) exécutés via l msgid "A recorded session can be:" msgstr "Une session enregistrée peut être :" -msgid "**Replayed** in validation mode, without adding new signal/image outputs to the workspace;" -msgstr "**rejouée** en mode validation, sans ajouter de nouvelles sorties signal/image à l'espace de travail ;" +msgid "**Replayed** silently or **step by step**, with an opportunity to edit available parameters. New outputs from computation actions are not added to the data panels. Recorded UI actions are invoked through their own methods and may reproduce their side effects, including creating, importing, or duplicating objects, unless an action has a specific replay guard;" +msgstr "**rejouée** silencieusement ou **pas à pas**, avec la possibilité de modifier les paramètres disponibles. Les nouvelles sorties des actions de calcul ne sont pas ajoutées aux panneaux de données. Les actions de l'interface enregistrées sont invoquées par leurs propres méthodes et peuvent reproduire leurs effets, notamment créer, importer ou dupliquer des objets, sauf lorsqu'une action possède une garde de rejeu spécifique ;" -msgid "**Duplicated and applied**, to create an explicit comparison branch with new outputs in the signal/image panels;" -msgstr "**dupliquée et appliquée**, afin de créer une branche de comparaison explicite avec de nouvelles sorties dans les panneaux signal/image ;" +msgid "**Duplicated** as independent processing chains in new history sessions, with the required signal/image objects cloned as part of the operation;" +msgstr "**dupliquée** sous forme de chaînes de traitement indépendantes dans de nouvelles sessions d'historique, les objets signal/image nécessaires étant clonés au cours de l'opération ;" msgid "**Saved to a standalone history file** (``.dlhist``) or **embedded in the workspace** when saving to HDF5, so that the full processing chain travels with the data." msgstr "**sauvegardée dans un fichier d'historique autonome** (``.dlhist``) ou **intégrée à l'espace de travail** lors de l'enregistrement au format HDF5, de sorte que toute la chaîne de traitement accompagne les données." msgid "The History Panel after recording a representative session: create three signals (Voigt, Lorentzian, Lorentzian), remove one of them, create a Gaussian signal, compute the average, add Gaussian noise to the result and run a Gaussian fit." -msgstr "Le Panneau historique après l'enregistrement d'une session représentative : création de trois signaux (Voigt, lorentzien, lorentzien), suppression de l'un d'eux, création d'un signal gaussien, calcul de la moyenne, ajout d'un bruit gaussien au résultat et ajustement par une gaussienne." +msgstr "Le panneau d'historique après l'enregistrement d'une session représentative : création de trois signaux (Voigt, lorentzien, lorentzien), suppression de l'un d'eux, création d'un signal gaussien, calcul de la moyenne, ajout d'un bruit gaussien au résultat et ajustement par une gaussienne." + +msgid "Recording and session lifecycle" +msgstr "Enregistrement et cycle de vie des sessions" + +msgid "Actions are recorded only while **Record mode** is enabled. Turning record mode off preserves existing sessions but does not add new entries." +msgstr "Les actions ne sont enregistrées que lorsque le **Mode d'enregistrement** est activé. Sa désactivation conserve les sessions existantes, mais n'ajoute aucune nouvelle entrée." + +msgid "The Signals and Images panels each have their own active session. New actions are added to the active session of the data panel they concern, so switching between signals and images does not mix their recording contexts." +msgstr "Les panneaux Signaux et Images disposent chacun de leur propre session active. Les nouvelles actions sont ajoutées à la session active du panneau de données concerné ; ainsi, le passage des signaux aux images ne mélange pas leurs contextes d'enregistrement." + +msgid "When a new object is created or a file is loaded into a populated active session, a configurable policy determines whether DataLab asks, starts a new session, or continues the current one. Plugin-created objects use separate policies. A single decision covers several objects only when the plugin uses an explicit plugin multi-load scope; DataLab does not infer such a scope from a sequence of additions." +msgstr "Lorsqu'un nouvel objet est créé ou qu'un fichier est chargé dans une session active non vide, une politique configurable détermine si DataLab demande quoi faire, démarre une nouvelle session ou continue dans la session courante. Des politiques distinctes s'appliquent aux objets créés par des plugins. Une décision unique ne couvre plusieurs objets que lorsque le plugin utilise une portée explicite de chargement multiple ; DataLab ne déduit pas une telle portée d'une suite d'ajouts." + +msgid "These options are available under ``File > Settings > Processing > History sessions``. See :ref:`history-session-settings` for the complete labels and default values." +msgstr "Ces options sont disponibles sous ``Fichier > Paramètres > Traitement > Sessions d'historique``. Voir :ref:`history-session-settings` pour la liste complète des libellés et des valeurs par défaut." msgid "Toolbar" msgstr "Barre d'outils" @@ -54,13 +69,13 @@ msgid "The toolbar at the top of the panel exposes the following actions:" msgstr "La barre d'outils en haut du panneau expose les actions suivantes :" msgid "|record| **Record mode**: toggle the recording of new actions. When off, no new entry is added to the history (existing sessions are preserved)." -msgstr "|record| **Mode enregistrement** : active ou désactive l'enregistrement des nouvelles actions. Lorsqu'il est désactivé, aucune nouvelle entrée n'est ajoutée à l'historique (les sessions existantes sont conservées)." +msgstr "|record| **Mode d'enregistrement** : active ou désactive l'enregistrement des nouvelles actions. Lorsqu'il est désactivé, aucune nouvelle entrée n'est ajoutée à l'historique (les sessions existantes sont conservées)." msgid "record" msgstr "record" -msgid "|new_session| **New session**: start a new history session." -msgstr "|new_session| **Nouvelle session** : démarre une nouvelle session d'historique." +msgid "|new_session| **New session**: start a new active history session for the current data panel." +msgstr "|new_session| **Nouvelle session** : démarre une nouvelle session d'historique active pour le panneau de données actuel." msgid "new_session" msgstr "new_session" @@ -72,7 +87,7 @@ msgid "open_history" msgstr "open_history" msgid "|save_history| **Save history file**: save the current recorded sessions to a standalone ``.dlhist`` file." -msgstr "|save_history| **Enregistrer le fichier d'historique** : enregistre les sessions actuellement enregistrées dans un fichier ``.dlhist`` autonome." +msgstr "|save_history| **Enregistrer un fichier d'historique** : enregistre les sessions actuellement enregistrées dans un fichier ``.dlhist`` autonome." msgid "save_history" msgstr "save_history" @@ -89,38 +104,38 @@ msgstr "|step_next| **Étape suivante** : sélectionne l'action suivante dans la msgid "step_next" msgstr "step_next" -msgid "|replay| **Replay**: validate/replay the selected action (or the whole session if a session row is selected) without changing the current workspace selection beforehand and without adding new outputs to the signal/image panels." -msgstr "|replay| **Rejouer** : valide/rejoue l'action sélectionnée (ou la session entière si une ligne de session est sélectionnée) sans modifier au préalable la sélection courante de l'espace de travail et sans ajouter de nouvelles sorties aux panneaux signal/image." +msgid "|replay| **Replay**: replay through the selected action, or replay the whole session if a session row is selected. The recorded workspace selection is not restored beforehand. New objects returned by computation actions are not added to the data panels. Recorded UI actions may reproduce side effects, including creating, importing, or duplicating objects, unless an action has a specific replay guard." +msgstr "|replay| **Rejouer** : rejoue jusqu'à l'action sélectionnée, ou rejoue la session entière si une ligne de session est sélectionnée. La sélection enregistrée de l'espace de travail n'est pas restaurée au préalable. Les nouveaux objets renvoyés par les actions de calcul ne sont pas ajoutés aux panneaux de données. Les actions de l'interface enregistrées peuvent reproduire des effets, notamment créer, importer ou dupliquer des objets, sauf lorsqu'une action possède une garde de rejeu spécifique." msgid "replay" msgstr "replay" -msgid "|step_by_step| **Step-by-step**: replay the selection one step at a time, opening the parameters dialog at each step so the user can tweak the parameters before re-running." -msgstr "|step_by_step| **Pas à pas** : rejoue la sélection étape par étape, en ouvrant la boîte de dialogue des paramètres à chaque étape afin que l'utilisateur puisse ajuster les paramètres avant de relancer." +msgid "|step_by_step| **Step-by-step**: process the selection one step at a time. Parameters may be reviewed and edited when the action supports it; supported actions and their dependent branches are then updated or recomputed in place." +msgstr "|step_by_step| **Pas à pas** : traite la sélection une étape à la fois. Les paramètres peuvent être examinés et modifiés lorsque l'action le permet ; les actions prises en charge et leurs branches dépendantes sont alors mises à jour ou recalculées sur place." msgid "step_by_step" msgstr "step_by_step" -msgid "|duplicate| **Duplicate**: copy the selected action or session into a new history session. The copied parameters are independent from the original record." -msgstr "|duplicate| **Dupliquer** : copie l'action ou la session sélectionnée dans une nouvelle session d'historique. Les paramètres copiés sont indépendants de l'enregistrement d'origine." +msgid "|duplicate| **Duplicate**: duplicate the processing chain containing each selected action, or the processing chains in each selected session. DataLab clones the required objects and creates independent history sessions." +msgstr "|duplicate| **Dupliquer** : duplique la chaîne de traitement contenant chaque action sélectionnée, ou les chaînes de traitement de chaque session sélectionnée. DataLab clone les objets nécessaires et crée des sessions d'historique indépendantes." msgid "duplicate" msgstr "duplicate" msgid "|remove_incompatible| **Remove incompatible**: remove all actions whose workspace state is no longer compatible with the current workspace. A confirmation dialog shows how many actions will be removed." -msgstr "|remove_incompatible| **Supprimer les incompatibles** : supprime toutes les actions dont l'état de l'espace de travail n'est plus compatible avec l'espace de travail actuel. Une boîte de dialogue de confirmation indique combien d'actions seront supprimées." +msgstr "|remove_incompatible| **Supprimer les actions incompatibles** : supprime toutes les actions dont l'état de l'espace de travail n'est plus compatible avec l'espace de travail actuel. Une boîte de dialogue de confirmation indique combien d'actions seront supprimées." msgid "remove_incompatible" msgstr "remove_incompatible" -msgid "|delete| **Delete**: remove the selected actions or sessions from the history." -msgstr "|delete| **Supprimer** : retire de l'historique les actions ou sessions sélectionnées." +msgid "|delete| **Delete**: remove the selected actions or sessions from the history. Removing an intermediate action splices it out and preserves its downstream steps as an independent chain." +msgstr "|delete| **Supprimer** : retire de l'historique les actions ou sessions sélectionnées. La suppression d'une action intermédiaire la retire de la chaîne et conserve ses étapes en aval sous forme de chaîne indépendante." msgid "delete" msgstr "delete" -msgid "Double-clicking on an action row in the tree is equivalent to **Replay**." -msgstr "Un double-clic sur la ligne d'une action dans l'arborescence équivaut à **Rejouer**." +msgid "Double-clicking a tree item triggers **Replay** for the current selection, using the action/session semantics described for **Replay** above. The recorded workspace selection is not restored before replay." +msgstr "Un double-clic sur un élément de l'arborescence déclenche **Rejouer** pour la sélection courante, selon la sémantique action/session décrite ci-dessus pour **Rejouer**. La sélection enregistrée de l'espace de travail n'est pas restaurée avant le rejeu." msgid "Tree view" msgstr "Arborescence" @@ -128,14 +143,20 @@ msgstr "Arborescence" msgid "The tree view organizes recorded actions into expandable sessions:" msgstr "L'arborescence organise les actions enregistrées dans des sessions dépliables :" -msgid "Each top-level row is a **session**, automatically created when recording is enabled and a new application context is started." -msgstr "Chaque ligne de premier niveau est une **session**, créée automatiquement lorsque l'enregistrement est activé et qu'un nouveau contexte d'application est démarré." +msgid "Each top-level row is a **session** associated with the Signals or Images panel. Sessions may be started when recording is enabled, with **New session**, or according to the configured session policy." +msgstr "Chaque ligne de premier niveau est une **session** associée au panneau Signaux ou Images. Les sessions peuvent être démarrées lorsque l'enregistrement est activé, avec **Nouvelle session**, ou selon la politique de session configurée." + +msgid "Each child row is an **action**, with its title, date/time and a description summarising its parameters or resolved call when available. A UI action whose call cannot be resolved may have an empty description." +msgstr "Chaque ligne enfant est une **action**, accompagnée de son titre, de sa date et de son heure, ainsi que d'une description résumant ses paramètres ou l'appel résolu lorsqu'ils sont disponibles. Une action de l'interface dont l'appel ne peut pas être résolu peut avoir une description vide." + +msgid "The selection of one or several rows determines which entries are targeted by the toolbar and context-menu commands. The context menu exposes the same commands as the toolbar." +msgstr "La sélection d'une ou de plusieurs lignes détermine les entrées ciblées par les commandes de la barre d'outils et du menu contextuel. Le menu contextuel propose les mêmes commandes que la barre d'outils." -msgid "Each child row is an **action**, with its title, date/time and a description summarising the parameters (for computations) or the call (for UI actions)." -msgstr "Chaque ligne enfant est une **action**, accompagnée de son titre, de sa date et de son heure, ainsi que d'une description résumant les paramètres (pour les calculs) ou l'appel (pour les actions de l'interface)." +msgid "When an action row is selected, its result object is selected in the corresponding data panel when available; otherwise, its existing input objects are selected. DataLab then switches to that data panel." +msgstr "Lorsqu'une ligne d'action est sélectionnée, son objet résultat est sélectionné dans le panneau de données correspondant s'il est disponible ; sinon, ses objets d'entrée existants sont sélectionnés. DataLab bascule ensuite vers ce panneau de données." -msgid "The selection of one or several rows drives which actions are targeted by the toolbar buttons." -msgstr "La sélection d'une ou de plusieurs lignes détermine les actions ciblées par les boutons de la barre d'outils." +msgid "While Record mode is enabled, selecting a session row makes that session active for its data panel." +msgstr "Lorsque le mode d'enregistrement est activé, sélectionner une ligne de session rend cette session active pour son panneau de données." msgid "Actions that are not compatible with the current workspace state (for example because a referenced object identifier no longer exists, or because its data shape changed) are shown with a disabled foreground and an explanatory tooltip. They cannot be replayed until the workspace matches the recorded state again." msgstr "Les actions qui ne sont pas compatibles avec l'état courant de l'espace de travail (par exemple parce qu'un identifiant d'objet référencé n'existe plus, ou parce que la forme de ses données a changé) sont affichées avec un texte désactivé et une infobulle explicative. Elles ne peuvent pas être rejouées tant que l'espace de travail ne correspond pas de nouveau à l'état enregistré." @@ -152,26 +173,8 @@ msgstr "**Tableau de gauche** : liste les signaux qui étaient sélectionnés, a msgid "**Right table**: lists the images that were selected, with their dimensions." msgstr "**Tableau de droite** : liste les images qui étaient sélectionnées, avec leurs dimensions." -msgid "This information helps the user understand the context in which each action was originally executed and diagnose compatibility issues when replaying sessions on a different workspace." -msgstr "Ces informations aident l'utilisateur à comprendre le contexte dans lequel chaque action a été exécutée à l'origine et à diagnostiquer les problèmes de compatibilité lors du rejeu de sessions sur un espace de travail différent." - -msgid "Session replay across workspaces" -msgstr "Rejeu d'une session entre espaces de travail" - -msgid "A full session can be replayed on a workspace that no longer contains the objects originally referenced by the recorded actions -- typically after loading a saved session into a fresh workspace. In that case, the panel **remaps the recorded object identifiers** to the newly-created ones on the fly:" -msgstr "Une session complète peut être rejouée sur un espace de travail qui ne contient plus les objets référencés à l'origine par les actions enregistrées -- typiquement après le chargement d'une session sauvegardée dans un espace de travail vierge. Dans ce cas, le panneau **réassocie à la volée les identifiants d'objets enregistrés** aux nouveaux identifiants créés :" - -msgid "UI actions creating new objects (e.g. *New signal*) enqueue the freshly created identifiers;" -msgstr "les actions de l'interface qui créent de nouveaux objets (par exemple *Nouveau signal*) empilent les identifiants fraîchement créés ;" - -msgid "subsequent computations claim the identifiers they need from that queue, in the same order as the original recording;" -msgstr "les calculs ultérieurs récupèrent dans cette file les identifiants dont ils ont besoin, dans l'ordre de l'enregistrement initial ;" - -msgid "UI actions removing objects keep the queue in sync with the live workspace contents, so chained creation/removal sequences replay correctly." -msgstr "les actions de l'interface qui suppriment des objets maintiennent la file synchronisée avec le contenu réel de l'espace de travail, de sorte que les séquences enchaînées de création et de suppression se rejouent correctement." - -msgid "This makes it possible, for instance, to record a full processing chain on one dataset, save it, then re-apply the exact same chain on a different but structurally identical input." -msgstr "Cela permet par exemple d'enregistrer une chaîne de traitement complète sur un jeu de données, de la sauvegarder, puis de la ré-appliquer telle quelle à une entrée différente mais structurellement identique." +msgid "This information helps the user understand the context in which each action was originally executed and diagnose compatibility issues when replaying the current selection." +msgstr "Ces informations aident l'utilisateur à comprendre le contexte dans lequel chaque action a été exécutée à l'origine et à diagnostiquer les problèmes de compatibilité lors du rejeu de la sélection actuelle." msgid "Persistence" msgstr "Persistance" @@ -180,16 +183,16 @@ msgid "The history can be persisted in two complementary ways:" msgstr "L'historique peut être persisté de deux manières complémentaires :" msgid "**Embedded in the workspace**: when the workspace is saved to HDF5 (``File > Save to HDF5 file``), the History Panel content is automatically saved alongside the signals and images. Reloading the workspace restores the recorded sessions." -msgstr "**Intégré à l'espace de travail** : lorsque l'espace de travail est enregistré au format HDF5 (``Fichier > Enregistrer dans un fichier HDF5``), le contenu du Panneau historique est automatiquement sauvegardé aux côtés des signaux et des images. Le rechargement de l'espace de travail restaure les sessions enregistrées." +msgstr "**Intégré à l'espace de travail** : lorsque l'espace de travail est enregistré au format HDF5 (``Fichier > Enregistrer dans un fichier HDF5``), le contenu du panneau d'historique est automatiquement sauvegardé aux côtés des signaux et des images. Le rechargement de l'espace de travail restaure les sessions enregistrées." -msgid "**Standalone history file** (``.dlhist``): the file embeds both the recorded sessions **and** all signal/image objects referenced by those sessions. This makes the file fully self-contained:" -msgstr "**Fichier d'historique autonome** (``.dlhist``) : le fichier embarque à la fois les sessions enregistrées **et** tous les objets signal/image référencés par ces sessions. Cela rend le fichier entièrement autonome :" +msgid "**Standalone history file** (``.dlhist``): the file embeds both the recorded sessions **and** all objects currently present in both the Signals and Images panels, whether or not an action references them. This makes the file fully self-contained:" +msgstr "**Fichier d'historique autonome** (``.dlhist``) : le fichier embarque à la fois les sessions enregistrées **et** tous les objets actuellement présents dans les panneaux Signaux et Images, qu'une action y fasse référence ou non. Le fichier est ainsi entièrement autonome :" -msgid "Opening a ``.dlhist`` into an **empty workspace** loads sessions and objects directly, restoring the workspace to its recorded state." -msgstr "Ouvrir un fichier ``.dlhist`` dans un **espace de travail vide** charge les sessions et les objets directement, restaurant l'espace de travail dans son état enregistré." +msgid "Opening a ``.dlhist`` into a **pristine workspace** (with no data objects and no existing history sessions) restores the saved objects and sessions directly." +msgstr "L'ouverture d'un fichier ``.dlhist`` dans un **espace de travail vierge** (sans objet de données ni session d'historique existante) restaure directement les objets et les sessions enregistrés." -msgid "Opening a ``.dlhist`` into a **non-empty workspace** creates new signal/image groups for the imported objects (with remapped identifiers to avoid collisions) and appends new history sessions that reference those fresh identifiers." -msgstr "Ouvrir un fichier ``.dlhist`` dans un **espace de travail non vide** crée de nouveaux groupes signal/image pour les objets importés (avec des identifiants remappés pour éviter les collisions) et ajoute de nouvelles sessions d'historique référençant ces nouveaux identifiants." +msgid "If the workspace is **already in use** (it contains any data object or history session), DataLab imports the objects into new signal/image groups, remaps their identifiers to avoid collisions, and appends imported history sessions that reference those fresh identifiers." +msgstr "Si l'espace de travail est **déjà utilisé** (il contient un objet de données ou une session d'historique), DataLab importe les objets dans de nouveaux groupes signal/image, réaffecte leurs identifiants afin d'éviter les collisions et ajoute les sessions d'historique importées qui référencent ces nouveaux identifiants." msgid "Replaying a session that depends on external files (e.g. opening a dataset from disk) will only succeed if those files are still available at the same locations as when the session was recorded." msgstr "Le rejeu d'une session qui dépend de fichiers externes (par exemple l'ouverture d'un jeu de données depuis le disque) ne réussira que si ces fichiers sont toujours disponibles aux mêmes emplacements qu'au moment de l'enregistrement de la session." @@ -198,7 +201,7 @@ msgid "Chain reconnection on deletion" msgstr "Reconnexion de la chaîne lors d'une suppression" msgid "When a result object is deleted from the **signal or image panel** (not from the History Panel tree), and that object was produced by a recorded processing step, the History Panel automatically reconnects the processing chain:" -msgstr "Lorsqu'un objet résultat est supprimé depuis le **panneau signal ou image** (et non depuis l'arborescence du panneau historique), et que cet objet a été produit par une étape de traitement enregistrée, le Panneau historique reconnecte automatiquement la chaîne de traitement :" +msgstr "Lorsqu'un objet résultat est supprimé depuis le **panneau signal ou image** (et non depuis l'arborescence du panneau d'historique), et que cet objet a été produit par une étape de traitement enregistrée, le panneau d'historique reconnecte automatiquement la chaîne de traitement :" msgid "All downstream steps that consumed the deleted object are rewired to use the source of the deleted step as their new input." msgstr "Toutes les étapes aval qui consommaient l'objet supprimé sont recâblées pour utiliser la source de l'étape supprimée comme nouvelle entrée." @@ -212,8 +215,11 @@ msgstr "Si aucune source valide ne peut être déterminée (par exemple la sourc msgid "This behaviour mirrors removing a link from a chain: the adjacent links reconnect to preserve the processing flow." msgstr "Ce comportement reproduit la suppression d'un maillon d'une chaîne : les maillons adjacents se reconnectent pour préserver le flux de traitement." -msgid "Reconnection is only triggered by deletions initiated from the signal/image panels. Deleting an action directly from the History Panel tree removes it and all subsequent actions in that session." -msgstr "La reconnexion n'est déclenchée que par les suppressions initiées depuis les panneaux signal/image. Supprimer une action directement depuis l'arborescence du Panneau historique la retire ainsi que toutes les actions suivantes de cette session." +msgid "Reconnection is only triggered by deletions initiated from the signal/image panels. Deleting an action directly from the History Panel" +msgstr "La reconnexion n'est déclenchée que par les suppressions initiées depuis les panneaux signal/image. La suppression d'une action directement depuis l'arborescence du panneau d'historique" + +msgid "tree behaves differently: the selected action is spliced out instead of truncating the session. If downstream steps depend on it, DataLab preserves them as an independent chain by cloning the required intermediate object and reconnecting those steps to the clone. Deleting a session removes that complete session." +msgstr "se comporte différemment : l'action sélectionnée est retirée de la chaîne au lieu de tronquer la session. Si des étapes en aval en dépendent, DataLab les conserve sous forme de chaîne indépendante en clonant l'objet intermédiaire requis et en reconnectant ces étapes au clone. La suppression d'une session supprime cette session dans son intégralité." msgid "Auto-recompute" msgstr "Recalcul automatique" @@ -241,3 +247,39 @@ msgstr "Lorsqu'un objet résultat est sélectionné dans le panneau signal/image #~ msgid "generate_macro" #~ msgstr "generate_macro" + +#~ msgid "**Duplicated and applied**, to create an explicit comparison branch with new outputs in the signal/image panels;" +#~ msgstr "**dupliquée et appliquée**, afin de créer une branche de comparaison explicite avec de nouvelles sorties dans les panneaux signal/image ;" + +#~ msgid "|step_by_step| **Step-by-step**: replay the selection one step at a time, opening the parameters dialog at each step so the user can tweak the parameters before re-running." +#~ msgstr "|step_by_step| **Pas à pas** : rejoue la sélection étape par étape, en ouvrant la boîte de dialogue des paramètres à chaque étape afin que l'utilisateur puisse ajuster les paramètres avant de relancer." + +#~ msgid "|duplicate| **Duplicate**: copy the selected action or session into a new history session. The copied parameters are independent from the original record." +#~ msgstr "|duplicate| **Dupliquer** : copie l'action ou la session sélectionnée dans une nouvelle session d'historique. Les paramètres copiés sont indépendants de l'enregistrement d'origine." + +#~ msgid "|delete| **Delete**: remove the selected actions or sessions from the history." +#~ msgstr "|delete| **Supprimer** : retire de l'historique les actions ou sessions sélectionnées." + +#~ msgid "Each top-level row is a **session**, automatically created when recording is enabled and a new application context is started." +#~ msgstr "Chaque ligne de premier niveau est une **session**, créée automatiquement lorsque l'enregistrement est activé et qu'un nouveau contexte d'application est démarré." + +#~ msgid "Session replay across workspaces" +#~ msgstr "Rejeu d'une session entre espaces de travail" + +#~ msgid "A full session can be replayed on a workspace that no longer contains the objects originally referenced by the recorded actions -- typically after loading a saved session into a fresh workspace. In that case, the panel **remaps the recorded object identifiers** to the newly-created ones on the fly:" +#~ msgstr "Une session complète peut être rejouée sur un espace de travail qui ne contient plus les objets référencés à l'origine par les actions enregistrées -- typiquement après le chargement d'une session sauvegardée dans un espace de travail vierge. Dans ce cas, le panneau **réassocie à la volée les identifiants d'objets enregistrés** aux nouveaux identifiants créés :" + +#~ msgid "UI actions creating new objects (e.g. *New signal*) enqueue the freshly created identifiers;" +#~ msgstr "les actions de l'interface qui créent de nouveaux objets (par exemple *Nouveau signal*) empilent les identifiants fraîchement créés ;" + +#~ msgid "subsequent computations claim the identifiers they need from that queue, in the same order as the original recording;" +#~ msgstr "les calculs ultérieurs récupèrent dans cette file les identifiants dont ils ont besoin, dans l'ordre de l'enregistrement initial ;" + +#~ msgid "UI actions removing objects keep the queue in sync with the live workspace contents, so chained creation/removal sequences replay correctly." +#~ msgstr "les actions de l'interface qui suppriment des objets maintiennent la file synchronisée avec le contenu réel de l'espace de travail, de sorte que les séquences enchaînées de création et de suppression se rejouent correctement." + +#~ msgid "This makes it possible, for instance, to record a full processing chain on one dataset, save it, then re-apply the exact same chain on a different but structurally identical input." +#~ msgstr "Cela permet par exemple d'enregistrer une chaîne de traitement complète sur un jeu de données, de la sauvegarder, puis de la ré-appliquer telle quelle à une entrée différente mais structurellement identique." + +#~ msgid "Opening a ``.dlhist`` into an **empty workspace** loads sessions and objects directly, restoring the workspace to its recorded state." +#~ msgstr "Ouvrir un fichier ``.dlhist`` dans un **espace de travail vide** charge les sessions et les objets directement, restaurant l'espace de travail dans son état enregistré." diff --git a/doc/locale/fr/LC_MESSAGES/features/common/overview.po b/doc/locale/fr/LC_MESSAGES/features/common/overview.po index 186725009..d6b258181 100644 --- a/doc/locale/fr/LC_MESSAGES/features/common/overview.po +++ b/doc/locale/fr/LC_MESSAGES/features/common/overview.po @@ -25,8 +25,8 @@ msgstr "Concepts de base" msgid "Working with DataLab is very easy. The user interface is intuitive and self-explanatory. The main window is divided into two main areas:" msgstr "Travailler avec DataLab est très simple. L'interface est intuitive et appréhendable facilement. La fenêtre principale est divisée en deux zones principales :" -msgid "The left area shows the list of data sets which are currently loaded in DataLab, distibuted over two tabs: **Signals** and **Images**. The user can switch between the two tabs by clicking on the corresponding tab: this switches the main window to the corresponding panel, as well as the menu and toolbar contents. Below the list of data sets, a **Properties** view shows information about the currently selected data set." -msgstr "La zone de gauche affiche la liste des jeux de données actuellement chargés dans DataLab, répartis sur deux onglets : **Signaux** et **Images**. L'utilisateur peut basculer entre les deux onglets en cliquant sur l'onglet correspondant : cela bascule la fenêtre principale vers le panneau correspondant, ainsi que le contenu du menu et de la barre d'outils. Sous la liste des jeux de données, une vue **Propriétés** affiche des informations sur le jeu de données actuellement sélectionné." +msgid "The left area contains the **Signals** and **Images** data tabs, which list the data sets currently loaded in each panel. Clicking a tab switches the main window to the corresponding panel, as well as the menu and toolbar contents. Below the list of data sets, a **Properties** view shows information about the currently selected data set." +msgstr "La zone de gauche contient les onglets de données **Signaux** et **Images**, qui répertorient les jeux de données actuellement chargés dans chaque panneau. Cliquer sur un onglet fait basculer la fenêtre principale vers le panneau correspondant, ainsi que le contenu du menu et de la barre d'outils. Sous la liste des jeux de données, une vue **Propriétés** affiche des informations sur le jeu de données actuellement sélectionné." msgid "The right area shows the visualization of the currently selected data set. The visualization is updated automatically when the user selects a new data set in the list of data sets." msgstr "La zone de droite affiche la visualisation du jeu de données actuellement sélectionné. La visualisation est mise à jour automatiquement lorsque l'utilisateur sélectionne un nouveau jeu de données dans la liste des jeux de données." @@ -34,6 +34,12 @@ msgstr "La zone de droite affiche la visualisation du jeu de données actuelleme msgid "DataLab main window, at startup." msgstr "Fenêtre principale de DataLab, au démarrage." +msgid "History Panel" +msgstr "Panneau d'historique" + +msgid "The :ref:`historypanel` is an additional dockable panel that records signal and image actions into separate active sessions for each data panel. It supports replay, step-by-step replay, duplication, and compatibility diagnostics. Sessions may be saved in standalone ``.dlhist`` files or with the workspace in HDF5 format." +msgstr "Le :ref:`historypanel` est un panneau ancrable supplémentaire qui enregistre les actions sur les signaux et les images dans des sessions actives distinctes pour chaque panneau de données. Il permet de rejouer les actions, de les rejouer pas à pas, de les dupliquer et de diagnostiquer les incompatibilités. Les sessions peuvent être enregistrées dans des fichiers autonomes ``.dlhist`` ou avec l'espace de travail au format HDF5." + msgid "Internal data model and workspace" msgstr "Modèle de données interne et espace de travail" @@ -61,7 +67,7 @@ msgstr "**Enregistrer dans un fichier HDF5** : enregistrer l'espace de travail a msgid "**Browse HDF5 file**: open the :ref:`h5browser` to explore the content of an HDF5 file and import data sets into the workspace." msgstr "**Parcourir un fichier HDF5** : ouvrir le :ref:`h5browser` pour explorer le contenu d'un fichier HDF5 et importer des jeux de données dans l'espace de travail." -msgid "Data sets may also be saved or loaded individually, using data formats such as `.txt` or `.npy` for 1D signals (see :ref:`open_signal` for the list of supported formats), , or `.tiff` or `.dcm` for 2D images (see :ref:`open_image` for the list of supported formats)." +msgid "Data sets may also be saved or loaded individually, using data formats such as `.txt` or `.npy` for 1D signals (see :ref:`open_signal` for the list of supported formats), or `.tiff` or `.dcm` for 2D images (see :ref:`open_image` for the list of supported formats)." msgstr "Les jeux de données peuvent également être enregistrés ou chargés individuellement, en utilisant des formats de données tels que `.txt` ou `.npy` pour les signaux 1D (voir :ref:`open_signal` pour la liste des formats pris en charge), ou `.tiff` ou `.dcm` pour les images 2D (voir :ref:`open_image` pour la liste des formats pris en charge)." msgid "Interactive object creation and processing" diff --git a/doc/locale/fr/LC_MESSAGES/features/common/settings.po b/doc/locale/fr/LC_MESSAGES/features/common/settings.po index faa90f9a8..a3aebe305 100644 --- a/doc/locale/fr/LC_MESSAGES/features/common/settings.po +++ b/doc/locale/fr/LC_MESSAGES/features/common/settings.po @@ -20,8 +20,8 @@ msgstr "DataLab, préférences, scientifique, données, analyse, visualisation, msgid "Settings" msgstr "Préférences" -msgid "DataLab provides a comprehensive settings dialog to customize the application behavior, visualization defaults, and I/O operations. The settings are organized into five tabs: General, Processing, Visualization, I/O, and Console." -msgstr "DataLab propose une boîte de dialogue de préférences complète pour personnaliser le comportement de l'application, les paramètres de visualisation par défaut et les opérations d'entrée/sortie. Les préférences sont organisées en cinq onglets : Général, Traitement, Visualisation, Entrée/sortie et Console." +msgid "DataLab provides a comprehensive settings dialog to customize the application behavior, visualization defaults, and I/O operations. The settings are organized into six tabs: General, Processing, Visualization, I/O, AI Assistant, and Console." +msgstr "DataLab propose une boîte de dialogue de préférences complète pour personnaliser le comportement de l'application, les paramètres de visualisation par défaut et les opérations d'entrée/sortie. Les préférences sont organisées en six onglets : Général, Traitement, Visualisation, Entrée/sortie, Assistant IA et Console." msgid "General" msgstr "Général" @@ -93,10 +93,10 @@ msgid "Choose the operation mode for computations taking N inputs:" msgstr "Choisir le mode d'opération pour les calculs prenant N entrées :" msgid "**Single**: single operand mode" -msgstr "**Single** : mode opérande unique" +msgstr "**Single** : mode d'opération avec un seul opérande" msgid "**Pairwise**: pairwise operation mode" -msgstr "**Pairwise** : mode opération par paire" +msgstr "**Pairwise** : mode d'opération par paire" msgid "These operation modes determine how DataLab handles computations involving multiple objects. They apply to two types of operations:" msgstr "Ces modes d'opération déterminent comment DataLab gère les calculs impliquant plusieurs objets. Ils s'appliquent à deux types d'opérations :" @@ -108,7 +108,7 @@ msgid "**N+1→N operations**: Apply an operation between N (≥1) objects and 1 msgstr "**Opérations N+1→N** : Appliquer une opération entre N (≥1) objets et 1 opérande pour produire N sorties (par exemple différence, division)" msgid "**Single operand mode** (default): Operations are applied independently within each group." -msgstr "**Mode opérande unique** (par défaut) : Les opérations sont appliquées indépendamment dans chaque groupe." +msgstr "**Mode d'opération avec un seul opérande** (par défaut) : Les opérations sont appliquées indépendamment dans chaque groupe." #, python-brace-format msgid "For **N→1 operations**: All objects in each group are combined into one result per group. Example with groups G1={A, B} and G2={C, D}, sum operation:" @@ -128,7 +128,7 @@ msgid "In G2: C-R, D-R" msgstr "Dans G2 : C-R, D-R" msgid "**Pairwise operation mode**: Objects from different groups are combined at matching positions (all groups must have the same number of objects)." -msgstr "**Mode opération par paire** : Les objets de différents groupes sont combinés aux positions correspondantes (tous les groupes doivent avoir le même nombre d'objets)." +msgstr "**Mode d'opération par paire** : Les objets de différents groupes sont combinés aux positions correspondantes (tous les groupes doivent avoir le même nombre d'objets)." #, python-brace-format msgid "For **N→1 operations**: Objects at the same position in each group are combined. Example with groups G1={A, B} and G2={C, D}, sum operation:" @@ -189,6 +189,63 @@ msgstr "**Demander** : afficher une boîte de dialogue de confirmation (par déf msgid "**Interpolate**: automatically interpolate signals" msgstr "**Interpoler** : interpoler automatiquement les signaux" +msgid "History sessions" +msgstr "Sessions d'historique" + +msgid "These settings control how new inputs are assigned to history sessions. They are evaluated only when **Record mode** is enabled and the target Signals or Images panel has a populated active session. No policy decision is needed when the active session is empty. The two data panels keep separate active sessions; see :ref:`historypanel` for the complete workflow." +msgstr "Ces paramètres déterminent comment les nouvelles entrées sont affectées aux sessions d'historique. Ils ne sont évalués que lorsque le **Mode d'enregistrement** est activé et que le panneau Signaux ou Images cible possède une session active non vide. Aucune décision de politique n'est nécessaire lorsque la session active est vide. Les deux panneaux de données conservent des sessions actives distinctes ; voir :ref:`historypanel` pour le flux de travail complet." + +msgid "**New object or file**" +msgstr "**Nouvel objet ou fichier**" + +msgid "Choose what happens when a new object is created or a file is loaded:" +msgstr "Choisir ce qui se produit lorsqu'un nouvel objet est créé ou qu'un fichier est chargé :" + +msgid "**Ask** (default): ask whether to start a new session" +msgstr "**Demander** (par défaut) : demander s'il faut démarrer une nouvelle session" + +msgid "**Always start a new session**: start a session before recording the input" +msgstr "**Toujours démarrer une nouvelle session** : démarrer une session avant d'enregistrer l'entrée" + +msgid "**Continue in the current session**: append the input to the active session" +msgstr "**Continuer dans la session courante** : ajouter l'entrée à la session active" + +msgid "**Plugin-created object**" +msgstr "**Objet créé par un plugin**" + +msgid "Choose what happens when a plugin adds one object:" +msgstr "Choisir ce qui se produit lorsqu'un plugin ajoute un objet :" + +msgid "**Ask**: ask whether to start a new session" +msgstr "**Demander** : demander s'il faut démarrer une nouvelle session" + +msgid "**Always start a new session**: start a session before recording the object" +msgstr "**Toujours démarrer une nouvelle session** : démarrer une session avant d'enregistrer l'objet" + +msgid "**Continue in the current session** (default): append the object without a modal prompt, so plugin execution is not blocked" +msgstr "**Continuer dans la session courante** (par défaut) : ajouter l'objet sans afficher de boîte de dialogue modale, afin de ne pas bloquer l'exécution du plugin" + +msgid "**Plugin multi-load**" +msgstr "**Chargement multiple par un plugin**" + +msgid "Choose what happens when a plugin explicitly groups several object additions in one multi-load scope:" +msgstr "Choisir ce qui se produit lorsqu'un plugin regroupe explicitement plusieurs ajouts d'objets dans une même portée de chargement multiple :" + +msgid "**Ask once**: ask once whether the whole batch should start a new session" +msgstr "**Demander une seule fois** : demander une seule fois si l'ensemble du lot doit démarrer une nouvelle session" + +msgid "**Start a new session**: start one session for the batch" +msgstr "**Démarrer une nouvelle session** : démarrer une seule session pour le lot" + +msgid "**Continue in the current session** (default): append the whole batch to the active session" +msgstr "**Continuer dans la session courante** (par défaut) : ajouter l'ensemble du lot à la session active" + +msgid "**Ask once** is the UI label for one decision covering the complete" +msgstr "**Demander une seule fois** est le libellé de l'interface pour une décision unique couvrant l'intégralité de la" + +msgid "plugin multi-load scope, rather than one prompt per object. DataLab does not infer a multi-load scope from a sequence of plugin additions." +msgstr "portée de chargement multiple du plugin, et non pour une demande par objet. DataLab ne déduit pas une telle portée d'une suite d'ajouts effectués par un plugin." + msgid "Result management" msgstr "Gestion des résultats" From 50f03933ca21bb305e13a5f338c2c7ad4f675cbe Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Wed, 5 Aug 2026 14:33:41 +0200 Subject: [PATCH 071/108] Doc: Correct scientific terminology and history replay guidance History and interactive-processing documentation contained ambiguous replay semantics, outdated menu paths, and inconsistent scientific vocabulary. Align the descriptions with current UI behavior and synchronize the French catalog so readers receive complete, accurate guidance in both languages. * [FIX] : Clarify action and session Replay targets, distinguish computation selection restoration from UI replay, and document prompt debouncing * [FIX] : Correct Create and Gaussian filter menu paths and refine signal, image, metadata, ROI, and morphological processing terminology * [CHG] : Align French translations with UI labels and scientific vocabulary, removing fragmented messages that could display English fallbacks --- doc/features/common/historypanel.rst | 51 +++++---- doc/features/common/overview.rst | 34 +++--- doc/features/common/settings.rst | 10 +- .../features/common/historypanel.po | 105 +++++------------- .../LC_MESSAGES/features/common/overview.po | 57 +++++----- .../LC_MESSAGES/features/common/settings.po | 22 ++-- 6 files changed, 121 insertions(+), 158 deletions(-) diff --git a/doc/features/common/historypanel.rst b/doc/features/common/historypanel.rst index 5234813d4..96b3acc95 100644 --- a/doc/features/common/historypanel.rst +++ b/doc/features/common/historypanel.rst @@ -16,8 +16,8 @@ list of either: - **UI actions** (creating a new signal, removing selected objects, saving the workspace to HDF5, ...), or -- **computations** (FFT, average, Gaussian fit, ...) dispatched through the - Sigima processor. +- **computations** (FFT, average, Gaussian fit, ...) dispatched by the DataLab + processors to Sigima. A recorded session can be: @@ -54,9 +54,10 @@ between signals and images does not mix their recording contexts. When a new object is created or a file is loaded into a populated active session, a configurable policy determines whether DataLab asks, starts a new session, or continues the current one. Plugin-created objects use separate -policies. A single decision covers several objects only when the plugin uses -an explicit plugin multi-load scope; DataLab does not infer such a scope from -a sequence of additions. +policies. An explicit plugin multi-load scope supplies one durable session +policy for the whole batch. With ordinary **Ask** behavior, repeated prompts +for synchronous additions to the same panel are debounced during the current +Qt event-loop turn. These options are available under ``File > Settings > Processing > History sessions``. See @@ -134,13 +135,15 @@ The toolbar at the top of the panel exposes the following actions: session (keyboard shortcut: :kbd:`Ctrl+Left`). - |step_next| **Next step**: select the following action in the current session (keyboard shortcut: :kbd:`Ctrl+Right`). -- |replay| **Replay**: replay through the selected action, or replay the whole - session if a session row is selected. The recorded workspace selection is - not restored beforehand. New objects returned by computation actions are - not added to the data panels. Recorded UI actions may reproduce side effects, - including creating, importing, or duplicating objects, unless an action has - a specific replay guard. -- |step_by_step| **Step-by-step**: process the selection one step at a time. +- |replay| **Replay**: selecting an action replays that action directly; + selecting a session replays the whole session. Compute actions restore their + captured input selection when the translated object identifiers are + compatible and resolvable; UI actions are replayed without restoring their + recorded workspace selection. New objects returned by computation actions + are not added to the data panels. Recorded UI actions may reproduce side + effects, including creating, importing, or duplicating objects, unless an + action has a specific replay guard. +- |step_by_step| **Step-by-step**: replay the selection one step at a time. Parameters may be reviewed and edited when the action supports it; supported actions and their dependent branches are then updated or recomputed in place. @@ -156,9 +159,9 @@ The toolbar at the top of the panel exposes the following actions: .. note:: - Double-clicking a tree item triggers **Replay** for the current selection, - using the action/session semantics described for **Replay** above. The - recorded workspace selection is not restored before replay. + Double-clicking a tree item invokes **Replay** for the current selection. It + uses the same action/session and compute/UI selection semantics documented + above. Tree view --------- @@ -185,7 +188,8 @@ for its data panel. Actions that are not compatible with the current workspace state (for example because a referenced object identifier no longer exists, or because its data -shape changed) are shown with a disabled foreground and an explanatory tooltip. +array shape changed) are shown with a disabled foreground and an explanatory +tooltip. They cannot be replayed until the workspace matches the recorded state again. Workspace state display @@ -194,7 +198,7 @@ Workspace state display Below the action tree, a split-view widget shows the **workspace state** captured at the time of the selected action: -- **Left table**: lists the signals that were selected, with their data shape. +- **Left table**: lists the signals that were selected, with their array shape. - **Right table**: lists the images that were selected, with their dimensions. This information helps the user understand the context in which each action @@ -250,13 +254,12 @@ reconnect to preserve the processing flow. .. note:: - Reconnection is only triggered by deletions initiated from the - signal/image panels. Deleting an action directly from the History Panel - tree behaves differently: the selected action is spliced out instead - of truncating the session. If downstream steps depend on it, DataLab - preserves them as an independent chain by cloning the required intermediate - object and reconnecting those steps to the clone. Deleting a session removes - that complete session. + Reconnection is only triggered by deletions initiated from the signal/image + panels. Deleting an action directly from the History Panel tree behaves + differently: the selected action is spliced out instead of truncating the + session. If downstream steps depend on it, DataLab preserves them as an + independent chain by cloning the required intermediate object and reconnecting + those steps to the clone. Deleting a session removes that complete session. Auto-recompute -------------- diff --git a/doc/features/common/overview.rst b/doc/features/common/overview.rst index bb9df13d2..db73472ad 100644 --- a/doc/features/common/overview.rst +++ b/doc/features/common/overview.rst @@ -43,14 +43,14 @@ DataLab has its own internal data model, in which data sets are organized around a tree structure. Each panel in the main window corresponds to a branch of the tree. Each data set shown in the panels corresponds to a leaf of the tree. Inside the data set, the data is organized in an object-oriented way, with a set of -attributes and methods. The data model is described in more details in the +attributes and methods. The data model is described in more detail in the API section (see :mod:`sigima.objects`). -For each data set (1D signal or 2D image), not only the data itself is stored, -but also a set of metadata, which describes the data or the way it has to be -displayed. The metadata is stored in a dictionary, which is accessible through -the ``metadata`` attribute of the data set (and may also be browsed in the -**Properties** view, with the **Metadata** button). +For each signal or image object, DataLab stores not only the data itself but +also a set of metadata describing the data and how it should be displayed. The +metadata is stored in a dictionary accessible through the object's ``metadata`` +attribute (and may also be browsed in the **Properties** view, with the +**Metadata** button). The DataLab **Workspace** is defined as the collection of all data sets which are currently loaded in DataLab, in both the **Signals** and **Images** panels. @@ -83,17 +83,17 @@ parameters, allowing you to fine-tune results without creating multiple objects. Interactive object creation ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -When creating a new signal or image using the creation functions (e.g., Gaussian signal, -2D peak image, etc.), DataLab stores the creation parameters in the object's metadata. -This enables interactive parameter adjustment after creation: +When creating a new signal or image object using the creation functions (e.g., Gaussian +signal, 2D peak image, etc.), DataLab stores the creation parameters in the object's +metadata. This enables interactive parameter adjustment after creation: -1. Create a signal or image using **Operations** > **Create** menu +1. Create a signal or image object from the **Create** menu 2. Select the created object in the list 3. A **Creation** tab appears in the Properties panel (bottom-left) 4. Modify any creation parameter (amplitude, frequency, size, etc.) 5. Click **Apply** to regenerate the object with new parameters -The object is updated in-place, preserving any subsequent processing or analysis results. +The object is updated in place, preserving any subsequent processing or analysis results. This is particularly useful for: - Exploring different parameter values without cluttering the workspace @@ -112,18 +112,18 @@ When applying a 1-to-1 processing operation that has configurable parameters (e. Gaussian filter, threshold, morphological operations), DataLab stores the processing metadata, enabling parameter adjustment and re-processing: -1. Apply a processing operation with parameters (e.g., **Processing** > **Filtering** > **Gaussian filter**) +1. Apply a processing operation with parameters (e.g., **Processing** > **Noise reduction** > **Gaussian filter**) 2. The result object contains processing metadata (parameters, source object, function name) 3. Select the processed object in the list 4. A **Processing** tab appears in the Properties panel 5. Modify processing parameters (e.g., filter sigma value) 6. Click **Apply** to re-process with updated parameters -The processed object is updated in-place with the new results. This workflow is ideal for: +The processed object is updated in place with the new results. This workflow is ideal for: -- Iteratively tuning filter parameters while observing results in real-time +- Iteratively tuning filter parameters while observing results in real time - Adjusting threshold values without creating multiple intermediate objects -- Experimenting with different morphological structure element sizes +- Experimenting with different morphological structuring element sizes - Educational demonstrations of parameter effects on processing results .. note:: @@ -145,7 +145,7 @@ Example workflow Here's a typical workflow using interactive processing: -1. **Create a test signal**: Operations > Create > Gaussian signal +1. **Create a test signal**: Create > Gaussian signal - Initial parameters: amplitude=1.0, mu=50, sigma=10 @@ -153,7 +153,7 @@ Here's a typical workflow using interactive processing: - Signal is regenerated with new width -3. **Apply Gaussian filter**: Processing > Filtering > Gaussian filter +3. **Apply Gaussian filter**: Processing > Noise reduction > Gaussian filter - Initial sigma=2.0 diff --git a/doc/features/common/settings.rst b/doc/features/common/settings.rst index b56085b16..fd353ad53 100644 --- a/doc/features/common/settings.rst +++ b/doc/features/common/settings.rst @@ -126,7 +126,7 @@ The Processing settings tab controls computation behavior and default parameters for easier visualization and analysis. **Extract multiple ROIs in a single object** - When enabled, multiple ROIs (Regions of Interest) are extracted into a single object. + When enabled, multiple regions of interest (ROIs) are extracted into a single object. When disabled, each ROI is extracted into a separate object. **Ignore warnings** @@ -173,9 +173,11 @@ see :ref:`historypanel` for the complete workflow. - **Continue in the current session** (default): append the whole batch to the active session - **Ask once** is the UI label for one decision covering the complete - plugin multi-load scope, rather than one prompt per object. DataLab does - not infer a multi-load scope from a sequence of plugin additions. + **Ask once** is the UI label for one durable session decision covering the + complete explicit plugin multi-load scope, rather than one prompt per + object. With ordinary **Ask** behavior, repeated prompts for synchronous + additions to the same panel are debounced during the current Qt event-loop + turn. Result management ^^^^^^^^^^^^^^^^^ diff --git a/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po b/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po index c333120a0..6a93dd4be 100644 --- a/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po +++ b/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po @@ -5,11 +5,18 @@ # msgid "" msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2026-08-05 14:24+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language: fr\n" +"Language-Team: fr <LL@li.org>\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.18.0\n" msgid "History Panel in DataLab, the open-source scientific data analysis and visualization platform" msgstr "Panneau d'historique de DataLab, la plateforme open-source d'analyse et de visualisation de données scientifiques" @@ -29,14 +36,14 @@ msgstr "Le « panneau d'historique » enregistre la séquence des actions effect msgid "**UI actions** (creating a new signal, removing selected objects, saving the workspace to HDF5, ...), or" msgstr "d'**actions de l'interface** (création d'un nouveau signal, suppression des objets sélectionnés, enregistrement de l'espace de travail au format HDF5, ...), soit" -msgid "**computations** (FFT, average, Gaussian fit, ...) dispatched through the Sigima processor." -msgstr "de **calculs** (FFT, moyenne, ajustement gaussien, ...) exécutés via le processeur Sigima." +msgid "**computations** (FFT, average, Gaussian fit, ...) dispatched by the DataLab processors to Sigima." +msgstr "de **calculs** (FFT, moyenne, ajustement gaussien, ...) dont l'exécution est confiée à Sigima par les processeurs de DataLab." msgid "A recorded session can be:" msgstr "Une session enregistrée peut être :" msgid "**Replayed** silently or **step by step**, with an opportunity to edit available parameters. New outputs from computation actions are not added to the data panels. Recorded UI actions are invoked through their own methods and may reproduce their side effects, including creating, importing, or duplicating objects, unless an action has a specific replay guard;" -msgstr "**rejouée** silencieusement ou **pas à pas**, avec la possibilité de modifier les paramètres disponibles. Les nouvelles sorties des actions de calcul ne sont pas ajoutées aux panneaux de données. Les actions de l'interface enregistrées sont invoquées par leurs propres méthodes et peuvent reproduire leurs effets, notamment créer, importer ou dupliquer des objets, sauf lorsqu'une action possède une garde de rejeu spécifique ;" +msgstr "**rejouée** silencieusement ou **pas à pas**, avec la possibilité de modifier les paramètres disponibles. Les nouvelles sorties des actions de calcul ne sont pas ajoutées aux panneaux de données. Les actions de l'interface enregistrées sont invoquées par leurs propres méthodes et peuvent reproduire leurs effets, notamment créer, importer ou dupliquer des objets, sauf lorsqu'une action dispose d'un mécanisme de protection spécifique lors du rejeu ;" msgid "**Duplicated** as independent processing chains in new history sessions, with the required signal/image objects cloned as part of the operation;" msgstr "**dupliquée** sous forme de chaînes de traitement indépendantes dans de nouvelles sessions d'historique, les objets signal/image nécessaires étant clonés au cours de l'opération ;" @@ -56,11 +63,11 @@ msgstr "Les actions ne sont enregistrées que lorsque le **Mode d'enregistrement msgid "The Signals and Images panels each have their own active session. New actions are added to the active session of the data panel they concern, so switching between signals and images does not mix their recording contexts." msgstr "Les panneaux Signaux et Images disposent chacun de leur propre session active. Les nouvelles actions sont ajoutées à la session active du panneau de données concerné ; ainsi, le passage des signaux aux images ne mélange pas leurs contextes d'enregistrement." -msgid "When a new object is created or a file is loaded into a populated active session, a configurable policy determines whether DataLab asks, starts a new session, or continues the current one. Plugin-created objects use separate policies. A single decision covers several objects only when the plugin uses an explicit plugin multi-load scope; DataLab does not infer such a scope from a sequence of additions." -msgstr "Lorsqu'un nouvel objet est créé ou qu'un fichier est chargé dans une session active non vide, une politique configurable détermine si DataLab demande quoi faire, démarre une nouvelle session ou continue dans la session courante. Des politiques distinctes s'appliquent aux objets créés par des plugins. Une décision unique ne couvre plusieurs objets que lorsque le plugin utilise une portée explicite de chargement multiple ; DataLab ne déduit pas une telle portée d'une suite d'ajouts." +msgid "When a new object is created or a file is loaded into a populated active session, a configurable policy determines whether DataLab asks, starts a new session, or continues the current one. Plugin-created objects use separate policies. An explicit plugin multi-load scope supplies one durable session policy for the whole batch. With ordinary **Ask** behavior, repeated prompts for synchronous additions to the same panel are debounced during the current Qt event-loop turn." +msgstr "Lorsqu'un nouvel objet est créé ou qu'un fichier est chargé dans une session active non vide, une politique configurable détermine si DataLab demande quoi faire, démarre une nouvelle session ou continue dans la session courante. Des politiques distinctes s'appliquent aux objets créés par des plugins. Une portée explicite de chargement multiple par un plugin fournit une politique de session unique et durable pour l'ensemble du lot. Avec le comportement **Demander** ordinaire, un mécanisme anti-rebond évite les demandes répétées pour les ajouts synchrones au même panneau pendant le tour courant de la boucle d'événements Qt." msgid "These options are available under ``File > Settings > Processing > History sessions``. See :ref:`history-session-settings` for the complete labels and default values." -msgstr "Ces options sont disponibles sous ``Fichier > Paramètres > Traitement > Sessions d'historique``. Voir :ref:`history-session-settings` pour la liste complète des libellés et des valeurs par défaut." +msgstr "Ces options sont disponibles sous ``Fichier > Préférences > Traitement > Sessions d'historique``. Voir :ref:`history-session-settings` pour la liste complète des libellés et des valeurs par défaut." msgid "Toolbar" msgstr "Barre d'outils" @@ -104,14 +111,14 @@ msgstr "|step_next| **Étape suivante** : sélectionne l'action suivante dans la msgid "step_next" msgstr "step_next" -msgid "|replay| **Replay**: replay through the selected action, or replay the whole session if a session row is selected. The recorded workspace selection is not restored beforehand. New objects returned by computation actions are not added to the data panels. Recorded UI actions may reproduce side effects, including creating, importing, or duplicating objects, unless an action has a specific replay guard." -msgstr "|replay| **Rejouer** : rejoue jusqu'à l'action sélectionnée, ou rejoue la session entière si une ligne de session est sélectionnée. La sélection enregistrée de l'espace de travail n'est pas restaurée au préalable. Les nouveaux objets renvoyés par les actions de calcul ne sont pas ajoutés aux panneaux de données. Les actions de l'interface enregistrées peuvent reproduire des effets, notamment créer, importer ou dupliquer des objets, sauf lorsqu'une action possède une garde de rejeu spécifique." +msgid "|replay| **Replay**: selecting an action replays that action directly; selecting a session replays the whole session. Compute actions restore their captured input selection when the translated object identifiers are compatible and resolvable; UI actions are replayed without restoring their recorded workspace selection. New objects returned by computation actions are not added to the data panels. Recorded UI actions may reproduce side effects, including creating, importing, or duplicating objects, unless an action has a specific replay guard." +msgstr "|replay| **Rejouer** : sélectionner une action rejoue directement cette action ; sélectionner une session rejoue toute la session. Les actions de calcul restaurent leur sélection d'entrées capturée lorsque les identifiants d'objets remappés sont compatibles et peuvent être résolus ; les actions de l'interface sont rejouées sans restaurer au préalable leur sélection de l'espace de travail enregistrée. Les nouveaux objets renvoyés par les actions de calcul ne sont pas ajoutés aux panneaux de données. Les actions de l'interface enregistrées peuvent reproduire des effets, notamment créer, importer ou dupliquer des objets, sauf lorsqu'une action dispose d'un mécanisme de protection spécifique lors du rejeu." msgid "replay" msgstr "replay" -msgid "|step_by_step| **Step-by-step**: process the selection one step at a time. Parameters may be reviewed and edited when the action supports it; supported actions and their dependent branches are then updated or recomputed in place." -msgstr "|step_by_step| **Pas à pas** : traite la sélection une étape à la fois. Les paramètres peuvent être examinés et modifiés lorsque l'action le permet ; les actions prises en charge et leurs branches dépendantes sont alors mises à jour ou recalculées sur place." +msgid "|step_by_step| **Step-by-step**: replay the selection one step at a time. Parameters may be reviewed and edited when the action supports it; supported actions and their dependent branches are then updated or recomputed in place." +msgstr "|step_by_step| **Pas à pas** : rejoue la sélection pas à pas. Les paramètres peuvent être examinés et modifiés lorsque l'action le permet ; les actions prises en charge et leurs branches dépendantes sont alors mises à jour ou recalculées sur place." msgid "step_by_step" msgstr "step_by_step" @@ -134,8 +141,8 @@ msgstr "|delete| **Supprimer** : retire de l'historique les actions ou sessions msgid "delete" msgstr "delete" -msgid "Double-clicking a tree item triggers **Replay** for the current selection, using the action/session semantics described for **Replay** above. The recorded workspace selection is not restored before replay." -msgstr "Un double-clic sur un élément de l'arborescence déclenche **Rejouer** pour la sélection courante, selon la sémantique action/session décrite ci-dessus pour **Rejouer**. La sélection enregistrée de l'espace de travail n'est pas restaurée avant le rejeu." +msgid "Double-clicking a tree item invokes **Replay** for the current selection. It uses the same action/session and compute/UI selection semantics documented above." +msgstr "Un double-clic sur un élément de l'arborescence déclenche **Rejouer** pour la sélection courante. Ce rejeu suit les mêmes règles que celles décrites ci-dessus concernant la sélection d'une action ou d'une session et la restauration des sélections pour les calculs ou l'interface." msgid "Tree view" msgstr "Arborescence" @@ -158,8 +165,8 @@ msgstr "Lorsqu'une ligne d'action est sélectionnée, son objet résultat est s msgid "While Record mode is enabled, selecting a session row makes that session active for its data panel." msgstr "Lorsque le mode d'enregistrement est activé, sélectionner une ligne de session rend cette session active pour son panneau de données." -msgid "Actions that are not compatible with the current workspace state (for example because a referenced object identifier no longer exists, or because its data shape changed) are shown with a disabled foreground and an explanatory tooltip. They cannot be replayed until the workspace matches the recorded state again." -msgstr "Les actions qui ne sont pas compatibles avec l'état courant de l'espace de travail (par exemple parce qu'un identifiant d'objet référencé n'existe plus, ou parce que la forme de ses données a changé) sont affichées avec un texte désactivé et une infobulle explicative. Elles ne peuvent pas être rejouées tant que l'espace de travail ne correspond pas de nouveau à l'état enregistré." +msgid "Actions that are not compatible with the current workspace state (for example because a referenced object identifier no longer exists, or because its data array shape changed) are shown with a disabled foreground and an explanatory tooltip. They cannot be replayed until the workspace matches the recorded state again." +msgstr "Les actions qui ne sont pas compatibles avec l'état courant de l'espace de travail (par exemple parce qu'un identifiant d'objet référencé n'existe plus, ou parce que la forme de son tableau a changé) sont affichées avec un texte désactivé et une infobulle explicative. Elles ne peuvent pas être rejouées tant que l'espace de travail ne correspond pas de nouveau à l'état enregistré." msgid "Workspace state display" msgstr "Affichage de l'état de l'espace de travail" @@ -167,8 +174,8 @@ msgstr "Affichage de l'état de l'espace de travail" msgid "Below the action tree, a split-view widget shows the **workspace state** captured at the time of the selected action:" msgstr "Sous l'arborescence des actions, un widget en vue divisée affiche l'**état de l'espace de travail** tel qu'il était au moment de l'action sélectionnée :" -msgid "**Left table**: lists the signals that were selected, with their data shape." -msgstr "**Tableau de gauche** : liste les signaux qui étaient sélectionnés, avec leur forme de données." +msgid "**Left table**: lists the signals that were selected, with their array shape." +msgstr "**Tableau de gauche** : liste les signaux qui étaient sélectionnés, avec la forme de leur tableau." msgid "**Right table**: lists the images that were selected, with their dimensions." msgstr "**Tableau de droite** : liste les images qui étaient sélectionnées, avec leurs dimensions." @@ -180,7 +187,7 @@ msgid "Persistence" msgstr "Persistance" msgid "The history can be persisted in two complementary ways:" -msgstr "L'historique peut être persisté de deux manières complémentaires :" +msgstr "L'historique peut être enregistré de deux manières complémentaires :" msgid "**Embedded in the workspace**: when the workspace is saved to HDF5 (``File > Save to HDF5 file``), the History Panel content is automatically saved alongside the signals and images. Reloading the workspace restores the recorded sessions." msgstr "**Intégré à l'espace de travail** : lorsque l'espace de travail est enregistré au format HDF5 (``Fichier > Enregistrer dans un fichier HDF5``), le contenu du panneau d'historique est automatiquement sauvegardé aux côtés des signaux et des images. Le rechargement de l'espace de travail restaure les sessions enregistrées." @@ -215,71 +222,11 @@ msgstr "Si aucune source valide ne peut être déterminée (par exemple la sourc msgid "This behaviour mirrors removing a link from a chain: the adjacent links reconnect to preserve the processing flow." msgstr "Ce comportement reproduit la suppression d'un maillon d'une chaîne : les maillons adjacents se reconnectent pour préserver le flux de traitement." -msgid "Reconnection is only triggered by deletions initiated from the signal/image panels. Deleting an action directly from the History Panel" -msgstr "La reconnexion n'est déclenchée que par les suppressions initiées depuis les panneaux signal/image. La suppression d'une action directement depuis l'arborescence du panneau d'historique" - -msgid "tree behaves differently: the selected action is spliced out instead of truncating the session. If downstream steps depend on it, DataLab preserves them as an independent chain by cloning the required intermediate object and reconnecting those steps to the clone. Deleting a session removes that complete session." -msgstr "se comporte différemment : l'action sélectionnée est retirée de la chaîne au lieu de tronquer la session. Si des étapes en aval en dépendent, DataLab les conserve sous forme de chaîne indépendante en clonant l'objet intermédiaire requis et en reconnectant ces étapes au clone. La suppression d'une session supprime cette session dans son intégralité." +msgid "Reconnection is only triggered by deletions initiated from the signal/image panels. Deleting an action directly from the History Panel tree behaves differently: the selected action is spliced out instead of truncating the session. If downstream steps depend on it, DataLab preserves them as an independent chain by cloning the required intermediate object and reconnecting those steps to the clone. Deleting a session removes that complete session." +msgstr "La reconnexion n'est déclenchée que par les suppressions effectuées depuis les panneaux Signaux ou Images. La suppression d'une action directement depuis l'arborescence du panneau d'historique suit un autre comportement : l'action sélectionnée est retirée de la chaîne au lieu de tronquer la session. Si des étapes en aval en dépendent, DataLab les conserve sous forme de chaîne indépendante en clonant l'objet intermédiaire nécessaire et en reconnectant ces étapes au clone. La suppression d'une session supprime cette session dans son intégralité." msgid "Auto-recompute" msgstr "Recalcul automatique" msgid "When a result object is selected in the signal/image panel and it has processing parameters (i.e. was produced by a 1-to-1 computation), a **Processing** tab appears in the Properties panel. Checking **Auto-recompute on edit** in that tab will re-run the computation automatically 300 ms after any parameter modification." msgstr "Lorsqu'un objet résultat est sélectionné dans le panneau signal/image et qu'il possède des paramètres de traitement (c'est-à-dire qu'il a été produit par un calcul 1-à-1), un onglet **Traitement** apparaît dans le panneau Propriétés. Cocher **Recalcul automatique lors de l'édition** dans cet onglet relancera automatiquement le calcul 300 ms après toute modification d'un paramètre." - -#~ msgid "**Restored to a given selection state** without re-executing anything, to quickly jump back to a previous working context;" -#~ msgstr "**restaurée dans un état de sélection donné** sans rien réexécuter, afin de revenir rapidement à un contexte de travail antérieur ;" - -#~ msgid "|restore_selection| **Restore selection**: only re-select the objects that were selected when the action was originally executed; no computation is re-run." -#~ msgstr "|restore_selection| **Restaurer la sélection** : ré-sélectionne uniquement les objets qui étaient sélectionnés lors de l'exécution initiale de l'action ; aucun calcul n'est ré-exécuté." - -#~ msgid "restore_selection" -#~ msgstr "restore_selection" - -#~ msgid "|edit_mode| **Edit mode**: when on, replaying a computation opens the parameters dialog so the user can tweak the parameters before re-running. When replaying a *whole session*, the parameter dialogs open in a **read-only** mode — all fields are shown with their recorded values but cannot be edited." -#~ msgstr "|edit_mode| **Mode édition** : lorsqu'il est activé, le rejeu d'un calcul ouvre la boîte de dialogue des paramètres afin que l'utilisateur puisse ajuster les paramètres avant de relancer. Lors du rejeu d'une *session entière*, les boîtes de dialogue des paramètres s'ouvrent en mode **lecture seule** — tous les champs affichent les valeurs enregistrées mais ne peuvent pas être édités." - -#~ msgid "edit_mode" -#~ msgstr "edit_mode" - -#~ msgid "|generate_macro| **Generate macro**: generate a Python macro script from the selected actions (or all actions if nothing is selected). The generated script is copied to the clipboard." -#~ msgstr "|generate_macro| **Générer une macro** : génère un script macro Python à partir des actions sélectionnées (ou de toutes les actions si rien n'est sélectionné). Le script généré est copié dans le presse-papiers." - -#~ msgid "generate_macro" -#~ msgstr "generate_macro" - -#~ msgid "**Duplicated and applied**, to create an explicit comparison branch with new outputs in the signal/image panels;" -#~ msgstr "**dupliquée et appliquée**, afin de créer une branche de comparaison explicite avec de nouvelles sorties dans les panneaux signal/image ;" - -#~ msgid "|step_by_step| **Step-by-step**: replay the selection one step at a time, opening the parameters dialog at each step so the user can tweak the parameters before re-running." -#~ msgstr "|step_by_step| **Pas à pas** : rejoue la sélection étape par étape, en ouvrant la boîte de dialogue des paramètres à chaque étape afin que l'utilisateur puisse ajuster les paramètres avant de relancer." - -#~ msgid "|duplicate| **Duplicate**: copy the selected action or session into a new history session. The copied parameters are independent from the original record." -#~ msgstr "|duplicate| **Dupliquer** : copie l'action ou la session sélectionnée dans une nouvelle session d'historique. Les paramètres copiés sont indépendants de l'enregistrement d'origine." - -#~ msgid "|delete| **Delete**: remove the selected actions or sessions from the history." -#~ msgstr "|delete| **Supprimer** : retire de l'historique les actions ou sessions sélectionnées." - -#~ msgid "Each top-level row is a **session**, automatically created when recording is enabled and a new application context is started." -#~ msgstr "Chaque ligne de premier niveau est une **session**, créée automatiquement lorsque l'enregistrement est activé et qu'un nouveau contexte d'application est démarré." - -#~ msgid "Session replay across workspaces" -#~ msgstr "Rejeu d'une session entre espaces de travail" - -#~ msgid "A full session can be replayed on a workspace that no longer contains the objects originally referenced by the recorded actions -- typically after loading a saved session into a fresh workspace. In that case, the panel **remaps the recorded object identifiers** to the newly-created ones on the fly:" -#~ msgstr "Une session complète peut être rejouée sur un espace de travail qui ne contient plus les objets référencés à l'origine par les actions enregistrées -- typiquement après le chargement d'une session sauvegardée dans un espace de travail vierge. Dans ce cas, le panneau **réassocie à la volée les identifiants d'objets enregistrés** aux nouveaux identifiants créés :" - -#~ msgid "UI actions creating new objects (e.g. *New signal*) enqueue the freshly created identifiers;" -#~ msgstr "les actions de l'interface qui créent de nouveaux objets (par exemple *Nouveau signal*) empilent les identifiants fraîchement créés ;" - -#~ msgid "subsequent computations claim the identifiers they need from that queue, in the same order as the original recording;" -#~ msgstr "les calculs ultérieurs récupèrent dans cette file les identifiants dont ils ont besoin, dans l'ordre de l'enregistrement initial ;" - -#~ msgid "UI actions removing objects keep the queue in sync with the live workspace contents, so chained creation/removal sequences replay correctly." -#~ msgstr "les actions de l'interface qui suppriment des objets maintiennent la file synchronisée avec le contenu réel de l'espace de travail, de sorte que les séquences enchaînées de création et de suppression se rejouent correctement." - -#~ msgid "This makes it possible, for instance, to record a full processing chain on one dataset, save it, then re-apply the exact same chain on a different but structurally identical input." -#~ msgstr "Cela permet par exemple d'enregistrer une chaîne de traitement complète sur un jeu de données, de la sauvegarder, puis de la ré-appliquer telle quelle à une entrée différente mais structurellement identique." - -#~ msgid "Opening a ``.dlhist`` into an **empty workspace** loads sessions and objects directly, restoring the workspace to its recorded state." -#~ msgstr "Ouvrir un fichier ``.dlhist`` dans un **espace de travail vide** charge les sessions et les objets directement, restaurant l'espace de travail dans son état enregistré." diff --git a/doc/locale/fr/LC_MESSAGES/features/common/overview.po b/doc/locale/fr/LC_MESSAGES/features/common/overview.po index d6b258181..eb3f38589 100644 --- a/doc/locale/fr/LC_MESSAGES/features/common/overview.po +++ b/doc/locale/fr/LC_MESSAGES/features/common/overview.po @@ -6,9 +6,16 @@ #, fuzzy msgid "" msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2026-08-05 14:24+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.18.0\n" msgid "Overview and basic concepts of DataLab, the open-source scientific data analysis and visualization platform" msgstr "Vue d'ensemble et concepts de base de DataLab, la plateforme open-source d'analyse et de visualisation de données scientifiques" @@ -43,11 +50,11 @@ msgstr "Le :ref:`historypanel` est un panneau ancrable supplémentaire qui enreg msgid "Internal data model and workspace" msgstr "Modèle de données interne et espace de travail" -msgid "DataLab has its own internal data model, in which data sets are organized around a tree structure. Each panel in the main window corresponds to a branch of the tree. Each data set shown in the panels corresponds to a leaf of the tree. Inside the data set, the data is organized in an object-oriented way, with a set of attributes and methods. The data model is described in more details in the API section (see :mod:`sigima.objects`)." +msgid "DataLab has its own internal data model, in which data sets are organized around a tree structure. Each panel in the main window corresponds to a branch of the tree. Each data set shown in the panels corresponds to a leaf of the tree. Inside the data set, the data is organized in an object-oriented way, with a set of attributes and methods. The data model is described in more detail in the API section (see :mod:`sigima.objects`)." msgstr "DataLab a son propre modèle de données interne, dans lequel les jeux de données sont organisés autour d'une structure arborescente. Chaque panneau de la fenêtre principale correspond à une branche de l'arbre. Chaque jeu de données affiché dans les panneaux correspond à une feuille de l'arbre. À l'intérieur du jeu de données, les données sont organisées de manière orientée objet, avec un ensemble d'attributs et de méthodes. Le modèle de données est décrit plus en détail dans la section API (voir :mod:`sigima.objects`)." -msgid "For each data set (1D signal or 2D image), not only the data itself is stored, but also a set of metadata, which describes the data or the way it has to be displayed. The metadata is stored in a dictionary, which is accessible through the ``metadata`` attribute of the data set (and may also be browsed in the **Properties** view, with the **Metadata** button)." -msgstr "Pour chaque jeu de données (signal 1D ou image 2D), non seulement les données elles-mêmes sont stockées, mais aussi un ensemble de métadonnées, qui décrit les données ou la façon dont elles doivent être affichées. Les métadonnées sont stockées dans un dictionnaire, qui est accessible via l'attribut ``metadata`` du jeu de données (et peuvent également être parcourues dans la vue **Propriétés**, avec le bouton **Métadonnées**)." +msgid "For each signal or image object, DataLab stores not only the data itself but also a set of metadata describing the data and how it should be displayed. The metadata is stored in a dictionary accessible through the object's ``metadata`` attribute (and may also be browsed in the **Properties** view, with the **Metadata** button)." +msgstr "Pour chaque objet signal ou image, DataLab stocke non seulement les données elles-mêmes, mais aussi un ensemble de métadonnées décrivant les données et la manière dont elles doivent être affichées. Ces métadonnées sont stockées dans un dictionnaire accessible par l'attribut ``metadata`` de l'objet (et peuvent également être consultées dans la vue **Propriétés**, à l'aide du bouton **Métadonnées**)." msgid "The DataLab **Workspace** is defined as the collection of all data sets which are currently loaded in DataLab, in both the **Signals** and **Images** panels." msgstr "L'**Espace de travail** de DataLab est défini comme l'ensemble de tous les jeux de données actuellement chargés dans DataLab, dans les panneaux **Signaux** et **Images**." @@ -77,13 +84,13 @@ msgid "DataLab provides an interactive workflow for creating objects and adjusti msgstr "DataLab fournit un flux de travail interactif pour créer des objets et ajuster les paramètres de traitement, vous permettant d'affiner les résultats sans créer plusieurs objets." msgid "Interactive object creation" -msgstr "Création d'objets interactifs" +msgstr "Création interactive d'objets" -msgid "When creating a new signal or image using the creation functions (e.g., Gaussian signal, 2D peak image, etc.), DataLab stores the creation parameters in the object's metadata. This enables interactive parameter adjustment after creation:" +msgid "When creating a new signal or image object using the creation functions (e.g., Gaussian signal, 2D peak image, etc.), DataLab stores the creation parameters in the object's metadata. This enables interactive parameter adjustment after creation:" msgstr "Lors de la création d'un nouveau signal ou d'une nouvelle image à l'aide des fonctions de création (par exemple, signal gaussien, image de pic 2D, etc.), DataLab stocke les paramètres de création dans les métadonnées de l'objet. Cela permet d'ajuster les paramètres de manière interactive après la création :" -msgid "Create a signal or image using **Operations** > **Create** menu" -msgstr "Créer un signal ou une image en utilisant le menu **Opérations** > **Créer**" +msgid "Create a signal or image object from the **Create** menu" +msgstr "Créer un objet signal ou image depuis le menu **Création**" msgid "Select the created object in the list" msgstr "Sélectionner l'objet créé dans la liste" @@ -97,7 +104,7 @@ msgstr "Modifier n'importe quel paramètre de création (amplitude, fréquence, msgid "Click **Apply** to regenerate the object with new parameters" msgstr "Cliquer sur **Appliquer** pour régénérer l'objet avec les nouveaux paramètres" -msgid "The object is updated in-place, preserving any subsequent processing or analysis results. This is particularly useful for:" +msgid "The object is updated in place, preserving any subsequent processing or analysis results. This is particularly useful for:" msgstr "L'objet est mis à jour sur place, préservant tous les résultats de traitement ou d'analyse ultérieurs. Cela est particulièrement utile pour :" msgid "Exploring different parameter values without cluttering the workspace" @@ -116,10 +123,10 @@ msgid "Interactive 1-to-1 processing" msgstr "Traitement interactif 1-vers-1" msgid "When applying a 1-to-1 processing operation that has configurable parameters (e.g., Gaussian filter, threshold, morphological operations), DataLab stores the processing metadata, enabling parameter adjustment and re-processing:" -msgstr "Lors de l'application d'une opération de traitement 1-vers-1 qui a des paramètres configurables (par exemple, filtre gaussien, seuil, opérations morphologiques), DataLab stocke les métadonnées de traitement, permettant l'ajustement des paramètres et le re-traitement :" +msgstr "Lors de l'application d'une opération de traitement 1-vers-1 qui a des paramètres configurables (par exemple, filtre gaussien, seuil, opérations morphologiques), DataLab stocke les métadonnées de traitement, permettant l'ajustement des paramètres et le retraitement :" -msgid "Apply a processing operation with parameters (e.g., **Processing** > **Filtering** > **Gaussian filter**)" -msgstr "Appliquer une opération de traitement avec des paramètres (par exemple, **Traitement** > **Filtrage** > **Filtre gaussien**)" +msgid "Apply a processing operation with parameters (e.g., **Processing** > **Noise reduction** > **Gaussian filter**)" +msgstr "Appliquer une opération de traitement avec des paramètres (par exemple, **Traitement** > **Réduction de bruit** > **Filtre gaussien**)" msgid "The result object contains processing metadata (parameters, source object, function name)" msgstr "L'objet résultant contient des métadonnées de traitement (paramètres, objet source, nom de la fonction)" @@ -131,22 +138,22 @@ msgid "A **Processing** tab appears in the Properties panel" msgstr "Un onglet **Traitement** apparaît dans le panneau des propriétés" msgid "Modify processing parameters (e.g., filter sigma value)" -msgstr "Modifier les paramètres de traitement (par exemple, valeur sigma du filtre)" +msgstr "Modifier les paramètres de traitement (par exemple, valeur du sigma du filtre)" msgid "Click **Apply** to re-process with updated parameters" -msgstr "Cliquer sur **Appliquer** pour re-traiter avec les paramètres mis à jour" +msgstr "Cliquer sur **Appliquer** pour retraiter avec les paramètres mis à jour" -msgid "The processed object is updated in-place with the new results. This workflow is ideal for:" +msgid "The processed object is updated in place with the new results. This workflow is ideal for:" msgstr "L'objet traité est mis à jour sur place avec les nouveaux résultats. Ce flux de travail est idéal pour :" -msgid "Iteratively tuning filter parameters while observing results in real-time" -msgstr "Ajustement itératif des paramètres du filtre tout en observant les résultats en temps réel" +msgid "Iteratively tuning filter parameters while observing results in real time" +msgstr "Ajuster de manière itérative les paramètres du filtre tout en observant les résultats en temps réel" msgid "Adjusting threshold values without creating multiple intermediate objects" msgstr "Ajustement des valeurs de seuil sans créer plusieurs objets intermédiaires" -msgid "Experimenting with different morphological structure element sizes" -msgstr "Expérimentation avec différentes tailles d'éléments de structure morphologique" +msgid "Experimenting with different morphological structuring element sizes" +msgstr "Tester différentes tailles d'éléments structurants morphologiques" msgid "Educational demonstrations of parameter effects on processing results" msgstr "Démonstrations éducatives des effets des paramètres sur les résultats du traitement" @@ -161,7 +168,7 @@ msgid "Processing functions without parameters (e.g., absolute value, inverse) w msgstr "Les fonctions de traitement sans paramètres (par exemple, valeur absolue, inverse) fonctionnent comme auparavant" msgid "Source object must still exist for re-processing (error shown if deleted)" -msgstr "L'objet source doit toujours exister pour le re-traitement (erreur affichée s'il est supprimé)" +msgstr "L'objet source doit toujours exister pour le retraitement (erreur affichée s'il est supprimé)" msgid "**Not supported for:**" msgstr "**Non pris en charge pour :**" @@ -181,20 +188,20 @@ msgstr "Exemple de flux de travail" msgid "Here's a typical workflow using interactive processing:" msgstr "Voici un flux de travail typique utilisant le traitement interactif :" -msgid "**Create a test signal**: Operations > Create > Gaussian signal" -msgstr "**Créer un signal de test** : Opérations > Créer > Signal gaussien" +msgid "**Create a test signal**: Create > Gaussian signal" +msgstr "**Créer un signal de test** : Création > Signal gaussien" msgid "Initial parameters: amplitude=1.0, mu=50, sigma=10" msgstr "Paramètres initiaux : amplitude=1.0, mu=50, sigma=10" msgid "**Adjust creation parameters**: In the Creation tab, change sigma to 20, click Apply" -msgstr "**Ajuster les paramètres de création** : Dans l'onglet Création, changer sigma à 20, cliquer sur Appliquer" +msgstr "**Ajuster les paramètres de création** : Dans l'onglet Création, faire passer sigma à 20, cliquer sur Appliquer" msgid "Signal is regenerated with new width" msgstr "Le signal est régénéré avec une nouvelle largeur" -msgid "**Apply Gaussian filter**: Processing > Filtering > Gaussian filter" -msgstr "**Appliquer le filtre gaussien** : Traitement > Filtrage > Filtre gaussien" +msgid "**Apply Gaussian filter**: Processing > Noise reduction > Gaussian filter" +msgstr "**Appliquer le filtre gaussien** : Traitement > Réduction de bruit > Filtre gaussien" msgid "Initial sigma=2.0" msgstr "Sigma initial=2.0" @@ -203,7 +210,7 @@ msgid "**Fine-tune filtering**: In the Processing tab, try sigma=1.0, then sigma msgstr "**Ajuster le filtrage** : Dans l'onglet Traitement, essayer sigma=1.0, puis sigma=5.0" msgid "Each Apply updates the filtered result" -msgstr "Chaque application met à jour le résultat filtré" +msgstr "Chaque clic sur **Appliquer** met à jour le résultat filtré" msgid "Compare different smoothing levels without creating multiple objects" msgstr "Comparer différents niveaux de lissage sans créer plusieurs objets" diff --git a/doc/locale/fr/LC_MESSAGES/features/common/settings.po b/doc/locale/fr/LC_MESSAGES/features/common/settings.po index a3aebe305..11742014f 100644 --- a/doc/locale/fr/LC_MESSAGES/features/common/settings.po +++ b/doc/locale/fr/LC_MESSAGES/features/common/settings.po @@ -5,11 +5,18 @@ # msgid "" msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2026-08-05 14:24+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language: fr\n" +"Language-Team: fr <LL@li.org>\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.18.0\n" msgid "Settings of DataLab, the open-source scientific data analysis and visualization platform" msgstr "Préférences de DataLab, la plateforme open-source d'analyse et de visualisation de données scientifiques" @@ -168,8 +175,8 @@ msgstr "Activer le décalage FFT pour centrer la composante de fréquence nulle msgid "**Extract multiple ROIs in a single object**" msgstr "**Extraire plusieurs ROI dans un seul objet**" -msgid "When enabled, multiple ROIs (Regions of Interest) are extracted into a single object. When disabled, each ROI is extracted into a separate object." -msgstr "Si le réglage est activé, plusieurs ROI (Régions d'Intérêt) sont extraites dans un seul objet. Lorsque désactivé, chaque ROI est extraite dans un objet séparé." +msgid "When enabled, multiple regions of interest (ROIs) are extracted into a single object. When disabled, each ROI is extracted into a separate object." +msgstr "Lorsque cette option est activée, plusieurs régions d'intérêt (ROI) sont extraites dans un seul objet. Lorsqu'elle est désactivée, chaque ROI est extraite dans un objet distinct." msgid "**Ignore warnings**" msgstr "**Ignorer les avertissements**" @@ -178,10 +185,10 @@ msgid "Suppress warning messages during computations." msgstr "Supprimer les messages d'avertissement pendant les calculs." msgid "**X-array compatibility behavior**" -msgstr "**Comportement de compatibilité des tableaux X**" +msgstr "**Comportement de compatibilité des tableaux des X**" msgid "Choose the behavior when X arrays are incompatible in multi-signal computations:" -msgstr "Choisir le comportement lorsque les tableaux X sont incompatibles dans les calculs multi-signaux :" +msgstr "Choisir le comportement lorsque les tableaux des X sont incompatibles dans les calculs multi-signaux :" msgid "**Ask**: display a confirmation dialog (default)" msgstr "**Demander** : afficher une boîte de dialogue de confirmation (par défaut)" @@ -240,11 +247,8 @@ msgstr "**Démarrer une nouvelle session** : démarrer une seule session pour le msgid "**Continue in the current session** (default): append the whole batch to the active session" msgstr "**Continuer dans la session courante** (par défaut) : ajouter l'ensemble du lot à la session active" -msgid "**Ask once** is the UI label for one decision covering the complete" -msgstr "**Demander une seule fois** est le libellé de l'interface pour une décision unique couvrant l'intégralité de la" - -msgid "plugin multi-load scope, rather than one prompt per object. DataLab does not infer a multi-load scope from a sequence of plugin additions." -msgstr "portée de chargement multiple du plugin, et non pour une demande par objet. DataLab ne déduit pas une telle portée d'une suite d'ajouts effectués par un plugin." +msgid "**Ask once** is the UI label for one durable session decision covering the complete explicit plugin multi-load scope, rather than one prompt per object. With ordinary **Ask** behavior, repeated prompts for synchronous additions to the same panel are debounced during the current Qt event-loop turn." +msgstr "**Demander une seule fois** est le libellé de l'interface correspondant à une décision de session unique et durable qui couvre toute la portée explicite de chargement multiple du plugin, plutôt qu'à une demande par objet. Avec le comportement **Demander** ordinaire, un mécanisme anti-rebond évite les demandes répétées pour les ajouts synchrones au même panneau pendant le tour courant de la boucle d'événements Qt." msgid "Result management" msgstr "Gestion des résultats" From d5aa166759cb688c08b3db86def7aef1f95788dc Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Wed, 5 Aug 2026 19:07:03 +0200 Subject: [PATCH 072/108] Refactor: Unify History panel replay on the in-place recompute engine The Replay button and double-click used a separate "silent replay" engine (session-level replay with UUID remapping) that re-executed computations with outputs suppressed: results were discarded, so replaying non-stale actions had no visible effect, and deleted outputs were re-created under new UUIDs, breaking downstream references. Replay is now routed through the same in-place recompute engine as edit mode, so replayed actions update their recorded outputs directly and deleted outputs are re-created under their original UUIDs, preserving downstream pipelines. This also builds on the single active recording session model: signal and image actions are chained into one shared session instead of one active session per data panel. * [CHG] : Route Replay button and double-click through the in-place recompute engine: replay_restore_actions collects selected actions (expanding sessions) and calls replay_actions(panel, actions, prompt=edit_mode) - renamed from edit_mode_replay_actions, with prompt=False recomputing silently with captured parameters * [FIX] : Re-create deleted outputs under their recorded UUIDs during replay (new apply_output_in_place_or_recreate helper covering all five recompute patterns), so downstream actions keep resolving their sources; only actions whose source objects are gone are skipped with a warning * [FIX] : Report a cascade warning instead of crashing when replaying a compute action with no recorded pattern * [CHG] : Remove the obsolete silent replay engine: ReplayUuidMap module, HistorySession.replay, select_last_compute_output, HistoryAction.replay_compute/translate_state/replay_inner/ resolve_panel/resolve_obj_by_uuid and the uuid_remap threading; HistoryAction.replay now handles UI-kind actions only * [CHG] : Replace the per-panel active session mapping with a single HistoryNavigation.active_session: create_new_session and maybe_start_session_for_input lose their panel_str parameter, the panel-switch hook on_current_panel_changed is removed, the input prompt debounce becomes a single flag, and the tree highlights one active session (set_active_session) * [CHG] : Update tests to the new replay contract: remove silent-replay engine tests, rewrite double-click/replay workflow tests, add test_replay_recreates_deleted_output_under_recorded_uuid * [DOC] : Rewrite the History panel documentation (introduction, Replay and Step-by-step buttons, double-click behavior) and update French translations (UI catalog and documentation) --- datalab/gui/historysession_ops.py | 51 +- datalab/gui/historytools_ops.py | 11 +- datalab/gui/main.py | 10 +- datalab/gui/panel/base.py | 14 +- datalab/gui/panel/history/facade.py | 15 +- .../gui/panel/history/interactive_replay.py | 102 +-- datalab/gui/panel/history/navigation.py | 54 +- datalab/gui/panel/history/recompute.py | 279 +++++--- datalab/gui/panel/history/runtime.py | 20 +- datalab/history/action.py | 168 +---- datalab/history/replaymap.py | 234 ------- datalab/history/session.py | 69 +- datalab/locale/fr/LC_MESSAGES/datalab.po | 280 ++++---- .../common/history_model_unit_test.py | 319 +++------ .../features/common/history_panel_test.py | 24 +- .../features/common/history_test_helpers.py | 40 +- .../features/common/history_workflow_test.py | 221 +++--- .../plugin_history_policy_unit_test.py | 23 +- datalab/widgets/historytree.py | 26 +- doc/features/common/historypanel.rst | 54 +- .../fr/LC_MESSAGES/features/advanced/proxy.po | 180 ++++- .../features/common/historypanel.po | 629 +++++++++++++++--- doc/locale/fr/LC_MESSAGES/requirements.po | 40 +- 23 files changed, 1425 insertions(+), 1438 deletions(-) delete mode 100644 datalab/history/replaymap.py diff --git a/datalab/gui/historysession_ops.py b/datalab/gui/historysession_ops.py index 2f123ae53..b0994bc21 100644 --- a/datalab/gui/historysession_ops.py +++ b/datalab/gui/historysession_ops.py @@ -23,23 +23,16 @@ SESSION_BEHAVIORS: tuple[SessionBehavior, ...] = ("ask", "yes", "no") -def create_new_session( - panel: HistoryPanel, panel_str: str | None = None -) -> HistorySession: - """Create a new history session and make it active for its panel. - - Args: - panel_str: Panel the new session belongs to ("signal"/"image"). - Defaults to the current data panel. +def create_new_session(panel: HistoryPanel) -> HistorySession: + """Create a new history session and make it the active recording session. Returns: The newly created session. """ - pstr = panel_str or panel.navigation.current_panel_str() panel.navigation.session_increment += 1 session = HistorySession(number=panel.navigation.session_increment) panel.history_sessions.append(session) - panel.navigation.set_active_session(session, pstr) + panel.navigation.set_active_session(session) panel.tree.populate_tree(panel.history_sessions) panel.refresh_compatibility_items() return session @@ -53,21 +46,18 @@ def start_new_session_after_workspace_reset(panel: HistoryPanel) -> None: def maybe_start_session_for_input( panel: HistoryPanel, - panel_str: str | None = None, *, load: bool = False, behavior: SessionBehavior | None = None, ) -> bool: """Offer to start a new history session before a creation/load is recorded. - When the target panel's active session already contains actions, prompt the - user to start a fresh session so the new creation/load becomes the root of - a clean, self-contained pipeline. A new session is opened *before* the - action is recorded when the user accepts. + When the active recording session already contains actions, prompt the user + to start a fresh session so the new creation/load becomes the root of a + clean, self-contained pipeline. A new session is opened *before* the action + is recorded when the user accepts. Args: - panel_str: Target data panel ("signal"/"image"). Defaults to the - current data panel for backward-compatible load callers. load: True when triggered by a file/workspace load, False for an object creation. Only affects the prompt wording. behavior: Session creation policy: ask, always create ("yes"), or keep @@ -87,24 +77,23 @@ def maybe_start_session_for_input( return False if panel.runtime.execution.suppress_session_prompt: return False - target_panel_str = panel_str or panel.navigation.current_panel_str() - active_session = panel.navigation.get_active_session(target_panel_str) + active_session = panel.navigation.get_active_session() if active_session is None or not active_session.actions: return False if behavior == "no": return False if behavior == "yes": - panel.create_new_session(panel_str=target_panel_str) + panel.create_new_session() return True # Debounce: a synchronous burst of creations (plugin/macro) must prompt only # once. The guard is reset on the next event-loop turn. - if not panel.runtime.execution.start_session_input_prompt(target_panel_str): + if not panel.runtime.execution.start_session_input_prompt(): return False if execenv.unattended: # Headless runs: honor the accept_dialogs flag (default False -> "No"), # so tests can drive the behavior without a real modal dialog. if execenv.accept_dialogs: - panel.create_new_session(panel_str=target_panel_str) + panel.create_new_session() return True return False if load: @@ -118,7 +107,7 @@ def maybe_start_session_for_input( QW.QMessageBox.Yes | QW.QMessageBox.No, ) if answer == QW.QMessageBox.Yes: - panel.create_new_session(panel_str=target_panel_str) + panel.create_new_session() return True return False @@ -341,7 +330,7 @@ def add_ui_entry( # When the entry is an object creation, offer to start a fresh history # session first so the creation becomes the root of a clean pipeline. if method_name in HistoryAction.UI_CREATION_METHODS: - panel.maybe_start_session_for_input(panel_str=target_panel_str, load=False) + panel.maybe_start_session_for_input(load=False) state = WorkspaceState() if save_state: state.save(panel.mainwindow, panel_str=target_panel_str) @@ -361,17 +350,15 @@ def add_ui_entry( def add_object(panel: HistoryPanel, obj: HistoryAction) -> None: - """Add an action to the active session of its panel. + """Add an action to the single active recording session. - Routes the action to the active recording session for the action's panel - ("signal"/"image"), creating a dedicated session on first use, so signal - and image pipelines stay in separate sessions and recording resumes in the - user-selected session. + Actions from both the signal and image panels are chained into the same + active recording session, creating one on first use, so mixed-panel + pipelines stay together and recording resumes in the user-selected session. """ - pstr = obj.effective_panel_str() or panel.navigation.current_panel_str() - session = panel.navigation.get_active_session(pstr) + session = panel.navigation.get_active_session() if session is None: - session = panel.create_new_session(panel_str=pstr) + session = panel.create_new_session() session.add_action(obj) session_index = panel.history_sessions.index(session) panel.tree.rebuild_session(session_index) diff --git a/datalab/gui/historytools_ops.py b/datalab/gui/historytools_ops.py index e84c0e8a0..c97c82b6c 100644 --- a/datalab/gui/historytools_ops.py +++ b/datalab/gui/historytools_ops.py @@ -131,14 +131,19 @@ def resolve_chain_selection(panel: HistoryPanel) -> list[ChainSelectionPlan]: def collect_referenced_uuids(chains: list[ProcessingChain]) -> dict[str, set[str]]: - """Collect referenced/produced UUIDs and all captured metadata UUIDs.""" + """Collect only chain input/output UUIDs per panel. + + Collected UUIDs are the chain inputs (recorded selections), the second + operands of 2-to-1 operations (``obj2_uuids``) and the produced outputs. + Captured ``object_metadata`` UUIDs are intentionally ignored: workspace + states snapshot every object alive at record time (in both panels), so + collecting them would clone unrelated objects. + """ uuids_by_panel: dict[str, set[str]] = {} for chain in chains: for action in chain.actions: for panel_str, uuids in action.state.selection.items(): uuids_by_panel.setdefault(panel_str, set()).update(uuids) - for panel_str, metadata in action.state.object_metadata.items(): - uuids_by_panel.setdefault(panel_str, set()).update(metadata) obj2_uuids = action.kwargs.get("obj2_uuids") if obj2_uuids: panel_str = action_panel_str(action) diff --git a/datalab/gui/main.py b/datalab/gui/main.py index 68d36881b..b43b0775f 100644 --- a/datalab/gui/main.py +++ b/datalab/gui/main.py @@ -1943,12 +1943,6 @@ def __tab_index_changed(self, index: int) -> None: dock = self.docks[self.tabwidget.widget(index)] dock.raise_() self.__update_actions() - if self.historypanel is not None: - widget = self.tabwidget.widget(index) - if widget is self.signalpanel: - self.historypanel.on_current_panel_changed("signal") - elif widget is self.imagepanel: - self.historypanel.on_current_panel_changed("image") def __update_generic_menu(self, menu: QW.QMenu | None = None) -> None: """Update menu before showing up -- Generic method""" @@ -2364,9 +2358,7 @@ def add_object( panel_str = "image" else: raise TypeError(f"Unsupported object type {type(obj)}") - self.historypanel.maybe_start_session_for_input( - panel_str=panel_str, behavior=new_session_behavior - ) + self.historypanel.maybe_start_session_for_input(behavior=new_session_behavior) panel.add_object(obj, group_id, set_current) # Record a creation entry so objects added programmatically (plugins, # macros, remote control) appear in the history. ``panel.add_object`` diff --git a/datalab/gui/panel/base.py b/datalab/gui/panel/base.py index e46290abc..578afb92c 100644 --- a/datalab/gui/panel/base.py +++ b/datalab/gui/panel/base.py @@ -2385,9 +2385,9 @@ def remove_object(self, force: bool = False) -> None: if answer == QW.QMessageBox.No: return # IMPORTANT: save_state=True is required so that the selection of objects - # being deleted is captured. On replay, the captured selection (translated - # through uuid_remap) is restored before remove_object runs, ensuring that - # the correct object is removed instead of whatever is currently selected. + # being deleted is captured. On replay, the captured selection is restored + # before remove_object runs, ensuring that the correct object is removed + # instead of whatever is currently selected. self.mainwindow.historypanel.add_ui_entry( _("Remove selected objects"), target=self.PANEL_STR_ID + "panel", @@ -2693,9 +2693,7 @@ def load_from_directory(self, directory: str | None = None) -> list[TypeObj]: if not directory: return [] # Offer a fresh history session for this batch *before* loading anything. - self.mainwindow.historypanel.maybe_start_session_for_input( - panel_str=self.PANEL_STR_ID, load=True - ) + self.mainwindow.historypanel.maybe_start_session_for_input(load=True) folders = [ path for path in glob.glob(osp.join(directory, "**"), recursive=True) @@ -2774,9 +2772,7 @@ def load_from_files( else: entry_title = _('Load "%s"') % osp.basename(filenames[0]) # Offer a fresh history session for this batch *before* recording any entry. - self.mainwindow.historypanel.maybe_start_session_for_input( - panel_str=self.PANEL_STR_ID, load=True - ) + self.mainwindow.historypanel.maybe_start_session_for_input(load=True) action = self.mainwindow.historypanel.add_ui_entry( entry_title, target=self.PANEL_STR_ID + "panel", diff --git a/datalab/gui/panel/history/facade.py b/datalab/gui/panel/history/facade.py index d0b8a57c7..0b137a4f4 100644 --- a/datalab/gui/panel/history/facade.py +++ b/datalab/gui/panel/history/facade.py @@ -160,17 +160,13 @@ def recompute_cascade( """Recompute descendants of a root action in place.""" hrec.recompute_cascade(self, root_action, descendants) - def on_current_panel_changed(self, panel_str: str) -> None: - """React to a Signal/Image panel switch.""" - self.navigation.on_current_panel_changed(panel_str) - class HistoryRecordingFacadeMixin: """Expose history-session recording operations used by application code.""" - def create_new_session(self, panel_str: str | None = None) -> HistorySession: - """Create a new history session for a data panel.""" - return hsess.create_new_session(self, panel_str=panel_str) + def create_new_session(self) -> HistorySession: + """Create a new history session and make it active.""" + return hsess.create_new_session(self) def start_new_session_after_workspace_reset(self) -> None: """Start a history session after a workspace reset when useful.""" @@ -178,15 +174,12 @@ def start_new_session_after_workspace_reset(self) -> None: def maybe_start_session_for_input( self, - panel_str: str | None = None, *, load: bool = False, behavior: hsess.SessionBehavior | None = None, ) -> bool: """Offer to start a new session before recording an input.""" - return hsess.maybe_start_session_for_input( - self, panel_str=panel_str, load=load, behavior=behavior - ) + return hsess.maybe_start_session_for_input(self, load=load, behavior=behavior) @contextmanager def session_prompt_suppressed(self) -> Generator[None, None, None]: diff --git a/datalab/gui/panel/history/interactive_replay.py b/datalab/gui/panel/history/interactive_replay.py index 1477eff4f..1a0d1c0cf 100644 --- a/datalab/gui/panel/history/interactive_replay.py +++ b/datalab/gui/panel/history/interactive_replay.py @@ -5,7 +5,6 @@ from __future__ import annotations import copy -import logging from dataclasses import dataclass from typing import TYPE_CHECKING, Any @@ -22,8 +21,6 @@ if TYPE_CHECKING: from datalab.gui.panel.history.panel import HistoryPanel -_logger = logging.getLogger(__name__) - @dataclass class ActionParamEdit: @@ -44,16 +41,8 @@ def replay_restore_actions( return selected = [panel.history_sessions[-1]] edit_mode = panel.runtime.execution.edit_mode - edit_actions: list[HistoryAction] = [] + actions_to_replay: list[HistoryAction] = [] for session_or_action in selected: - if ( - replay - and not edit_mode - and isinstance(session_or_action, HistoryAction) - and session_or_action.is_stale - ): - hrec.recompute_cascade(panel, session_or_action) - continue if not session_or_action.is_current_state_compatible( panel.mainwindow, restore_selection=restore_selection ): @@ -65,18 +54,10 @@ def replay_restore_actions( ) return if replay: - if edit_mode: - if isinstance(session_or_action, HistorySession): - edit_actions.extend(session_or_action.actions) - else: - edit_actions.append(session_or_action) + if isinstance(session_or_action, HistorySession): + actions_to_replay.extend(session_or_action.actions) else: - with panel.replaying(), panel.output_suppressed(): - session_or_action.replay( - panel.mainwindow, - restore_selection=restore_selection, - edit=edit_mode, - ) + actions_to_replay.append(session_or_action) elif restore_selection: if edit_mode or any( action.has_pending_edits @@ -86,8 +67,8 @@ def replay_restore_actions( restore_action_params(panel, session_or_action) else: session_or_action.restore(panel.mainwindow) - if edit_actions: - edit_mode_replay_actions(panel, edit_actions) + if actions_to_replay: + replay_actions(panel, actions_to_replay, prompt=edit_mode) def prepare_action_param_edit(action: HistoryAction) -> ActionParamEdit | None: @@ -129,14 +110,23 @@ def prompt_edit_action_params( return True -def edit_mode_replay_actions(panel: HistoryPanel, actions: list[HistoryAction]) -> None: - """Edit selected actions and recompute their affected branches once. +def replay_actions( + panel: HistoryPanel, actions: list[HistoryAction], prompt: bool = True +) -> None: + """Replay selected actions through the in-place recompute engine. + + When ``prompt`` is enabled, each selected action gets exactly one + parameter dialog. Recomputable selected actions are always included, + while accepted parameter edits also include all downstream dependent + actions. When ``prompt`` is disabled, actions are recomputed silently + with their current parameters (no dialogs anywhere). The resulting + global plan is deduplicated and executed in session order. A re-entrance + guard prevents nested prompt loops. - Each selected action gets exactly one parameter dialog. Recomputable - selected actions are always included, while accepted parameter edits also - include all downstream dependent actions. The resulting global plan is - deduplicated and executed in session order. A re-entrance guard prevents - nested prompt loops. + Args: + panel: History panel instance + actions: Selected actions to replay + prompt: Open parameter dialogs before recomputing """ # Deduplicate and sort the selected actions in their session order ordered = order_selected_actions(panel, actions) @@ -145,13 +135,17 @@ def edit_mode_replay_actions(panel: HistoryPanel, actions: list[HistoryAction]) with panel.runtime.execution.replaying_edits() as started: if not started: return - entry_states = { - action.uuid: ( - copy_history_value(action.kwargs), - copy_history_value(action.saved_kwargs), - ) - for action in ordered - } + entry_states = ( + { + action.uuid: ( + copy_history_value(action.kwargs), + copy_history_value(action.saved_kwargs), + ) + for action in ordered + } + if prompt + else {} + ) edited_actions: list[HistoryAction] = [] recomputable: list[HistoryAction] = [] deferred_actions: list[HistoryAction] = [] @@ -163,19 +157,27 @@ def edit_mode_replay_actions(panel: HistoryPanel, actions: list[HistoryAction]) is_compute = ( action.kind == HistoryAction.KIND_COMPUTE and action.pattern is not None ) + if action.kind == HistoryAction.KIND_COMPUTE and not is_compute: + name = action.func_name or action.title or action.uuid + panel.runtime.execution.cascade_warnings.append( + _("Action %s has no recorded pattern and cannot be replayed.") + % name + ) + continue if not is_creation and not is_compute: deferred_actions.append(action) continue - result = prompt_edit_action_params(panel, action) - if result is False: - for selected_action in ordered: - kwargs, saved_kwargs = entry_states[selected_action.uuid] - selected_action.kwargs = kwargs - selected_action.saved_kwargs = saved_kwargs - panel.tree.refresh_action_item(selected_action) - return - if result is True: - edited_actions.append(action) + if prompt: + result = prompt_edit_action_params(panel, action) + if result is False: + for selected_action in ordered: + kwargs, saved_kwargs = entry_states[selected_action.uuid] + selected_action.kwargs = kwargs + selected_action.saved_kwargs = saved_kwargs + panel.tree.refresh_action_item(selected_action) + return + if result is True: + edited_actions.append(action) recomputable.append(action) for action in edited_actions: @@ -195,7 +197,7 @@ def edit_mode_replay_actions(panel: HistoryPanel, actions: list[HistoryAction]) if action in deferred_actions: with panel.replaying(), panel.output_suppressed(): action.replay( - panel.mainwindow, restore_selection=True, edit=True + panel.mainwindow, restore_selection=True, edit=prompt ) continue if hchain.action_consumes_any(action, blocked_outputs): diff --git a/datalab/gui/panel/history/navigation.py b/datalab/gui/panel/history/navigation.py index 6777fc735..ad4e7d683 100644 --- a/datalab/gui/panel/history/navigation.py +++ b/datalab/gui/panel/history/navigation.py @@ -22,7 +22,7 @@ class HistoryNavigation: def __init__(self, panel: HistoryPanel) -> None: self.panel = panel self.syncing = False - self.active_session_by_panel: dict[str, HistorySession] = {} + self.active_session: HistorySession | None = None self.session_increment = 0 def current_action(self) -> HistoryAction | None: @@ -93,41 +93,23 @@ def update_state_widget(self) -> None: action.state if action is not None else None ) - def session_panel_str(self, session: HistorySession) -> str | None: - """Return the data panel to which a session belongs.""" - for action in session.actions: - panel_str = action.effective_panel_str() - if panel_str: - return panel_str - for panel_str, active_session in self.active_session_by_panel.items(): - if active_session is session: - return panel_str - return None - - def get_active_session(self, panel_str: str) -> HistorySession | None: - """Return the valid active recording session for a data panel.""" - session = self.active_session_by_panel.get(panel_str) + def get_active_session(self) -> HistorySession | None: + """Return the valid active recording session.""" + session = self.active_session if session is not None and session in self.panel.history_sessions: return session return None - def set_active_session( - self, session: HistorySession, panel_str: str | None = None - ) -> None: - """Mark a session as active for its data panel.""" - target = panel_str or self.session_panel_str(session) - if target: - self.active_session_by_panel[target] = session - self.refresh_active_session_highlight() + def set_active_session(self, session: HistorySession) -> None: + """Mark a session as the single active recording session.""" + self.active_session = session + self.refresh_active_session_highlight() def refresh_active_session_highlight(self) -> None: - """Highlight each data panel's active session in the tree.""" - active = { - session.number: panel_str - for panel_str, session in self.active_session_by_panel.items() - if session in self.panel.history_sessions - } - self.panel.tree.set_active_sessions(active) + """Highlight the active recording session in the tree.""" + session = self.get_active_session() + number = session.number if session is not None else None + self.panel.tree.set_active_session(number) def set_active_session_from_selection(self) -> None: """Make the selected session active while recording.""" @@ -151,18 +133,6 @@ def set_active_session_from_selection(self) -> None: if session is not None: self.set_active_session(session) - def on_current_panel_changed(self, panel_str: str) -> None: - """Bring the current data panel's active recording session into view.""" - if panel_str not in ("signal", "image"): - return - self.refresh_active_session_highlight() - session = self.get_active_session(panel_str) - if session is not None and session in self.panel.history_sessions: - index = self.panel.history_sessions.index(session) - item = self.panel.tree.topLevelItem(index) - if item is not None: - self.panel.tree.scrollToItem(item) - def current_session(self) -> HistorySession | None: """Return the session relevant for step navigation.""" item = self.panel.tree.currentItem() diff --git a/datalab/gui/panel/history/recompute.py b/datalab/gui/panel/history/recompute.py index 1041a514e..8683aaf8b 100644 --- a/datalab/gui/panel/history/recompute.py +++ b/datalab/gui/panel/history/recompute.py @@ -100,7 +100,12 @@ def refresh_target(panel_data: BaseDataPanel, output_uuid: str) -> None: def record_missing_outputs( panel: HistoryPanel, action: HistoryAction, missing: list[str] ) -> None: - """Log + queue a user-facing warning for deleted output objects.""" + """Log + queue a user-facing warning for deleted output objects. + + Only used for genuinely irrecoverable cases (e.g. recorded outputs that + cannot be aligned with the action's parameters); recoverable deletions + are handled by :func:`apply_output_in_place_or_recreate`. + """ if not missing: return name = action.func_name or action.title or action.uuid @@ -119,6 +124,53 @@ def record_missing_outputs( ) +def apply_output_in_place_or_recreate( + panel: HistoryPanel, + panel_data: BaseDataPanel, + action: HistoryAction, + out_uuid: str, + new_obj: SignalObj | ImageObj, + pparams: ProcessingParameters | None = None, + group_id: str | None = None, +) -> None: + """Update the recorded output in place, re-creating it if it was deleted. + + When the recorded output object no longer exists in ``panel_data``, the + freshly computed ``new_obj`` is inserted back **under its original + recorded UUID** so that downstream references (``source_uuid`` / + ``source_uuids`` metadata and ``action.output_uuids``) remain valid + without any remapping. The runtime action→outputs mapping (pruned when + the object was deleted) is re-registered. + + This only commits the data: callers are responsible for calling + :func:`refresh_target` once all outputs have been committed. + + Args: + panel: History panel instance. + panel_data: Data panel that owns (or owned) the output object. + action: History action that produced the output. + out_uuid: Recorded UUID of the output object. + new_obj: Freshly recomputed object providing title, data and metadata. + pparams: Processing parameters to store on the output, or ``None``. + group_id: Group for a re-created output (``None`` = default group). + """ + if panel_data.objmodel.has_uuid(out_uuid): + target_obj = panel_data.objmodel[out_uuid] + update_obj_in_place(target_obj, new_obj) + else: + new_obj.set_metadata_option("uuid", out_uuid) + # The ``replaying()`` guard suppresses history capture and session + # prompts while the deleted output is re-inserted in the data panel. + with panel.replaying(): + panel_data.add_object(new_obj, group_id=group_id, set_current=False) + target_obj = panel_data.objmodel[out_uuid] + panel.runtime.objects.register_action_outputs( + action, hchain.recorded_action_output_uuids(panel, action) + ) + if pparams is not None: + insert_processing_parameters(target_obj, pparams) + + def recompute_action_in_place(panel: HistoryPanel, action: HistoryAction) -> bool: """Re-run ``action`` on the existing output object(s) (same UUIDs).""" if ( @@ -211,18 +263,16 @@ def recompute_creation_in_place(panel: HistoryPanel, action: HistoryAction) -> b Rebuild the object from the edited ``param`` and copy it onto the existing output object so its UUID (and downstream references) are kept. + If the output object was deleted, it is re-created under its recorded + UUID so the downstream chain remains valid. """ panel_data = hchain.resolve_panel_for_action(panel, action) if panel_data is None: return False - existing, missing = hchain.resolve_target_outputs(panel, panel_data, action) - record_missing_outputs(panel, action, missing) - if missing or not existing: - return False - output_uuid = existing[0] - if not panel_data.objmodel.has_uuid(output_uuid): + recorded = hchain.recorded_action_output_uuids(panel, action) + if not recorded: return False - output_obj = panel_data.objmodel[output_uuid] + output_uuid = recorded[0] param = action.kwargs.get("param") if param is None: return False @@ -233,41 +283,48 @@ def recompute_creation_in_place(panel: HistoryPanel, action: HistoryAction) -> b new_obj = create_signal_from_param(prepared) else: new_obj = create_image_from_param(param) - update_obj_in_place(output_obj, new_obj) - insert_creation_parameters(output_obj, param) + # Creation parameters are carried by ``new_obj`` so both the in-place + # update (metadata copy) and the recreation path preserve them. + insert_creation_parameters(new_obj, param) + apply_output_in_place_or_recreate(panel, panel_data, action, output_uuid, new_obj) refresh_target(panel_data, output_uuid) return True def recompute_1_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> bool: - """Recompute a single 1-to-1 action in place.""" + """Recompute a single 1-to-1 action in place. + + If the output object was deleted, it is re-created under its recorded + UUID; the source is then resolved from the action's captured state. + """ panel_data = hchain.resolve_panel_for_action(panel, action) if panel_data is None: return False - existing, missing = hchain.resolve_target_outputs(panel, panel_data, action) - if not existing and not missing: - legacy = hchain.find_output_object_uuid(panel, panel_data, action) - if legacy is not None: - existing = [legacy] - record_missing_outputs(panel, action, missing) - if missing or not existing: - return False - output_uuid = existing[0] - if not panel_data.objmodel.has_uuid(output_uuid): - return False - output_obj = panel_data.objmodel[output_uuid] - pp = extract_processing_parameters(output_obj) - if pp is None or pp.source_uuid is None: + recorded = hchain.recorded_action_output_uuids(panel, action) + if not recorded: return False - if not panel_data.objmodel.has_uuid(pp.source_uuid): + output_uuid = recorded[0] + output_obj = ( + panel_data.objmodel[output_uuid] + if panel_data.objmodel.has_uuid(output_uuid) + else None + ) + pp = extract_processing_parameters(output_obj) if output_obj is not None else None + source_uuid = pp.source_uuid if pp is not None and pp.source_uuid else None + if source_uuid is None: + selection = action.state.selection.get(panel_data.PANEL_STR_ID, []) + source_uuid = selection[0] if selection else None + if source_uuid is None: + return False + if not panel_data.objmodel.has_uuid(source_uuid): panel.runtime.execution.cascade_warnings.append( _("Action %s: source object was deleted — skipping.") % (action.func_name or action.uuid) ) return False - source_obj = panel_data.objmodel[pp.source_uuid] + source_obj = panel_data.objmodel[source_uuid] param = action.kwargs.get("param") - plugin_origin = action.plugin_origin or pp.plugin_origin + plugin_origin = action.plugin_origin or (pp.plugin_origin if pp else None) compout = panel_data.processor.recompute_1_to_1( action.func_name, source_obj, @@ -285,45 +342,72 @@ def recompute_1_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> boo new_obj = compout.result if not isinstance(new_obj, (SignalObj, ImageObj)): return False - panel_data.objprop.apply_recomputed_object_in_place( - output_obj, - new_obj, - ProcessingParameters( - func_name=pp.func_name, - pattern=pp.pattern, - param=param if param is not None else pp.param, - source_uuid=pp.source_uuid, - plugin_origin=plugin_origin, - ), + pp_new = ProcessingParameters( + func_name=pp.func_name if pp is not None else action.func_name, + pattern=pp.pattern if pp is not None else "1-to-1", + param=param if param is not None else (pp.param if pp is not None else None), + source_uuid=source_uuid, + plugin_origin=plugin_origin, ) + if output_obj is not None: + # Preserve the existing output's own metadata (ROIs, annotations...) + panel_data.objprop.apply_recomputed_object_in_place(output_obj, new_obj, pp_new) + else: + apply_output_in_place_or_recreate( + panel, + panel_data, + action, + output_uuid, + new_obj, + pp_new, + group_id=panel_data.objmodel.get_object_group_id(source_obj), + ) refresh_target(panel_data, output_uuid) return True def recompute_1_to_n_in_place(panel: HistoryPanel, action: HistoryAction) -> bool: - """Recompute a 1-to-n action in place: replace each of the N outputs.""" + """Recompute a 1-to-n action in place: replace each of the N outputs. + + Deleted outputs are re-created under their recorded UUIDs; indices of + ``action.output_uuids`` align with the recorded ``params`` list. + """ panel_data = hchain.resolve_panel_for_action(panel, action) if panel_data is None: return False - existing, missing = hchain.resolve_target_outputs(panel, panel_data, action) - record_missing_outputs(panel, action, missing) - if missing or not existing or not panel_data.objmodel.has_uuid(existing[0]): + params = action.kwargs.get("params") or [] + recorded = hchain.recorded_action_output_uuids(panel, action) + if not recorded or not params: + return False + if len(recorded) != len(params): + # Legacy or inconsistent recording: outputs cannot be aligned with + # the parameter list, so recreation is impossible. + record_missing_outputs( + panel, + action, + [u for u in recorded if not panel_data.objmodel.has_uuid(u)], + ) return False - first_obj = panel_data.objmodel[existing[0]] - pp = extract_processing_parameters(first_obj) - if pp is None or pp.source_uuid is None: + existing = [u for u in recorded if panel_data.objmodel.has_uuid(u)] + pp = ( + extract_processing_parameters(panel_data.objmodel[existing[0]]) + if existing + else None + ) + source_uuid = pp.source_uuid if pp is not None and pp.source_uuid else None + if source_uuid is None: + selection = action.state.selection.get(panel_data.PANEL_STR_ID, []) + source_uuid = selection[0] if selection else None + if source_uuid is None: return False - if not panel_data.objmodel.has_uuid(pp.source_uuid): + if not panel_data.objmodel.has_uuid(source_uuid): panel.runtime.execution.cascade_warnings.append( _("Action %s: source object was deleted — skipping.") % (action.func_name or action.uuid) ) return False - source_obj = panel_data.objmodel[pp.source_uuid] - params = action.kwargs.get("params") or [] - if not params: - return False - plugin_origin = action.plugin_origin or pp.plugin_origin + source_obj = panel_data.objmodel[source_uuid] + plugin_origin = action.plugin_origin or (pp.plugin_origin if pp else None) new_objs = panel_data.processor.recompute_1_to_n( action.func_name, source_obj, @@ -332,38 +416,42 @@ def recompute_1_to_n_in_place(panel: HistoryPanel, action: HistoryAction) -> boo ) if not new_objs: return False - if len(new_objs) != len(existing) or not all( + if len(new_objs) != len(recorded) or not all( isinstance(obj, (SignalObj, ImageObj)) for obj in new_objs ): _logger.warning( - "1-to-n cardinality changed for action %s: %d outputs, %d existing.", + "1-to-n cardinality changed for action %s: %d outputs, %d recorded.", action.uuid, len(new_objs), - len(existing), + len(recorded), ) panel.runtime.execution.cascade_warnings.append( _("Action %s: recompute returned %d output(s), expected %d.") - % (action.func_name or action.uuid, len(new_objs), len(existing)) + % (action.func_name or action.uuid, len(new_objs), len(recorded)) ) return False + group_id = panel_data.objmodel.get_object_group_id(source_obj) snapshots = { out_uuid: copy.deepcopy(panel_data.objmodel[out_uuid]) for out_uuid in existing } try: - for idx, out_uuid in enumerate(existing): - out_obj = panel_data.objmodel[out_uuid] - update_obj_in_place(out_obj, new_objs[idx]) - insert_processing_parameters( - out_obj, + for idx, out_uuid in enumerate(recorded): + apply_output_in_place_or_recreate( + panel, + panel_data, + action, + out_uuid, + new_objs[idx], ProcessingParameters( func_name=action.func_name, pattern="1-to-n", param=params[idx], - source_uuid=pp.source_uuid, + source_uuid=source_uuid, plugin_origin=plugin_origin, ), + group_id=group_id, ) - for out_uuid in existing: + for out_uuid in recorded: refresh_target(panel_data, out_uuid) except Exception: for out_uuid, snapshot in snapshots.items(): @@ -381,19 +469,24 @@ def recompute_1_to_n_in_place(panel: HistoryPanel, action: HistoryAction) -> boo def recompute_n_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> bool: - """Recompute an n-to-1 action in place.""" + """Recompute an n-to-1 action in place. + + If the output object was deleted, it is re-created under its recorded + UUID; sources are then resolved from the action's captured state. + """ panel_data = hchain.resolve_panel_for_action(panel, action) if panel_data is None: return False - existing, missing = hchain.resolve_target_outputs(panel, panel_data, action) - record_missing_outputs(panel, action, missing) - if missing or not existing: - return False - output_uuid = existing[0] - if not panel_data.objmodel.has_uuid(output_uuid): + recorded = hchain.recorded_action_output_uuids(panel, action) + if not recorded: return False - output_obj = panel_data.objmodel[output_uuid] - pp = extract_processing_parameters(output_obj) + output_uuid = recorded[0] + output_obj = ( + panel_data.objmodel[output_uuid] + if panel_data.objmodel.has_uuid(output_uuid) + else None + ) + pp = extract_processing_parameters(output_obj) if output_obj is not None else None source_uuids: list[str] = [] if pp is not None and pp.source_uuids: source_uuids = list(pp.source_uuids) @@ -418,9 +511,12 @@ def recompute_n_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> boo ) if not isinstance(new_obj, (SignalObj, ImageObj)): return False - update_obj_in_place(output_obj, new_obj) - insert_processing_parameters( - output_obj, + apply_output_in_place_or_recreate( + panel, + panel_data, + action, + output_uuid, + new_obj, ProcessingParameters( func_name=action.func_name, pattern="n-to-1", @@ -428,19 +524,24 @@ def recompute_n_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> boo source_uuids=[get_uuid(o) for o in src_objs], plugin_origin=plugin_origin, ), + group_id=panel_data.objmodel.get_object_group_id(src_objs[0]), ) refresh_target(panel_data, output_uuid) return True def recompute_2_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> bool: - """Recompute a 2-to-1 action in place (single or pairwise).""" + """Recompute a 2-to-1 action in place (single or pairwise). + + Deleted outputs are re-created under their recorded UUIDs; sources are + then resolved from the action's captured inputs (indices of + ``action.output_uuids`` align with the recorded input/operand lists). + """ panel_data = hchain.resolve_panel_for_action(panel, action) if panel_data is None: return False - existing, missing = hchain.resolve_target_outputs(panel, panel_data, action) - record_missing_outputs(panel, action, missing) - if missing or not existing: + recorded = hchain.recorded_action_output_uuids(panel, action) + if not recorded: return False param = action.kwargs.get("param") obj2_uuids = action.kwargs.get("obj2_uuids") or [] @@ -456,10 +557,12 @@ def recompute_2_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> boo dict | None, ] ] = [] - for idx, out_uuid in enumerate(existing): - if not panel_data.objmodel.has_uuid(out_uuid): - return False - pp = extract_processing_parameters(panel_data.objmodel[out_uuid]) + for idx, out_uuid in enumerate(recorded): + pp = ( + extract_processing_parameters(panel_data.objmodel[out_uuid]) + if panel_data.objmodel.has_uuid(out_uuid) + else None + ) src_uuids = ( list(pp.source_uuids) if pp is not None and pp.source_uuids @@ -528,13 +631,16 @@ def recompute_2_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> boo snapshots = { out_uuid: copy.deepcopy(panel_data.objmodel[out_uuid]) for out_uuid, *_rest in staged + if panel_data.objmodel.has_uuid(out_uuid) } try: for out_uuid, new_obj, obj1, obj2, plugin_origin in staged: - output_obj = panel_data.objmodel[out_uuid] - update_obj_in_place(output_obj, new_obj) - insert_processing_parameters( - output_obj, + apply_output_in_place_or_recreate( + panel, + panel_data, + action, + out_uuid, + new_obj, ProcessingParameters( func_name=action.func_name, pattern="2-to-1", @@ -542,6 +648,7 @@ def recompute_2_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> boo source_uuids=[get_uuid(obj1), get_uuid(obj2)], plugin_origin=plugin_origin, ), + group_id=panel_data.objmodel.get_object_group_id(obj1), ) for out_uuid, *_rest in staged: refresh_target(panel_data, out_uuid) diff --git a/datalab/gui/panel/history/runtime.py b/datalab/gui/panel/history/runtime.py index e026e40c8..253657f73 100644 --- a/datalab/gui/panel/history/runtime.py +++ b/datalab/gui/panel/history/runtime.py @@ -22,7 +22,7 @@ class HistoryExecutionState: def __init__(self) -> None: self.record_mode = False self.edit_mode = False - self.session_input_pending_panels: set[str] = set() + self.session_input_pending = False self.suppress_session_prompt = False self.replaying_active = False self.output_suppressed_active = False @@ -61,19 +61,17 @@ def session_prompt_suppressed(self) -> Generator[None, None, None]: finally: self.suppress_session_prompt = previous - def start_session_input_prompt(self, panel_str: str) -> bool: - """Start the input prompt debounce window for a data panel.""" - if panel_str in self.session_input_pending_panels: + def start_session_input_prompt(self) -> bool: + """Start the input prompt debounce window.""" + if self.session_input_pending: return False - self.session_input_pending_panels.add(panel_str) - QC.QTimer.singleShot( - 0, functools.partial(self.finish_session_input_prompt, panel_str) - ) + self.session_input_pending = True + QC.QTimer.singleShot(0, self.finish_session_input_prompt) return True - def finish_session_input_prompt(self, panel_str: str) -> None: - """End the input prompt debounce window for a data panel.""" - self.session_input_pending_panels.discard(panel_str) + def finish_session_input_prompt(self) -> None: + """End the input prompt debounce window.""" + self.session_input_pending = False @contextmanager def recomputing_cascade(self) -> Generator[bool, None, None]: diff --git a/datalab/history/action.py b/datalab/history/action.py index 47e6ea0cc..42a33c4bf 100644 --- a/datalab/history/action.py +++ b/datalab/history/action.py @@ -28,7 +28,6 @@ import sigima.proc.signal from guidata.dataset.datatypes import DataSet -from datalab.config import _ from datalab.gui import ObjItf from datalab.history.core import ( HISTORY_ACTION_SCHEMA_VERSION, @@ -434,16 +433,6 @@ def resolve_target(self, mainwindow: DLMainWindow) -> Any: return mainwindow.imagepanel.processor return getattr(mainwindow, attr) - def resolve_panel(self, mainwindow: DLMainWindow): - """Resolve the data panel for a compute action.""" - if self.panel_str == "signal": - return mainwindow.signalpanel - if self.panel_str == "image": - return mainwindow.imagepanel - raise ValueError( - f"Unknown panel_str {self.panel_str!r} for compute history action" - ) - def resolve_callable(self) -> Callable | None: """Best-effort lookup of the underlying callable, for description only.""" if self.kind == self.KIND_COMPUTE and self.func_name: @@ -453,41 +442,34 @@ def resolve_callable(self) -> Callable | None: return func return None - def resolve_obj_by_uuid(self, mainwindow: DLMainWindow, uuid: str) -> Any | None: - """Look up an object by UUID across both data panels.""" - for panel in (mainwindow.signalpanel, mainwindow.imagepanel): - try: - return panel.objmodel[uuid] - except KeyError: - continue - return None - def replay( self, mainwindow: DLMainWindow, restore_selection: bool, edit: bool, - uuid_remap: dict[str, dict[str, str]] | None = None, ) -> None: - """Replay the action. + """Replay a UI-kind action. + + Compute-kind actions are recomputed in place by the History panel + engine (see :mod:`datalab.gui.panel.history.recompute`) and must never + reach this method. Args: mainwindow: DataLab's main window - restore_selection: True to restore the workspace selection before replaying - a UI-kind action. Compute-kind actions restore their captured - selection only when its translated UUIDs remain compatible and - resolvable; otherwise they retain the current selection. + restore_selection: True to restore the captured workspace selection + before replaying the action. edit: If True, request a parameter dialog for supported actions with editable parameters. If False, use the captured parameters. - uuid_remap: optional per-panel mapping ``{panel_str: {old_uuid: new_uuid}}`` - used during full-session replay to translate captured state UUIDs, - compute operand UUIDs, and supported UI source UUIDs. Defaults to - an empty (identity) mapping. + + Raises: + NotImplementedError: If called on a compute-kind action. """ - if uuid_remap is None: - uuid_remap = {} + if self.kind == self.KIND_COMPUTE: + raise NotImplementedError( + "Compute actions are recomputed in place and cannot be replayed." + ) # Suppress history capture during replay to avoid recording - # synthetic entries when the processor re-executes features. + # synthetic entries when the target re-executes features. # The context manager is reentrant, so nesting with # HistoryPanel.replay_restore_actions() is safe. hpanel = getattr(mainwindow, "historypanel", None) @@ -496,125 +478,14 @@ def replay( else: ctx = nullcontext() with ctx: - self.replay_inner(mainwindow, restore_selection, edit, uuid_remap) - - def replay_inner( - self, - mainwindow: DLMainWindow, - restore_selection: bool, - edit: bool, - uuid_remap: dict[str, dict[str, str]], - ) -> None: - """Inner replay logic, always called under the replaying guard.""" - if self.kind == self.KIND_COMPUTE and self.pattern == "1_to_0" and not edit: - return - if self.kind == self.KIND_COMPUTE: - # Compute actions are selection-driven: restore the captured - # selection (translated through ``uuid_remap`` for session - # replays) whenever it is still resolvable so chained replays - # (especially ``n_to_1`` / ``2_to_1`` / ``1_to_n`` patterns) - # operate on the original input objects rather than on whatever - # the previous action left selected. When the captured UUIDs no - # longer exist (e.g. heuristic remap missed an object), fall - # back to the current selection -- replay may still fail - # downstream, but with the native processor error rather than - # an opaque ``WorkspaceState`` incompatibility. - translated = self.translate_state(uuid_remap) - if translated.is_current_state_compatible(mainwindow, False): - translated.restore(mainwindow) - self.replay_compute(mainwindow, edit, uuid_remap) - else: if restore_selection: self.state.restore(mainwindow) - self.replay_ui(mainwindow, edit, uuid_remap) - - def translate_state(self, uuid_remap: dict[str, dict[str, str]]) -> WorkspaceState: - """Return ``self.state`` with captured UUIDs translated. - - The original state is returned when no mapping is provided; otherwise a - translated copy is returned. - """ - if not uuid_remap: - return self.state - translated = WorkspaceState() - for panel_str, uuids in self.state.selection.items(): - panel_map = uuid_remap.get(panel_str, {}) - translated.selection[panel_str] = [panel_map.get(u, u) for u in uuids] - translated.states = dict(self.state.states) - translated.titles = dict(self.state.titles) - for panel_str, metadata in self.state.object_metadata.items(): - panel_map = uuid_remap.get(panel_str, {}) - translated.object_metadata[panel_str] = { - panel_map.get(uuid, uuid): dict(signature) - for uuid, signature in metadata.items() - } - return translated - - def replay_compute( - self, - mainwindow: DLMainWindow, - edit: bool, - uuid_remap: dict[str, dict[str, str]] | None = None, - ) -> None: - """Replay a compute-kind action via ``processor.run_feature``.""" - if self.pattern == "multiple_1_to_1": - raise NotImplementedError( - _("Replaying compound 'multiple_1_to_1' actions is not supported yet.") - ) - panel = self.resolve_panel(mainwindow) - processor = panel.processor - param = self.kwargs.get("param") - params = self.kwargs.get("params") or [] - paramclass_name = type(param).__name__ if param is not None else None - if self.pattern == "1_to_n" and params: - paramclass_name = type(params[0]).__name__ - feature = processor.get_feature( - self.func_name, - plugin_origin=self.plugin_origin, - paramclass_name=paramclass_name, - ) - run_kwargs: dict[str, Any] = {self.FUNC_EDIT_MODE: edit} - - if self.pattern in {"1_to_1", "1_to_0", "n_to_1"}: - if param is not None: - run_kwargs["param"] = param - if self.pattern == "n_to_1" and "pairwise" in self.kwargs: - run_kwargs["pairwise"] = self.kwargs["pairwise"] - elif self.pattern == "2_to_1": - uuids = self.kwargs.get("obj2_uuids") or [] - if isinstance(uuids, str): - uuids = [uuids] - # Translate captured UUIDs through ``uuid_remap`` (session replay). - # ``uuid_remap`` keys are ``panel.PANEL_STR_ID`` (matches - # ``WorkspaceState.selection`` keys and - # ``HistoryAction.panel_str``). - panel_map = (uuid_remap or {}).get(panel.PANEL_STR_ID, {}) - uuids = [panel_map.get(u, u) for u in uuids] - objs2 = [ - obj - for obj in (self.resolve_obj_by_uuid(mainwindow, u) for u in uuids) - if obj is not None - ] - if not objs2: - raise ValueError( - _("Cannot replay 2-to-1 action: source object(s) missing.") - ) - run_kwargs["obj2"] = objs2[0] if len(objs2) == 1 else objs2 - if param is not None: - run_kwargs["param"] = param - if "pairwise" in self.kwargs: - run_kwargs["pairwise"] = self.kwargs["pairwise"] - elif self.pattern == "1_to_n": - run_kwargs["params"] = params - else: - raise ValueError(f"Unknown compute pattern: {self.pattern!r}") - processor.run_feature(feature, **run_kwargs) + self.replay_ui(mainwindow, edit) def replay_ui( self, mainwindow: DLMainWindow, edit: bool, - uuid_remap: dict[str, dict[str, str]] | None = None, ) -> None: """Replay a UI-kind action by calling ``target.method_name(**kwargs)``.""" hpanel = mainwindow.historypanel @@ -656,13 +527,6 @@ def replay_ui( return method = getattr(target, self.method_name) call_kwargs = dict(self.kwargs) - # Translate a recorded source object UUID through the session uuid_remap - # so deterministic replay after save/reload still targets the right object. - pstr = self.effective_panel_str() - if uuid_remap and pstr and "source_uuid" in call_kwargs: - panel_map = uuid_remap.get(pstr, {}) - old = call_kwargs["source_uuid"] - call_kwargs["source_uuid"] = panel_map.get(old, old) # Inject edit mode if the method supports it try: sig = inspect.signature(method) diff --git a/datalab/history/replaymap.py b/datalab/history/replaymap.py deleted file mode 100644 index 7d908d4ee..000000000 --- a/datalab/history/replaymap.py +++ /dev/null @@ -1,234 +0,0 @@ -# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. - -"""UUID reconciliation for history session replay.""" - -from __future__ import annotations - -from typing import TYPE_CHECKING - -from datalab.history.action import HistoryAction - -if TYPE_CHECKING: - from datalab.gui.panel.base import BaseDataPanel - - -class ReplayUuidMap: - """Reconcile recorded object UUIDs with objects created during replay. - - Args: - panels: Data panels participating in the replay - """ - - def __init__(self, panels: tuple[BaseDataPanel, ...]) -> None: - """Initialize an empty per-panel UUID reconciliation map.""" - self.panels = {panel.PANEL_STR_ID: panel for panel in panels} - self.mapping: dict[str, dict[str, str]] = { - panel_str: {} for panel_str in self.panels - } - self.unclaimed: dict[str, list[str]] = { - panel_str: [] for panel_str in self.panels - } - - def translate_uuid(self, panel_str: str, uuid: str) -> str: - """Translate a recorded UUID to its replay UUID.""" - return self.mapping.get(panel_str, {}).get(uuid, uuid) - - def snapshot_object_ids(self) -> dict[str, set[str]]: - """Return the current object UUIDs for every replay panel.""" - return { - panel_str: set(panel.objmodel.get_object_ids()) - for panel_str, panel in self.panels.items() - } - - def claim_action_inputs(self, action: HistoryAction) -> None: - """Claim replay objects corresponding to a compute action's inputs.""" - if action.kind != HistoryAction.KIND_COMPUTE: - return - panel_str = action.panel_str or "" - recorded_uuids = list(action.state.selection.get(panel_str, [])) - if action.pattern == "2_to_1": - second_uuids = action.kwargs.get("obj2_uuids") or [] - if isinstance(second_uuids, str): - second_uuids = [second_uuids] - recorded_uuids = list(second_uuids) + recorded_uuids - self.claim_inputs(panel_str, recorded_uuids, action) - - def claim_inputs( - self, panel_str: str, recorded_uuids: list[str], action: HistoryAction - ) -> None: - """Claim unassigned replay UUIDs for recorded input UUIDs.""" - unmapped = self.get_unmapped(panel_str, recorded_uuids) - if not unmapped: - return - panel_order = list(action.state.object_metadata.get(panel_str, {})) - if panel_order and all(uuid in panel_order for uuid in unmapped): - unmapped.sort(key=panel_order.index) - queue = self.unclaimed.get(panel_str, []) - if not queue: - return - assigned = self.match_exact_uuids(panel_str, unmapped, queue) - assigned.update(self.match_titles(panel_str, unmapped, queue, action)) - assigned.update(self.match_positions(panel_str, unmapped, queue, panel_order)) - self.unclaimed[panel_str] = [uuid for uuid in queue if uuid not in assigned] - - def get_unmapped(self, panel_str: str, recorded_uuids: list[str]) -> list[str]: - """Return distinct recorded UUIDs that have no replay mapping.""" - panel_mapping = self.mapping.get(panel_str, {}) - unmapped: list[str] = [] - for uuid in recorded_uuids: - if uuid not in unmapped and uuid not in panel_mapping: - unmapped.append(uuid) - return unmapped - - def match_exact_uuids( - self, panel_str: str, recorded_uuids: list[str], queue: list[str] - ) -> set[str]: - """Match recorded inputs whose UUID is present unchanged in the queue.""" - assigned = set(recorded_uuids).intersection(queue) - panel_mapping = self.mapping.setdefault(panel_str, {}) - panel_mapping.update({uuid: uuid for uuid in assigned}) - return assigned - - def match_titles( - self, - panel_str: str, - recorded_uuids: list[str], - queue: list[str], - action: HistoryAction, - ) -> set[str]: - """Match remaining inputs with the unique replay object of the same title.""" - old_titles = self.get_recorded_titles(panel_str, recorded_uuids, action) - new_titles = self.get_replay_titles(panel_str, queue) - panel_mapping = self.mapping.setdefault(panel_str, {}) - assigned = set(panel_mapping.values()).intersection(queue) - for old_uuid in recorded_uuids: - if old_uuid in panel_mapping or old_uuid not in old_titles: - continue - candidates = [ - new_uuid - for new_uuid in queue - if new_uuid not in assigned - and new_titles.get(new_uuid) == old_titles[old_uuid] - ] - if len(candidates) == 1: - panel_mapping[old_uuid] = candidates[0] - assigned.add(candidates[0]) - return assigned - - def get_recorded_titles( - self, panel_str: str, recorded_uuids: list[str], action: HistoryAction - ) -> dict[str, str]: - """Return recorded object titles indexed by UUID.""" - selected = action.state.selection.get(panel_str, []) - titles = action.state.titles.get(panel_str, []) - old_titles = { - uuid: title - for uuid, title in zip(selected, titles) - if uuid in recorded_uuids - } - metadata = action.state.object_metadata.get(panel_str, {}) - for uuid in recorded_uuids: - signature = metadata.get(uuid) - if uuid not in old_titles and isinstance(signature, dict): - title = signature.get("title") - if isinstance(title, str): - old_titles[uuid] = title - return old_titles - - def get_replay_titles( - self, panel_str: str, replay_uuids: list[str] - ) -> dict[str, str]: - """Return titles of queued replay objects that still exist.""" - panel = self.panels.get(panel_str) - if panel is None: - return {} - titles: dict[str, str] = {} - for uuid in replay_uuids: - try: - titles[uuid] = panel.objmodel[uuid].title - except KeyError: - continue - return titles - - def match_positions( - self, - panel_str: str, - recorded_uuids: list[str], - queue: list[str], - panel_order: list[str], - ) -> set[str]: - """Match remaining inputs by absolute or relative recorded position.""" - panel_mapping = self.mapping.setdefault(panel_str, {}) - old_remaining = [uuid for uuid in recorded_uuids if uuid not in panel_mapping] - assigned = set(panel_mapping.values()).intersection(queue) - new_remaining = [uuid for uuid in queue if uuid not in assigned] - if not old_remaining: - return assigned - free_indices = [ - index for index, uuid in enumerate(panel_order) if uuid not in panel_mapping - ] - if panel_order and len(new_remaining) == len(free_indices): - self.match_absolute_positions( - panel_mapping, old_remaining, new_remaining, panel_order, free_indices - ) - else: - panel_mapping.update(dict(zip(old_remaining, new_remaining))) - return set(panel_mapping.values()).intersection(queue) - - @staticmethod - def match_absolute_positions( - panel_mapping: dict[str, str], - old_uuids: list[str], - new_uuids: list[str], - panel_order: list[str], - free_indices: list[int], - ) -> None: - """Match remaining UUIDs using their absolute recorded panel positions.""" - new_by_index = dict(zip(free_indices, new_uuids)) - for old_uuid in old_uuids: - if old_uuid in panel_order: - index = panel_order.index(old_uuid) - if index in new_by_index: - panel_mapping[old_uuid] = new_by_index[index] - - def capture_changes( - self, action: HistoryAction, before: dict[str, set[str]] - ) -> None: - """Capture objects created and removed by a replayed action.""" - for panel_str, panel in self.panels.items(): - object_ids = panel.objmodel.get_object_ids() - current = set(object_ids) - self.discard_removed(panel_str, before[panel_str] - current) - created = [uuid for uuid in object_ids if uuid not in before[panel_str]] - self.capture_created(panel_str, created, action) - - def discard_removed(self, panel_str: str, removed_uuids: set[str]) -> None: - """Discard queued objects and mappings whose replay objects were removed.""" - if not removed_uuids: - return - self.unclaimed[panel_str] = [ - uuid - for uuid in self.unclaimed.get(panel_str, []) - if uuid not in removed_uuids - ] - panel_mapping = self.mapping.get(panel_str, {}) - for old_uuid in [ - uuid - for uuid, new_uuid in panel_mapping.items() - if new_uuid in removed_uuids - ]: - panel_mapping.pop(old_uuid) - - def capture_created( - self, panel_str: str, created_uuids: list[str], action: HistoryAction - ) -> None: - """Map or queue objects created by a replayed action.""" - if not created_uuids: - return - captured = action.state.selection.get(panel_str, []) - if action.kind == HistoryAction.KIND_UI and captured: - self.mapping.setdefault(panel_str, {}).update( - dict(zip(captured, created_uuids)) - ) - created_uuids = created_uuids[len(captured) :] - self.unclaimed.setdefault(panel_str, []).extend(created_uuids) diff --git a/datalab/history/session.py b/datalab/history/session.py index f2f1d1153..b912aecd5 100644 --- a/datalab/history/session.py +++ b/datalab/history/session.py @@ -1,6 +1,6 @@ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. -"""HistorySession: ordered list of HistoryAction with replay logic.""" +"""HistorySession: ordered list of HistoryAction.""" from __future__ import annotations @@ -9,7 +9,6 @@ from datalab.config import _ from datalab.history.action import HistoryAction from datalab.history.core import HISTORY_SCHEMA_VERSION, get_datetime_str -from datalab.history.replaymap import ReplayUuidMap if TYPE_CHECKING: from datalab.gui.main import DLMainWindow @@ -103,36 +102,6 @@ def restore(self, mainwindow: DLMainWindow) -> None: if self.actions: self.actions[0].restore(mainwindow) - def replay( - self, mainwindow: DLMainWindow, restore_selection: bool, edit: bool - ) -> None: - """Replay the history session - - Args: - mainwindow: DataLab's main window - restore_selection: True to request restoration of captured selections. - Compute actions restore them only when compatible and resolvable. - edit: If True, request parameter dialogs for supported actions with - editable parameters. If False, use the captured parameters. - """ - panels = (mainwindow.signalpanel, mainwindow.imagepanel) - replay_map = ReplayUuidMap(panels) - for action in self.actions[:]: - before = replay_map.snapshot_object_ids() - replay_map.claim_action_inputs(action) - action.replay( - mainwindow, - restore_selection=restore_selection, - edit=edit, - uuid_remap=replay_map.mapping, - ) - replay_map.capture_changes(action, before) - - if self.actions: - select_last_compute_output( - mainwindow, panels, replay_map.mapping, self.actions[-1] - ) - def serialize(self, writer: NativeH5Writer) -> None: """Serialize this history session @@ -178,39 +147,3 @@ def remove_action(self, action: HistoryAction) -> None: if action in self.actions: index = self.actions.index(action) self.actions = self.actions[:index] - - -def select_last_compute_output( - mainwindow: DLMainWindow, - panels: tuple, - uuid_remap: dict[str, dict[str, str]], - last_action: HistoryAction, -) -> None: - """Select the output of the last compute action after a session replay. - - Visually closes the replay by highlighting the final result in its panel. - No-op when the last action is not a compute action or its output is gone. - - Args: - mainwindow: DataLab's main window - panels: signal and image panels - uuid_remap: per-panel ``{old_uuid: new_uuid}`` mapping built during replay - last_action: last action of the replayed session - """ - if last_action.kind != HistoryAction.KIND_COMPUTE: - return - hpanel = getattr(mainwindow, "historypanel", None) - if hpanel is None: - return - output_uuid = hpanel.action_output_uuid(last_action) - if not output_uuid: - return - panel_str = last_action.panel_str or "" - mapped_uuid = uuid_remap.get(panel_str, {}).get(output_uuid, output_uuid) - target_panel = next((p for p in panels if p.PANEL_STR_ID == panel_str), None) - if target_panel is None: - return - try: - target_panel.objview.select_objects([mapped_uuid]) - except KeyError: - pass diff --git a/datalab/locale/fr/LC_MESSAGES/datalab.po b/datalab/locale/fr/LC_MESSAGES/datalab.po index 4416e1264..a1ac503ff 100644 --- a/datalab/locale/fr/LC_MESSAGES/datalab.po +++ b/datalab/locale/fr/LC_MESSAGES/datalab.po @@ -360,12 +360,8 @@ msgid "Recompute" msgstr "Retraiter" #, python-format -msgid "" -"Recompute selected %s: refresh both processing and analysis results with their " -"stored parameters" -msgstr "" -"Retraiter l'objet %s sélectionné : actualiser les résultats de traitement et " -"d'analyse à partir de leurs paramètres enregistrés" +msgid "Recompute selected %s: refresh both processing and analysis results with their stored parameters" +msgstr "Retraiter l'objet %s sélectionné : actualiser les résultats de traitement et d'analyse à partir de leurs paramètres enregistrés" msgid "Select source objects" msgstr "Sélectionner les objets source" @@ -953,6 +949,9 @@ msgstr "Tapez pour rechercher une commande…" msgid "Search a command…" msgstr "Rechercher une commande…" +msgid "Custom signal" +msgstr "Signal personnalisé" + msgid "Process signal" msgstr "Traiter le signal" @@ -1366,9 +1365,6 @@ msgstr "Modifier la courbe graphiquement" msgid "Insert point" msgstr "Insérer un point" -msgid "Custom signal" -msgstr "Signal personnalisé" - msgid "Object metadata" msgstr "Métadonnées de l'objet" @@ -1411,6 +1407,12 @@ msgstr "Propriétés" msgid "Parameters for function `%s`" msgstr "Paramètres pour la fonction `%s`" +msgid "Created: historical peak parameters" +msgstr "Créé : paramètres de pic historiques" + +msgid "Created: invalid creation parameters" +msgstr "Créé : paramètres de création invalides" + msgid "Created" msgstr "Créé" @@ -1429,6 +1431,23 @@ msgstr "Paramètres de création" msgid "Creation" msgstr "Création" +msgid "This object uses historical area-based peak parameters. Convert them to signed peak height before editing." +msgstr "Cet objet utilise des paramètres de pic historiques fondés sur l'aire. Convertissez-les en hauteur de pic signée avant de les modifier." + +msgid "Convert historical parameters" +msgstr "Convertir les paramètres historiques" + +msgid "Creation parameters cannot be edited because their metadata is invalid or was written by a newer DataLab version." +msgstr "Les paramètres de création ne peuvent pas être modifiés, car leurs métadonnées sont invalides ou ont été écrites par une version plus récente de DataLab." + +#, python-format +msgid "" +"Failed to convert historical creation parameters:\n" +"%s" +msgstr "" +"Échec de la conversion des paramètres de création historiques :\n" +"%s" + #, python-format msgid "" "Failed to recreate object with new parameters:\n" @@ -1478,9 +1497,6 @@ msgstr "Aucun objet de traitement disponible." msgid "Processing metadata is incomplete." msgstr "Les métadonnées de traitement sont incomplètes." -msgid "Processing metadata is incomplete (missing source UUID)." -msgstr "Les métadonnées de traitement sont incomplètes (UUID source manquant)." - msgid "Source object no longer exists." msgstr "L'objet source n'existe plus." @@ -1498,12 +1514,6 @@ msgstr "" msgid "Processing was cancelled." msgstr "Le traitement a été annulé." -msgid "Signal was reprocessed." -msgstr "Le signal a été retraité." - -msgid "Image was reprocessed." -msgstr "L'image a été retraitée." - msgid "Failed to reprocess object." msgstr "Échec du retraitement de l'objet." @@ -1641,6 +1651,9 @@ msgstr "Charger depuis %d fichiers" msgid "Load \"%s\"" msgstr "Charger \"%s\"" +msgid "Save as" +msgstr "Enregistrer sous" + #, python-format msgid "Save to %d different files" msgstr "Enregistrer dans %d fichiers différents" @@ -1649,9 +1662,6 @@ msgstr "Enregistrer dans %d fichiers différents" msgid "Save to \"%s\"" msgstr "Enregistrer dans \"%s\"" -msgid "Save as" -msgstr "Enregistrer sous" - msgid "Saving..." msgstr "Enregistrement en cours..." @@ -1661,25 +1671,21 @@ msgstr "Importer une ROI" msgid "Export ROI" msgstr "Exporter une ROI" -msgid "" -"Selected object(s) do not have processing or analysis parameters that can be " -"recomputed." -msgstr "" -"L'objet (ou les objets) sélectionné(s) n'ont pas de paramètres de traitement ou " -"d'analyse pouvant être recalculés." +msgid "Selected object(s) do not have processing or analysis parameters that can be recomputed." +msgstr "L'objet (ou les objets) sélectionné(s) n'ont pas de paramètres de traitement ou d'analyse pouvant être recalculés." msgid "Recomputing objects" msgstr "Retraitement des objets" -msgid "Recomputing analyses" -msgstr "Recalcul des analyses" - msgid "Failed to recompute object" msgstr "Échec du retraitement de l'objet" msgid "Do you want to continue with the next object?" msgstr "Souhaitez-vous continuer avec l'objet suivant ?" +msgid "Recomputing analyses" +msgstr "Recalcul des analyses" + msgid "Analysis computation failed." msgstr "Le calcul de l'analyse a échoué." @@ -1762,26 +1768,92 @@ msgstr "« %s » possède des opérations dépendantes mais aucune source valide msgid "Some operations could not be reconnected after deletion:" msgstr "Certaines opérations n'ont pas pu être reconnectées après la suppression :" +msgid "Commit edit mode changes?" +msgstr "Valider les modifications du mode d'édition ?" + +msgid "" +"You are about to exit Edit mode.\n" +"\n" +"All parameter changes made during this session will be permanently kept.\n" +"This action cannot be undone — Restore will no longer be available.\n" +"\n" +"Do you want to continue?" +msgstr "" +"Vous êtes sur le point de quitter le mode d'édition.\n" +"\n" +"Toutes les modifications de paramètres effectuées lors de cette session seront conservées de façon permanente.\n" +"Cette action est irréversible — la fonction Restaurer ne sera plus disponible.\n" +"\n" +"Souhaitez-vous continuer ?" + msgid "The current workspace state is not compatible with the action." msgstr "L'état actuel de l'espace de travail n'est pas compatible avec l'action." msgid "Parameters" msgstr "Paramètres" +#, python-format +msgid "Action %s has no recorded pattern and cannot be replayed." +msgstr "L'action %s n'a pas de motif enregistré et ne peut pas être rejouée." + msgid "History panel" msgstr "Panneau d'historique" msgid "History files" msgstr "Fichiers d'historique" +#, python-format +msgid "Action %s has been edited but its target output object(s) no longer exist — skipping." +msgstr "L'action %s a été modifiée mais son ou ses objets de sortie cibles n'existent plus — ignorée." + +#, python-format +msgid "Action %s uses pattern %r which is not recomputable yet." +msgstr "L'action %s utilise le motif %r qui n'est pas encore recalculable." + #, python-format msgid "Action %s could not be fully recomputed." msgstr "L'action %s n'a pas pu être entièrement recalculée." +#, python-format +msgid "Recompute failed for action %s: %s" +msgstr "Échec du recalcul pour l'action %s : %s" + +#, python-format +msgid "" +"Action %(name)s skipped: plugin '%(loc)s' is missing.\n" +"Required parameter class: %(param)s\n" +"Reinstall the plugin to re-enable this action." +msgstr "" +"Action %(name)s ignorée : le plugin '%(loc)s' est manquant.\n" +"Classe de paramètre requise : %(param)s\n" +"Réinstallez le plugin pour réactiver cette action." + +#, python-format +msgid "Action %s: source object was deleted — skipping." +msgstr "Action %s : l'objet source a été supprimé — ignorée." + #, python-format msgid "Action %s: recompute returned %d output(s), expected %d." msgstr "Action %s : le recalcul a renvoyé %d sortie(s), %d attendue(s)." +#, python-format +msgid "Action %s: source object(s) were deleted — skipping." +msgstr "Action %s : le ou les objets source ont été supprimés — ignorée." + +#, python-format +msgid "Action %s: missing source(s) for output #%d — skipping." +msgstr "Action %s : source(s) manquante(s) pour la sortie n°%d — ignorée." + +#, python-format +msgid "Action %s: %d analysed object(s) were deleted — skipping." +msgstr "Action %s : %d objet(s) analysé(s) ont été supprimés — ignorée." + +msgid "Cascade recompute" +msgstr "Recalcul en cascade" + +msgid "Some downstream actions could not be recomputed:" +msgstr "Certaines actions en aval n'ont pas pu être recalculées :" + msgid "Record mode" msgstr "Mode d'enregistrement" @@ -1833,68 +1905,6 @@ msgstr "Pas à pas" msgid "Replay the selection step by step, editing parameters at each step" msgstr "Rejouer la sélection pas à pas, en modifiant les paramètres à chaque étape" -msgid "Commit edit mode changes?" -msgstr "Valider les modifications du mode d'édition ?" - -msgid "" -"You are about to exit Edit mode.\n" -"\n" -"All parameter changes made during this session will be permanently kept.\n" -"This action cannot be undone — Restore will no longer be available.\n" -"\n" -"Do you want to continue?" -msgstr "" -"Vous êtes sur le point de quitter le mode d'édition.\n" -"\n" -"Toutes les modifications de paramètres effectuées lors de cette session seront conservées de façon permanente.\n" -"Cette action est irréversible — la fonction Restaurer ne sera plus disponible.\n" -"\n" -"Souhaitez-vous continuer ?" - -#, python-format -msgid "Action %s has been edited but its target output object(s) no longer exist — skipping." -msgstr "L'action %s a été modifiée mais son ou ses objets de sortie cibles n'existent plus — ignorée." - -#, python-format -msgid "Action %s uses pattern %r which is not recomputable yet." -msgstr "L'action %s utilise le motif %r qui n'est pas encore recalculable." - -#, python-format -msgid "Recompute failed for action %s: %s" -msgstr "Échec du recalcul pour l'action %s : %s" - -#, python-format -msgid "" -"Action %(name)s skipped: plugin '%(loc)s' is missing.\n" -"Required parameter class: %(param)s\n" -"Reinstall the plugin to re-enable this action." -msgstr "" -"Action %(name)s ignorée : le plugin '%(loc)s' est manquant.\n" -"Classe de paramètre requise : %(param)s\n" -"Réinstallez le plugin pour réactiver cette action." - -#, python-format -msgid "Action %s: source object was deleted — skipping." -msgstr "Action %s : l'objet source a été supprimé — ignorée." - -#, python-format -msgid "Action %s: missing source(s) for output #%d — skipping." -msgstr "Action %s : source(s) manquante(s) pour la sortie n°%d — ignorée." - -#, python-format -msgid "Action %s: source object(s) were deleted — skipping." -msgstr "Action %s : le ou les objets source ont été supprimés — ignorée." - -#, python-format -msgid "Action %s: %d analysed object(s) were deleted — skipping." -msgstr "Action %s : %d objet(s) analysé(s) ont été supprimés — ignorée." - -msgid "Cascade recompute" -msgstr "Recalcul en cascade" - -msgid "Some downstream actions could not be recomputed:" -msgstr "Certaines actions en aval n'ont pas pu être recalculées :" - msgid "New image" msgstr "Nouvelle image" @@ -2144,6 +2154,15 @@ msgstr "" msgid "Yes to All" msgstr "Oui à tout" +msgid "Processing metadata is incomplete (missing source UUID)." +msgstr "Les métadonnées de traitement sont incomplètes (UUID source manquant)." + +msgid "Signal was reprocessed." +msgstr "Le signal a été retraité." + +msgid "Image was reprocessed." +msgstr "L'image a été retraitée." + msgid "Recomputing..." msgstr "Retraitement en cours..." @@ -2651,6 +2670,31 @@ msgstr "Ajustement exponentiel par morceaux" msgid "Sigmoid fit" msgstr "Ajustement sigmoïde" +#, python-format +msgid "%s: fitting curve was computed by an earlier version and cannot be evaluated (please recompute the fit)" +msgstr "%s : la courbe d'ajustement a été calculée par une version antérieure et ne peut pas être évaluée (veuillez recalculer l'ajustement)" + +#, python-format +msgid "%s: signal does not contain valid fit parameters" +msgstr "%s : le signal ne contient pas de paramètres d'ajustement valides" + +msgid "Cannot evaluate fit" +msgstr "Impossible d'évaluer l'ajustement" + +#, python-format +msgid "" +"One or more selected signals have invalid or unsupported fit parameters:\n" +"%s" +msgstr "" +"Un ou plusieurs signaux sélectionnés ont des paramètres d'ajustement invalides ou non pris en charge :\n" +"%s" + +msgid "Convert historical fit parameters" +msgstr "Convertir les paramètres d'ajustement historiques" + +msgid "One or more selected fitting curves use historical area-based peak parameters. Convert them to signed peak height before evaluating?" +msgstr "Une ou plusieurs courbes d'ajustement sélectionnées utilisent des paramètres de pic historiques fondés sur l'aire. Les convertir en hauteur de pic signée avant l'évaluation ?" + msgid "signal to subtract" msgstr "signal à soustraire" @@ -3493,12 +3537,6 @@ msgstr "Ouvrir un fichier d'historique" msgid "Imported" msgstr "Importé" -msgid "Replaying compound 'multiple_1_to_1' actions is not supported yet." -msgstr "La relecture des actions composées 'multiple_1_to_1' n'est pas encore prise en charge." - -msgid "Cannot replay 2-to-1 action: source object(s) missing." -msgstr "Impossible de rejouer une action 2-à-1 : objet(s) source manquant(s)." - #, python-format msgid "Failed to deserialize history DataSet kwarg %r." msgstr "Échec de la désérialisation de l'argument DataSet de l'historique %r." @@ -3507,9 +3545,6 @@ msgstr "Échec de la désérialisation de l'argument DataSet de l'historique %r. msgid "Failed to deserialize history DataSet-list kwarg %r." msgstr "Échec de la désérialisation de l'argument DataSet-list de l'historique %r." -msgid "Session" -msgstr "Session" - msgid "Registered plugins:" msgstr "Plugins enregistrés :" @@ -3939,10 +3974,6 @@ msgstr "L'action est compatible avec l'état actuel de l'espace de travail." msgid "Action is not compatible with the current workspace state." msgstr "L'action n'est pas compatible avec l'état actuel de l'espace de travail." -#, python-format -msgid "Processing chain — %d step(s)" -msgstr "Chaîne de traitement — %d étape(s)" - #, python-brace-format msgid "Active recording session ({panel})." msgstr "Session d'enregistrement active ({panel})." @@ -4381,42 +4412,3 @@ msgstr "Aucun contour n'a été trouvé pour la plage de niveaux sélectionnée. msgid "Show contour plot..." msgstr "Afficher le tracé de contours..." -msgid "Created: historical peak parameters" -msgstr "Créé : paramètres de pic historiques" - -msgid "This object uses historical area-based peak parameters. Convert them to signed peak height before editing." -msgstr "Cet objet utilise des paramètres de pic historiques fondés sur l'aire. Convertissez-les en hauteur de pic signée avant de les modifier." - -msgid "Convert historical parameters" -msgstr "Convertir les paramètres historiques" - -#, python-format -msgid "Failed to convert historical creation parameters:\n%s" -msgstr "Échec de la conversion des paramètres de création historiques :\n%s" - -msgid "Convert historical fit parameters" -msgstr "Convertir les paramètres d'ajustement historiques" - -msgid "One or more selected fitting curves use historical area-based peak parameters. Convert them to signed peak height before evaluating?" -msgstr "Une ou plusieurs courbes d'ajustement sélectionnées utilisent des paramètres de pic historiques fondés sur l'aire. Les convertir en hauteur de pic signée avant l'évaluation ?" - -msgid "Created: invalid creation parameters" -msgstr "Créé : paramètres de création invalides" - -msgid "Creation parameters cannot be edited because their metadata is invalid or was written by a newer DataLab version." -msgstr "Les paramètres de création ne peuvent pas être modifiés, car leurs métadonnées sont invalides ou ont été écrites par une version plus récente de DataLab." - -#, python-format -msgid "%s: signal does not contain valid fit parameters" -msgstr "%s : le signal ne contient pas de paramètres d'ajustement valides" - -msgid "Cannot evaluate fit" -msgstr "Impossible d'évaluer l'ajustement" - -#, python-format -msgid "One or more selected signals have invalid or unsupported fit parameters:\n%s" -msgstr "Un ou plusieurs signaux sélectionnés ont des paramètres d'ajustement invalides ou non pris en charge :\n%s" - -#, python-format -msgid "%s: fitting curve was computed by an earlier version and cannot be evaluated (please recompute the fit)" -msgstr "%s : la courbe d'ajustement a été calculée par une version antérieure et ne peut pas être évaluée (veuillez recalculer l'ajustement)" diff --git a/datalab/tests/features/common/history_model_unit_test.py b/datalab/tests/features/common/history_model_unit_test.py index b61b4b8d1..18061917b 100644 --- a/datalab/tests/features/common/history_model_unit_test.py +++ b/datalab/tests/features/common/history_model_unit_test.py @@ -1,6 +1,6 @@ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. -"""Pure unit contracts for history persistence, copying and replay mapping.""" +"""Pure unit contracts for history persistence, copying and recompute.""" from __future__ import annotations @@ -26,7 +26,6 @@ from datalab.gui.panel.history import interactive_replay as hireplay from datalab.gui.panel.history import recompute as hrec from datalab.gui.panel.history import runtime as hruntime -from datalab.gui.panel.history.navigation import HistoryNavigation from datalab.gui.panel.history.ui import HistoryPanelUI from datalab.gui.processor.base import ( BaseProcessor, @@ -42,8 +41,6 @@ from datalab.objectmodel import get_uuid, set_uuid from datalab.tests.features.common.history_test_helpers import ( build_history_action, - build_replay_map, - build_workspace_state, delete_hdf5_items_by_name, read_history_sessions, ) @@ -75,12 +72,10 @@ def __init__(self, prompt_allowed: bool = True) -> None: self.suppress_session_prompt = False self.prompt_allowed = prompt_allowed self.prompt_count = 0 - self.prompt_panel_strs: list[str] = [] - def start_session_input_prompt(self, panel_str: str) -> bool: + def start_session_input_prompt(self) -> bool: """Record that the debounce guard was reached.""" self.prompt_count += 1 - self.prompt_panel_strs.append(panel_str) return self.prompt_allowed @contextmanager @@ -95,18 +90,18 @@ def session_prompt_suppressed(self): class PromptNavigation: - """Minimal active-session registry for prompt tests.""" + """Minimal single active-session registry for prompt tests.""" - def __init__(self, active_sessions: dict[str, HistorySession]) -> None: - self.active_sessions = dict(active_sessions) + def __init__(self, active_session: HistorySession | None) -> None: + self.active_session = active_session def current_panel_str(self) -> str: - """Return the fallback panel used by legacy load callers.""" + """Return the fallback panel used for per-action panel resolution.""" return "signal" - def get_active_session(self, panel_str: str) -> HistorySession | None: - """Return the active session for ``panel_str``.""" - return self.active_sessions.get(panel_str) + def get_active_session(self) -> HistorySession | None: + """Return the single active recording session.""" + return self.active_session class PromptTree: @@ -141,17 +136,17 @@ class PromptPanel: def __init__( self, - active_sessions: dict[str, HistorySession], + sessions: list[HistorySession] | None = None, prompt_allowed: bool = True, ) -> None: self.record_mode_enabled = True - self.navigation = PromptNavigation(active_sessions) + self.history_sessions = list(sessions or []) + active = self.history_sessions[-1] if self.history_sessions else None + self.navigation = PromptNavigation(active) self.runtime = SimpleNamespace(execution=PromptExecution(prompt_allowed)) - self.history_sessions = list(active_sessions.values()) self.tree = PromptTree() self.ui = PromptUI() - self.created_panel_strs: list[str] = [] - self.prompt_panel_strs: list[str | None] = [] + self.created_sessions: list[HistorySession] = [] self.prompt_behaviors: list[hsess.SessionBehavior | None] = [] self.prompt_suppressed_states: list[bool] = [] self.added_actions: list[HistoryAction] = [] @@ -163,32 +158,27 @@ def is_replaying(self) -> bool: """Return whether history replay is active.""" return False - def create_new_session(self, panel_str: str | None = None) -> HistorySession: + def create_new_session(self) -> HistorySession: """Create and activate a session without constructing GUI objects.""" - assert panel_str is not None - self.created_panel_strs.append(panel_str) session = HistorySession(number=len(self.history_sessions) + 1) self.history_sessions.append(session) - self.navigation.active_sessions[panel_str] = session + self.navigation.active_session = session + self.created_sessions.append(session) return session def maybe_start_session_for_input( self, - panel_str: str | None = None, *, load: bool = False, behavior: hsess.SessionBehavior | None = None, ) -> bool: - """Forward to the session operation while recording its target.""" + """Forward to the session operation while recording the evaluation.""" self.events.append("session_decision") - self.prompt_panel_strs.append(panel_str) self.prompt_behaviors.append(behavior) self.prompt_suppressed_states.append( self.runtime.execution.suppress_session_prompt ) - return hsess.maybe_start_session_for_input( - self, panel_str=panel_str, load=load, behavior=behavior - ) + return hsess.maybe_start_session_for_input(self, load=load, behavior=behavior) @contextmanager def session_prompt_suppressed(self): @@ -288,15 +278,21 @@ def average(_objects: list[object]) -> None: @pytest.mark.parametrize("column", (0, 2)) -@pytest.mark.parametrize("selected_row", (HistoryAction(), HistorySession())) +@pytest.mark.parametrize("selected_kind", ("action", "session")) def test_history_tree_double_click_replays_current_selection_without_restoring( - selected_row: HistoryAction | HistorySession, column: int + selected_kind: str, column: int ) -> None: """Replay the current action or session selection from either tree column.""" + if selected_kind == "action": + selected_row: HistoryAction | HistorySession = HistoryAction() + expected_actions = [selected_row] + else: + selected_row = HistorySession() + selected_row.add_action(HistoryAction()) + selected_row.add_action(HistoryAction()) + expected_actions = list(selected_row.actions) selected_row.is_current_state_compatible = Mock(return_value=True) - selected_row.replay = Mock() clicked_row = HistoryAction() - clicked_row.replay = Mock() tree = SimpleNamespace( customContextMenuRequested=Mock(), itemDoubleClicked=Mock(), @@ -326,21 +322,28 @@ def test_history_tree_double_click_replays_current_selection_without_restoring( ui.setup_connections() double_click_slot = tree.itemDoubleClicked.connect.call_args.args[0] - double_click_slot(clicked_row, column) + with patch.object(hireplay, "replay_actions") as replay_actions_mock: + double_click_slot(clicked_row, column) - selected_row.replay.assert_called_once_with( - mainwindow, restore_selection=False, edit=False + selected_row.is_current_state_compatible.assert_called_once_with( + mainwindow, restore_selection=False ) - clicked_row.replay.assert_not_called() + replay_actions_mock.assert_called_once_with(panel, expected_actions, prompt=False) + assert clicked_row not in replay_actions_mock.call_args.args[1] -def test_image_creation_routes_to_image_session_when_signal_is_current() -> None: - """Route an image creation independently of the globally current panel.""" +def test_image_creation_extends_active_signal_session_when_rejected() -> None: + """Chain an image creation into the single active recording session.""" signal_session = make_prompt_session("signal", populated=True) signal_actions = list(signal_session.actions) - panel = PromptPanel({"signal": signal_session}) - unattended = SimpleNamespace(unattended=True, accept_dialogs=True) - with patch.object(hsess, "execenv", unattended): + panel = PromptPanel([signal_session]) + unattended = SimpleNamespace(unattended=True, accept_dialogs=False) + with ( + patch.object(hsess, "execenv", unattended), + patch.object( + hsess.Conf.proc.history_new_session_behavior, "get", return_value="ask" + ), + ): action = hsess.add_ui_entry( panel, "New image", @@ -348,41 +351,38 @@ def test_image_creation_routes_to_image_session_when_signal_is_current() -> None method_name="new_object", save_state=False, ) - image_session = panel.navigation.get_active_session("image") assert action is panel.added_actions[0] assert action.panel_str == "image" - assert panel.prompt_panel_strs == ["image"] assert panel.prompt_behaviors == [None] - assert panel.runtime.execution.prompt_count == 0 - assert panel.created_panel_strs == ["image"] - assert image_session is panel.history_sessions[-1] - assert image_session.actions == [action] - assert signal_session.actions == signal_actions + assert panel.runtime.execution.prompt_count == 1 + assert panel.created_sessions == [] + assert panel.navigation.get_active_session() is signal_session + assert signal_session.actions == signal_actions + [action] -def test_empty_active_image_session_skips_prompt() -> None: - """Reuse an empty active image session without reaching the debounce.""" +def test_empty_active_session_skips_prompt() -> None: + """Reuse an empty active session without reaching the debounce.""" image_session = make_prompt_session("image", populated=False) - panel = PromptPanel({"image": image_session}) - created = hsess.maybe_start_session_for_input(panel, panel_str="image") + panel = PromptPanel([image_session]) + created = hsess.maybe_start_session_for_input(panel) assert created is False assert panel.runtime.execution.prompt_count == 0 - assert panel.created_panel_strs == [] + assert panel.created_sessions == [] def test_omitted_session_behavior_reads_live_general_policy() -> None: """Resolve the general policy on every omitted-behavior call.""" image_session = make_prompt_session("image", populated=True) - panel = PromptPanel({"image": image_session}) + panel = PromptPanel([image_session]) option = hsess.Conf.proc.history_new_session_behavior with patch.object(option, "get", side_effect=["no", "yes"]) as get_behavior: - first_created = panel.maybe_start_session_for_input(panel_str="image") - second_created = panel.maybe_start_session_for_input(panel_str="image") + first_created = panel.maybe_start_session_for_input() + second_created = panel.maybe_start_session_for_input() assert first_created is False assert second_created is True - assert panel.created_panel_strs == ["image"] + assert len(panel.created_sessions) == 1 assert panel.prompt_behaviors == [None, None] assert get_behavior.call_count == 2 @@ -396,42 +396,39 @@ def test_explicit_session_behaviors_bypass_prompt() -> None: attended = SimpleNamespace(unattended=False, accept_dialogs=False) for behavior, expected_created in cases: image_session = make_prompt_session("image", populated=True) - panel = PromptPanel({"image": image_session}) + panel = PromptPanel([image_session]) with ( patch.object(hsess, "execenv", attended), patch.object(hsess.QW, "QMessageBox") as message_box, ): - created = panel.maybe_start_session_for_input( - panel_str="image", behavior=behavior - ) + created = panel.maybe_start_session_for_input(behavior=behavior) assert created is expected_created assert panel.runtime.execution.prompt_count == 0 - assert panel.created_panel_strs == (["image"] if expected_created else []) + assert len(panel.created_sessions) == (1 if expected_created else 0) message_box.question.assert_not_called() def test_invalid_session_behavior_has_no_side_effects() -> None: """Reject an invalid policy before debounce or session creation.""" image_session = make_prompt_session("image", populated=True) - panel = PromptPanel({"image": image_session}) + panel = PromptPanel([image_session]) with pytest.raises(ValueError, match="Invalid session behavior"): hsess.maybe_start_session_for_input( panel, - panel_str="image", behavior=cast(hsess.SessionBehavior, "invalid"), ) assert panel.runtime.execution.prompt_count == 0 - assert panel.created_panel_strs == [] + assert panel.created_sessions == [] assert panel.history_sessions == [image_session] -def test_accepted_image_prompt_routes_action_to_new_image_session() -> None: - """Record an image creation in the newly accepted image session.""" +def test_accepted_prompt_routes_action_to_new_session() -> None: + """Record an image creation in the newly accepted session.""" image_session = make_prompt_session("image", populated=True) previous_actions = list(image_session.actions) - panel = PromptPanel({"image": image_session}) + panel = PromptPanel([image_session]) unattended = SimpleNamespace(unattended=True, accept_dialogs=True) with ( patch.object(hsess, "execenv", unattended), @@ -446,36 +443,31 @@ def test_accepted_image_prompt_routes_action_to_new_image_session() -> None: method_name="new_object", save_state=False, ) - new_image_session = panel.navigation.get_active_session("image") + new_session = panel.navigation.get_active_session() assert panel.runtime.execution.prompt_count == 1 - assert panel.created_panel_strs == ["image"] - assert new_image_session is panel.history_sessions[-1] - assert new_image_session.actions == [action] + assert panel.created_sessions == [new_session] + assert new_session is panel.history_sessions[-1] + assert new_session.actions == [action] assert image_session.actions == previous_actions -def test_populated_active_signal_session_is_evaluated_independently() -> None: - """Start a signal session without replacing the active image session.""" +def test_accepted_prompt_replaces_active_session() -> None: + """Make the freshly created session the single active recording session.""" signal_session = make_prompt_session("signal", populated=True) - image_session = make_prompt_session("image", populated=False) - panel = PromptPanel({"signal": signal_session, "image": image_session}) + panel = PromptPanel([signal_session]) unattended = SimpleNamespace(unattended=True, accept_dialogs=True) with patch.object(hsess, "execenv", unattended): - created = hsess.maybe_start_session_for_input( - panel, panel_str="signal", behavior="ask" - ) + created = hsess.maybe_start_session_for_input(panel, behavior="ask") assert created is True assert panel.runtime.execution.prompt_count == 1 - assert panel.runtime.execution.prompt_panel_strs == ["signal"] - assert panel.created_panel_strs == ["signal"] - assert panel.navigation.get_active_session("image") is image_session + assert panel.created_sessions == [panel.navigation.get_active_session()] + assert panel.navigation.get_active_session() is not signal_session -def test_input_prompt_debounce_is_panel_scoped() -> None: - """Debounce signal and image decisions on independent timer windows.""" +def test_input_prompt_debounce_is_global() -> None: + """Debounce a synchronous burst of prompts on a single timer window.""" signal_session = make_prompt_session("signal", populated=True) - image_session = make_prompt_session("image", populated=True) - panel = PromptPanel({"signal": signal_session, "image": image_session}) + panel = PromptPanel([signal_session]) execution = hruntime.HistoryExecutionState() panel.runtime = SimpleNamespace(execution=execution) callbacks = [] @@ -489,22 +481,13 @@ def test_input_prompt_debounce_is_panel_scoped() -> None: ), patch.object(hsess, "execenv", unattended), ): - assert not hsess.maybe_start_session_for_input( - panel, panel_str="signal", behavior="ask" - ) - assert not hsess.maybe_start_session_for_input( - panel, panel_str="image", behavior="ask" - ) - assert not hsess.maybe_start_session_for_input( - panel, panel_str="signal", behavior="ask" - ) + assert not hsess.maybe_start_session_for_input(panel, behavior="ask") + assert not hsess.maybe_start_session_for_input(panel, behavior="ask") - assert execution.session_input_pending_panels == {"signal", "image"} - assert len(callbacks) == 2 + assert execution.session_input_pending is True + assert len(callbacks) == 1 callbacks[0]() - assert execution.session_input_pending_panels == {"image"} - callbacks[1]() - assert execution.session_input_pending_panels == set() + assert execution.session_input_pending is False def test_ui_entries_serialize_data_target_ownership() -> None: @@ -517,7 +500,7 @@ def test_ui_entries_serialize_data_target_ownership() -> None: "mainwindow": None, "historypanel": None, } - panel = PromptPanel({}) + panel = PromptPanel([]) actions = [] for target, panel_str in expected_ownership.items(): action = hsess.add_ui_entry( @@ -571,40 +554,6 @@ def test_ui_entries_serialize_data_target_ownership() -> None: assert action.effective_panel_str() == panel_str -def test_legacy_imageprocessor_replay_remaps_source_uuid() -> None: - """Remap a legacy processor UI action through its effective image owner.""" - replayed_source_uuids: list[str] = [] - - def load_from_source(source_uuid: str) -> None: - replayed_source_uuids.append(source_uuid) - - mainwindow = SimpleNamespace( - historypanel=SimpleNamespace( - is_output_suppressed=lambda: False, - replaying=nullcontext, - ), - imagepanel=SimpleNamespace( - processor=SimpleNamespace(load_from_source=load_from_source) - ), - ) - action = HistoryAction( - kind=HistoryAction.KIND_UI, - panel_str="", - target="imageprocessor", - method_name="load_from_source", - kwargs={"source_uuid": "old-image"}, - ) - - action.replay( - mainwindow, - restore_selection=False, - edit=False, - uuid_remap={"image": {"old-image": "new-image"}}, - ) - - assert replayed_source_uuids == ["new-image"] - - def test_resolve_panel_for_data_owned_ui_actions() -> None: """Resolve legacy processor and data-panel load actions to image data.""" signal_panel = SimpleNamespace(name="signal") @@ -652,15 +601,15 @@ def test_history_tools_action_panel_str_uses_effective_ownership() -> None: assert hops.action_panel_str(HistoryAction(target="mainwindow")) == "signal" -def test_image_histogram_action_keeps_image_session_ownership() -> None: - """Keep a signal-valued histogram in its image source session.""" +def test_image_histogram_action_keeps_image_ownership_in_active_session() -> None: + """Keep a signal-valued histogram owned by its image source panel.""" signal_session = make_prompt_session("signal", populated=True) image_session = make_prompt_session("image", populated=True) signal_actions = list(signal_session.actions) image_actions = list(image_session.actions) signal_output = SimpleNamespace(uuid="histogram-signal", panel_str="signal") image_source_panel = SimpleNamespace(name="image") - panel = PromptPanel({"signal": signal_session, "image": image_session}) + panel = PromptPanel([signal_session, image_session]) panel.mainwindow = SimpleNamespace( signalpanel=SimpleNamespace(name="signal", objects=[signal_output]), imagepanel=image_source_panel, @@ -676,7 +625,6 @@ def test_image_histogram_action_keeps_image_session_ownership() -> None: panel.add_object(action) - assert panel.navigation.current_panel_str() == "signal" assert signal_output.panel_str == "signal" assert action.effective_panel_str() == "image" assert hops.action_panel_str(action) == "image" @@ -686,9 +634,9 @@ def test_image_histogram_action_keeps_image_session_ownership() -> None: def test_debounce_rejection_does_not_start_or_prompt() -> None: - """Keep routing in the active target session when debounce rejects.""" + """Keep routing in the active session when debounce rejects.""" image_session = make_prompt_session("image", populated=True) - panel = PromptPanel({"image": image_session}, prompt_allowed=False) + panel = PromptPanel([image_session], prompt_allowed=False) attended = SimpleNamespace(unattended=False, accept_dialogs=True) with ( patch.object(hsess, "execenv", attended), @@ -705,33 +653,31 @@ def test_debounce_rejection_does_not_start_or_prompt() -> None: save_state=False, ) assert panel.runtime.execution.prompt_count == 1 - assert panel.created_panel_strs == [] - assert panel.navigation.get_active_session("image") is image_session + assert panel.created_sessions == [] + assert panel.navigation.get_active_session() is image_session assert image_session.actions[-1] is action message_box.question.assert_not_called() -def test_unattended_reject_keeps_populated_target_session() -> None: - """Leave the active image session untouched after unattended rejection.""" +def test_unattended_reject_keeps_populated_active_session() -> None: + """Leave the active session untouched after unattended rejection.""" image_session = make_prompt_session("image", populated=True) previous_actions = list(image_session.actions) - panel = PromptPanel({"image": image_session}) + panel = PromptPanel([image_session]) unattended = SimpleNamespace(unattended=True, accept_dialogs=False) with patch.object(hsess, "execenv", unattended): - created = hsess.maybe_start_session_for_input( - panel, panel_str="image", behavior="ask" - ) + created = hsess.maybe_start_session_for_input(panel, behavior="ask") assert created is False assert panel.runtime.execution.prompt_count == 1 - assert panel.created_panel_strs == [] - assert panel.navigation.get_active_session("image") is image_session + assert panel.created_sessions == [] + assert panel.navigation.get_active_session() is image_session assert image_session.actions == previous_actions def test_mainwindow_add_object_decides_before_mutation_and_suppresses_entry() -> None: """Decide before adding and suppress the creation entry's second prompt.""" image_session = make_prompt_session("image", populated=True) - historypanel = PromptPanel({"image": image_session}) + historypanel = PromptPanel([image_session]) added_objects = [] def add_to_image_panel(obj, group_id, set_current): @@ -770,7 +716,7 @@ def add_to_image_panel(obj, group_id, set_current): def test_mainwindow_add_object_preserves_no_record_and_memory_rejection() -> None: """Keep data addition without recording and stop entirely on memory refusal.""" image_session = make_prompt_session("image", populated=True) - historypanel = PromptPanel({"image": image_session}) + historypanel = PromptPanel([image_session]) historypanel.record_mode_enabled = False added_objects = [] @@ -798,14 +744,6 @@ def add_to_image_panel(obj, group_id, set_current): assert historypanel.prompt_behaviors == ["no"] -def test_navigation_uses_effective_panel_for_ui_only_session() -> None: - """Resolve legacy UI-only sessions from their action target.""" - session = HistorySession(number=1) - session.add_action(HistoryAction(kind=HistoryAction.KIND_UI, target="imagepanel")) - navigation = HistoryNavigation(SimpleNamespace()) - assert navigation.session_panel_str(session) == "image" - - def test_action_hdf5_current_and_legacy_contract() -> None: """Round-trip current fields and apply all legacy defaults.""" action = build_history_action() @@ -874,63 +812,6 @@ def test_action_copy_remaps_all_uuid_references() -> None: assert action.plugin_origin["metadata"]["entry_points"] == ["difference"] -def test_replay_uuid_map_matches_exact_title_and_position() -> None: - """Match replay inputs by exact UUID, unique title, then panel position.""" - replay_map, _signal_model, _image_model = build_replay_map( - [("same", "Exact"), ("new-position", "Other"), ("new-title", "Named")] - ) - replay_map.unclaimed["signal"] = ["same", "new-position", "new-title"] - state = build_workspace_state( - ["same", "old-title", "old-position"], ["Exact", "Named", "Recorded"] - ) - action = HistoryAction( - kind=HistoryAction.KIND_COMPUTE, panel_str="signal", state=state - ) - replay_map.claim_action_inputs(action) - assert replay_map.mapping["signal"] == { - "same": "same", - "old-title": "new-title", - "old-position": "new-position", - } - assert replay_map.unclaimed["signal"] == [] - - -def test_replay_uuid_map_preserves_operands_and_tracks_changes() -> None: - """Claim obj2 before primary inputs and track panel-local object changes.""" - replay_map, signal_model, image_model = build_replay_map( - [("new-second", "Second"), ("new-primary", "Primary")], - [("image-old", "Image")], - ) - replay_map.unclaimed["signal"] = ["new-second", "new-primary"] - action = HistoryAction( - kind=HistoryAction.KIND_COMPUTE, - panel_str="signal", - pattern="2_to_1", - kwargs={"obj2_uuids": ["old-second"]}, - state=build_workspace_state(["old-primary"], ["Primary"]), - ) - replay_map.claim_action_inputs(action) - assert replay_map.mapping["signal"] == { - "old-second": "new-second", - "old-primary": "new-primary", - } - before = replay_map.snapshot_object_ids() - signal_model.add("signal-new", "Created") - replay_map.capture_changes( - HistoryAction( - kind=HistoryAction.KIND_UI, - state=build_workspace_state(["old-new"]), - ), - before, - ) - assert replay_map.mapping["signal"]["old-new"] == "signal-new" - before = replay_map.snapshot_object_ids() - signal_model.remove("signal-new") - replay_map.capture_changes(HistoryAction(), before) - assert "old-new" not in replay_map.mapping["signal"] - assert image_model.get_object_ids() == ["image-old"] - - def test_edited_image_creation_recomputes_downstream_in_place() -> None: """Regenerate an edited image before recomputing its existing descendant.""" initial_param = Gauss2DParam.create( diff --git a/datalab/tests/features/common/history_panel_test.py b/datalab/tests/features/common/history_panel_test.py index 0644cc830..01679fa45 100644 --- a/datalab/tests/features/common/history_panel_test.py +++ b/datalab/tests/features/common/history_panel_test.py @@ -36,11 +36,12 @@ def test_panel_replay_restores_selection_without_outputs() -> None: assert panel.objview.get_sel_object_uuids() == [output_uuid] object_count, action_count = len(panel.objmodel), len(history) history.replay_restore_actions(replay=True, restore_selection=True) + # In-place recompute keeps counts unchanged and selects the refreshed output assert ( len(panel.objmodel), len(history), panel.objview.get_sel_object_uuids(), - ) == (object_count, action_count, [source_uuid]) + ) == (object_count, action_count, [output_uuid]) assert action in history.history_sessions[-1].actions and ( history.runtime.objects.action_output_uuids[action.uuid] == [output_uuid] ) @@ -105,21 +106,14 @@ def test_cross_panel_sessions_navigation_and_tree_state() -> None: image_panel.objview.select_objects([1]) image_panel.processor.run_feature(sipi.inverse) image_action = history[len(history)] - image_session = history.navigation.get_active_session("image") - assert ( - history.navigation.get_active_session("signal") is signal_session - and image_session is not None - and signal_session is not image_session - ) - bold_before = ( - is_session_bold(history, signal_session), - is_session_bold(history, image_session), - ) + # Unified model: the image action is chained into the single active + # recording session, alongside the signal actions. + assert history.navigation.get_active_session() is signal_session + assert image_action in signal_session.actions + bold_before = is_session_bold(history, signal_session) history.tree.populate_tree(history.history_sessions) - assert bold_before == (True, True) and ( - is_session_bold(history, signal_session), - is_session_bold(history, image_session), - ) == (True, True) + assert bold_before is True + assert is_session_bold(history, signal_session) is True output_uuid = first_signal_action.output_uuids[0] select_tree_entry(history, first_signal_action.uuid) assert signal_panel.objview.get_sel_object_uuids() == [output_uuid] diff --git a/datalab/tests/features/common/history_test_helpers.py b/datalab/tests/features/common/history_test_helpers.py index d486a607d..b55ba55b7 100644 --- a/datalab/tests/features/common/history_test_helpers.py +++ b/datalab/tests/features/common/history_test_helpers.py @@ -5,8 +5,7 @@ from __future__ import annotations from dataclasses import dataclass -from types import SimpleNamespace -from typing import TYPE_CHECKING, Any, cast +from typing import TYPE_CHECKING, Any import sigima.params import sigima.proc.signal as sips @@ -16,7 +15,6 @@ from datalab.h5.native import NativeH5Reader from datalab.history.action import HistoryAction -from datalab.history.replaymap import ReplayUuidMap from datalab.history.session import HistorySession from datalab.history.workspace_state import WorkspaceState @@ -33,42 +31,6 @@ class SignalChain: outputs: tuple[Any, Any, Any] -class ReplayObjectModel: - """Minimal ordered object model used by replay-map tests.""" - - def __init__(self, objects: list[tuple[str, str]]) -> None: - self.objects = {uuid: SimpleNamespace(title=title) for uuid, title in objects} - - def __getitem__(self, uuid: str) -> SimpleNamespace: - """Return an object by UUID.""" - return self.objects[uuid] - - def get_object_ids(self) -> list[str]: - """Return object UUIDs in panel order.""" - return list(self.objects) - - def add(self, uuid: str, title: str) -> None: - """Add an object to the model.""" - self.objects[uuid] = SimpleNamespace(title=title) - - def remove(self, uuid: str) -> None: - """Remove an object from the model.""" - self.objects.pop(uuid) - - -def build_replay_map( - signal_objects: list[tuple[str, str]], - image_objects: list[tuple[str, str]] | None = None, -) -> tuple[ReplayUuidMap, ReplayObjectModel, ReplayObjectModel]: - """Build a replay map backed by minimal signal and image panels.""" - signal_model = ReplayObjectModel(signal_objects) - image_model = ReplayObjectModel(image_objects or []) - signal_panel = SimpleNamespace(PANEL_STR_ID="signal", objmodel=signal_model) - image_panel = SimpleNamespace(PANEL_STR_ID="image", objmodel=image_model) - panels = cast(Any, (signal_panel, image_panel)) - return ReplayUuidMap(panels), signal_model, image_model - - def build_workspace_state( selection: list[str], titles: list[str] | None = None ) -> WorkspaceState: diff --git a/datalab/tests/features/common/history_workflow_test.py b/datalab/tests/features/common/history_workflow_test.py index 8f7255953..655efce4c 100644 --- a/datalab/tests/features/common/history_workflow_test.py +++ b/datalab/tests/features/common/history_workflow_test.py @@ -12,7 +12,7 @@ import numpy as np import sigima.params import sigima.proc.signal as sips -from sigima.tests.data import create_paracetamol_signal +from sigima.tests.data import create_paracetamol_signal, create_sincos_image from datalab.adapters_metadata.common import ResultData from datalab.gui import historytools_ops as htools @@ -104,7 +104,7 @@ def test_remap_processing_parameters_preserves_plugin_origin() -> None: def test_history_recording_contract_and_output_index() -> None: - """Record producing patterns and index every output without replay entries.""" + """Record producing patterns and index every output.""" with datalab_test_app_context(history=True) as win: history, panel = win.historypanel, win.signalpanel history.toggle_record_mode(True) @@ -129,114 +129,6 @@ def test_history_recording_contract_and_output_index() -> None: assert ( history.runtime.objects.output_to_action[output_uuid] == action.uuid ) - count_before = len(history) - derivative.replay(win, restore_selection=True, edit=False) - assert len(history) == count_before - - -def test_session_replay_remaps_distinct_processing_patterns() -> None: - """Replay chained 1-to-1, n-to-1 and ordered 2-to-1 computations.""" - with datalab_test_app_context(history=True) as win: - history, panel = win.historypanel, win.signalpanel - history.toggle_record_mode(True) - add_paracetamol_signals(panel, 2) - panel.objview.select_objects([1]) - panel.processor.run_feature(sips.derivative) - panel.objview.select_objects([2]) - panel.processor.run_feature(sips.derivative) - panel.objview.select_objects([3, 4]) - panel.processor.run_feature(sips.average) - panel.objview.select_objects([3]) - panel.processor.run_feature( - sips.difference, panel.objmodel.get_object_from_number(4) - ) - session = history.history_sessions[-1] - difference = session.actions[-1] - original_title = panel.objmodel[difference.output_uuids[0]].title - assert original_title.index("s003") < original_title.index("s004") - object_count = len(panel.objmodel) - action_count = len(history) - session.replay(win, restore_selection=False, edit=False) - assert len(panel.objmodel) == object_count + 4 - assert len(history) == action_count - replayed = panel.objmodel.get_object_from_number(len(panel.objmodel)) - assert "s" in replayed.title and "-" in replayed.title - - -def test_analysis_replay_requires_explicit_edit() -> None: - """Skip an analysis during ordinary replay but allow explicit edit replay.""" - with datalab_test_app_context(history=True) as win: - history, panel = win.historypanel, win.signalpanel - history.toggle_record_mode(True) - add_paracetamol_signals(panel, 1) - panel.objview.select_objects([1]) - panel.processor.run_feature(sips.stats) - analysis_action = history[len(history)] - assert analysis_action.pattern == "1_to_0" - with patch.object(panel.processor, "run_feature") as run_feature: - analysis_action.replay(win, restore_selection=True, edit=False) - run_feature.assert_not_called() - analysis_action.replay(win, restore_selection=True, edit=True) - run_feature.assert_called_once() - - -def test_replay_resolves_feature_with_plugin_origin_and_paramclass() -> None: - """Resolve replayed features with their plugin and parameter identities.""" - with datalab_test_app_context(history=True) as win: - history, panel = win.historypanel, win.signalpanel - history.toggle_record_mode(True) - add_paracetamol_signals(panel, 1) - panel.objview.select_objects([1]) - param = sigima.params.GaussianParam.create(sigma=1.5) - panel.processor.run_feature(sips.gaussian_filter, param) - action = history[len(history)] - plugin_origin = { - "module": "test_plugin.operations", - "directory": "test_plugin", - } - action.plugin_origin = plugin_origin - - with patch.object( - panel.processor, "get_feature", wraps=panel.processor.get_feature - ) as get_feature: - action.replay(win, restore_selection=True, edit=False) - - get_feature.assert_called_once_with( - action.func_name, - plugin_origin=plugin_origin, - paramclass_name=type(param).__name__, - ) - - -def test_replay_1_to_n_resolves_feature_with_first_paramclass() -> None: - """Resolve a 1-to-n feature with the first stored parameter identity.""" - with datalab_test_app_context(history=True) as win: - history, panel = win.historypanel, win.signalpanel - history.toggle_record_mode(True) - add_paracetamol_signals(panel, 1) - panel.objview.select_objects([1]) - params = [sigima.params.GaussianParam.create(sigma=1.5)] - action = HistoryAction() - action.kind = HistoryAction.KIND_COMPUTE - action.pattern = "1_to_n" - action.target = "signalpanel" - action.panel_str = "signal" - action.func_name = sips.gaussian_filter.__name__ - action.kwargs = {"params": params} - - with ( - patch.object( - panel.processor, "get_feature", return_value=sips.gaussian_filter - ) as get_feature, - patch.object(panel.processor, "run_feature"), - ): - action.replay_compute(win, edit=False) - - get_feature.assert_called_once_with( - action.func_name, - plugin_origin=None, - paramclass_name=type(params[0]).__name__, - ) def test_history_hdf5_pristine_load_and_nonempty_import() -> None: @@ -288,7 +180,7 @@ def test_duplicate_creation_and_operation_rooted_chains() -> None: "module": "example.plugin", "metadata": {"entry_points": ["derivative"]}, } - history.create_new_session(panel_str="signal") + history.create_new_session() win.add_object(create_paracetamol_signal()) panel.objview.select_objects([3]) panel.processor.run_feature(sips.derivative) @@ -344,6 +236,49 @@ def test_duplicate_creation_and_operation_rooted_chains() -> None: assert len(chains) == 1 and chains[0].root is duplicate.actions[0] +def test_duplicate_clones_only_chain_objects() -> None: + """Duplicate clones only chain inputs/outputs, not unrelated objects.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + # Unrelated objects alive at record time (captured in workspace state) + unrelated = create_paracetamol_signal() + unrelated.title = "Unrelated signal" + panel.add_object(unrelated) + win.imagepanel.add_object(create_sincos_image()) + source_uuid = add_paracetamol_signals(panel, 1)[0] + panel.objview.select_objects([source_uuid]) + panel.processor.run_feature(sips.derivative) + original = history.history_sessions[-1] + signal_count_before = len(panel.objmodel) + image_count_before = len(win.imagepanel.objmodel) + image_group_count_before = len(win.imagepanel.objmodel.get_groups()) + title_count_before = sum( + panel.objmodel[uuid].title == unrelated.title + for uuid in panel.objmodel.get_object_ids() + ) + select_tree_session(history, original) + htools.duplicate_selected_entries(history) + # Only the chain source and its derivative output are cloned + assert len(panel.objmodel) == signal_count_before + 2 + title_count_after = sum( + panel.objmodel[uuid].title == unrelated.title + for uuid in panel.objmodel.get_object_ids() + ) + assert title_count_after == title_count_before + # Image panel is untouched + assert len(win.imagepanel.objmodel) == image_count_before + assert len(win.imagepanel.objmodel.get_groups()) == image_group_count_before + duplicate = history.history_sessions[-1] + original_outputs = { + uuid for action in original.actions for uuid in action.output_uuids + } + duplicate_outputs = { + uuid for action in duplicate.actions for uuid in action.output_uuids + } + assert duplicate_outputs.isdisjoint(original_outputs) + + def test_edit_cascade_preserves_identity_and_action_state() -> None: """Cascade in place while preserving identities, metadata and edit baseline.""" with datalab_test_app_context(history=True) as win: @@ -488,7 +423,7 @@ def test_multi_action_edit_recomputes_selected_descendants_once() -> None: hrec, "recompute_action_in_place", return_value=True ) as recompute, ): - hireplay.edit_mode_replay_actions(history, selected) + hireplay.replay_actions(history, selected) assert [call.args[1] for call in prompt.call_args_list] == selected assert [call.args[1] for call in recompute.call_args_list] == expected @@ -514,12 +449,11 @@ def test_edit_mode_selected_session_uses_global_replay_planner() -> None: assert selected == [session, stale_action] with ( - patch.object(type(session), "replay") as direct_replay, patch.object(hrec, "recompute_cascade") as direct_cascade, patch.object( hireplay, - "edit_mode_replay_actions", - wraps=hireplay.edit_mode_replay_actions, + "replay_actions", + wraps=hireplay.replay_actions, ) as edit_planner, patch.object( hireplay, "prompt_edit_action_params", return_value=True @@ -530,9 +464,10 @@ def test_edit_mode_selected_session_uses_global_replay_planner() -> None: ): hireplay.replay_restore_actions(history) - direct_replay.assert_not_called() direct_cascade.assert_not_called() - edit_planner.assert_called_once_with(history, [*expected, stale_action]) + edit_planner.assert_called_once_with( + history, [*expected, stale_action], prompt=True + ) assert [call.args[1] for call in prompt.call_args_list] == expected assert [call.args[1] for call in recompute.call_args_list] == expected assert all(action.is_stale is False for action in expected) @@ -583,7 +518,7 @@ def test_multi_action_edit_cascades_across_independent_sessions() -> None: history.toggle_record_mode(True) history.toggle_edit_mode(True) first_chain = build_independent_signal_branch(panel, history) - history.create_new_session(panel_str="signal") + history.create_new_session() second_chain = build_independent_signal_branch(panel, history) selected = [second_chain[0], first_chain[0]] expected = [*first_chain, *second_chain] @@ -594,7 +529,7 @@ def test_multi_action_edit_cascades_across_independent_sessions() -> None: hrec, "recompute_action_in_place", return_value=True ) as recompute, ): - hireplay.edit_mode_replay_actions(history, selected) + hireplay.replay_actions(history, selected) assert [call.args[1] for call in recompute.call_args_list] == expected assert all(action.is_stale is False for action in expected) @@ -607,7 +542,7 @@ def test_multi_action_edit_failure_skips_dependents_and_continues() -> None: history.toggle_record_mode(True) history.toggle_edit_mode(True) failed_chain = build_independent_signal_branch(panel, history) - history.create_new_session(panel_str="signal") + history.create_new_session() successful_chain = build_independent_signal_branch(panel, history) failed_root = failed_chain[0] failed_output_uuid = failed_root.output_uuids[0] @@ -636,9 +571,7 @@ def recompute_action(_panel, action): hrec, "recompute_action_in_place", side_effect=recompute_action ), ): - hireplay.edit_mode_replay_actions( - history, [failed_root, successful_chain[0]] - ) + hireplay.replay_actions(history, [failed_root, successful_chain[0]]) assert recomputed == [failed_root, *successful_chain] assert all(action.is_stale is True for action in failed_chain) @@ -662,7 +595,7 @@ def prompt(_panel, action): return False with patch.object(hireplay, "prompt_edit_action_params", side_effect=prompt): - hireplay.edit_mode_replay_actions(history, [first_action, second_action]) + hireplay.replay_actions(history, [first_action, second_action]) assert first_action.kwargs["param"].sigma == 2.5 assert first_action.saved_kwargs["param"].sigma == 1.5 @@ -686,7 +619,7 @@ def test_multi_action_edit_cancel_skips_deferred_ui_replay() -> None: patch.object(ui_action, "replay") as replay, patch.object(hireplay, "prompt_edit_action_params", return_value=False), ): - hireplay.edit_mode_replay_actions(history, [ui_action, compute_action]) + hireplay.replay_actions(history, [ui_action, compute_action]) replay.assert_not_called() @@ -720,7 +653,7 @@ def replay_ui(*_args, **_kwargs): patch.object(hrec, "recompute_action_in_place", side_effect=recompute), patch.object(ui_action, "replay", side_effect=replay_ui), ): - hireplay.edit_mode_replay_actions(history, [first_compute, ui_action]) + hireplay.replay_actions(history, [first_compute, ui_action]) assert execution_order == [first_compute, ui_action, second_compute] @@ -746,7 +679,7 @@ def recompute(_panel, _action): wraps=hrec.flush_cascade_warnings, ) as flush, ): - hireplay.edit_mode_replay_actions(history, [action]) + hireplay.replay_actions(history, [action]) flush.assert_called_once_with(history) assert history.runtime.execution.cascade_warnings == [] @@ -1036,6 +969,40 @@ def test_1_to_0_cascade_uses_roi_safe_parameter_copy() -> None: assert action.kwargs["param"].create_rois is True +def test_replay_recreates_deleted_output_under_recorded_uuid() -> None: + """Re-create a deleted compute output under its recorded UUID on replay.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + source_uuid = add_paracetamol_signals(panel, 1)[0] + panel.objview.select_objects([source_uuid]) + panel.processor.run_feature(sips.derivative) + action = history[len(history)] + output_uuid = action.output_uuids[0] + expected_data = panel.objmodel[output_uuid].xydata.copy() + object_count = len(panel.objmodel) + panel.objview.select_objects([output_uuid]) + panel.remove_object(force=True) + assert not panel.objmodel.has_uuid(output_uuid) + assert action.output_uuids == [output_uuid] + + with patch.object(hrec, "flush_cascade_warnings"): + hireplay.replay_actions(history, [action], prompt=False) + + assert history.runtime.execution.cascade_warnings == [] + assert action.is_stale is False + assert len(panel.objmodel) == object_count + assert panel.objmodel.has_uuid(output_uuid) + recreated = panel.objmodel[output_uuid] + assert get_uuid(recreated) == output_uuid + assert np.array_equal(recreated.xydata, expected_data) + assert history.runtime.objects.output_to_action[output_uuid] == action.uuid + assert history.runtime.objects.action_output_uuids[action.uuid] == [output_uuid] + parameters = extract_processing_parameters(recreated) + assert parameters is not None + assert parameters.source_uuid == source_uuid + + def test_deletion_reconnects_and_splices_chain() -> None: """Reconnect after data deletion, then splice the producing action.""" with datalab_test_app_context(history=True) as win: diff --git a/datalab/tests/features/plugins/plugin_history_policy_unit_test.py b/datalab/tests/features/plugins/plugin_history_policy_unit_test.py index d6deea2dd..9648ffcf0 100644 --- a/datalab/tests/features/plugins/plugin_history_policy_unit_test.py +++ b/datalab/tests/features/plugins/plugin_history_policy_unit_test.py @@ -74,12 +74,11 @@ class HistoryPromptRecorder: def __init__(self) -> None: self.suppressed = False - self.calls: list[tuple[str, bool, hsess.SessionBehavior | None, bool]] = [] + self.calls: list[tuple[bool, hsess.SessionBehavior | None, bool]] = [] self.decision_count = 0 def maybe_start_session_for_input( self, - panel_str: str | None = None, *, load: bool = False, behavior: hsess.SessionBehavior | None = None, @@ -87,8 +86,7 @@ def maybe_start_session_for_input( """Record a validated session-policy evaluation.""" if behavior is not None and behavior not in hsess.SESSION_BEHAVIORS: raise ValueError(f"Invalid session behavior: {behavior!r}") - assert panel_str is not None - self.calls.append((panel_str, load, behavior, self.suppressed)) + self.calls.append((load, behavior, self.suppressed)) if not self.suppressed and behavior != "no": self.decision_count += 1 return False @@ -101,9 +99,8 @@ def add_ui_entry( save_state: bool = True, ) -> None: """Record the nested creation evaluation from the main window.""" - del action_title, method_name, save_state - panel_str = "signal" if target == "signalpanel" else "image" - self.maybe_start_session_for_input(panel_str=panel_str) + del action_title, target, method_name, save_state + self.maybe_start_session_for_input() @contextmanager def session_prompt_suppressed(self) -> Generator[None, None, None]: @@ -291,10 +288,10 @@ def test_plugin_multiload_decides_once_and_suppresses_internal_adds() -> None: assert mainwindow.added_objects == [first, second] assert mainwindow.historypanel.calls == [ - ("signal", False, "ask", False), - ("signal", False, None, True), - ("signal", False, "no", False), - ("signal", False, None, True), + (False, "ask", False), + (False, None, True), + (False, "no", False), + (False, None, True), ] assert mainwindow.historypanel.decision_count == 1 assert mainwindow.historypanel.suppressed is False @@ -374,8 +371,8 @@ def test_multiload_memory_rejection_does_not_consume_first_decision() -> None: assert mainwindow.memory_confirmation_count == 2 assert mainwindow.added_objects == [accepted] assert mainwindow.historypanel.calls == [ - ("signal", False, "ask", False), - ("signal", False, None, True), + (False, "ask", False), + (False, None, True), ] assert mainwindow.historypanel.decision_count == 1 diff --git a/datalab/widgets/historytree.py b/datalab/widgets/historytree.py index 6bede3140..a4684edc4 100644 --- a/datalab/widgets/historytree.py +++ b/datalab/widgets/historytree.py @@ -42,10 +42,9 @@ def __init__(self, parent: QW.QWidget) -> None: header.setSectionResizeMode(self.DESCRIPTION_COLUMN, QW.QHeaderView.Stretch) # Per-action expanded state, preserved across repopulate (delete/replay). self.__expanded_state: dict[str, bool] = {} - # Session numbers currently flagged as active recording sessions, - # mapped to their panel id ('signal'/'image'). Used to highlight the - # active session(s) and survive tree repopulation. - self.__active_session_numbers: dict[int, str] = {} + # Session number currently flagged as the active recording session. + # Used to highlight the active session and survive tree repopulation. + self.__active_session_number: int | None = None def on_description_toggled(self, uuid: str, expanded: bool) -> None: """Remember the expanded state of a description cell.""" @@ -186,34 +185,33 @@ def build_session_children( session_item.addChild(child) self.install_description_widget(child, action) - def set_active_sessions(self, active_session_numbers: dict[int, str]) -> None: - """Flag the active recording session(s) by session number and panel. + def set_active_session(self, active_session_number: int | None) -> None: + """Flag the active recording session by session number. Args: - active_session_numbers: Mapping ``{session.number: panel_str}`` of - the active recording session for each panel. + active_session_number: Session number of the active recording + session, or None when no session is active. """ - self.__active_session_numbers = dict(active_session_numbers) + self.__active_session_number = active_session_number self.__apply_active_highlight() def __apply_active_highlight(self) -> None: - """Bold + tint the top-level items of the active recording sessions.""" + """Bold + tint the top-level item of the active recording session.""" hl = self.palette().color(QG.QPalette.Highlight) hl.setAlpha(60) active_brush = QG.QBrush(hl) normal_brush = QG.QBrush() - tip = _("Active recording session ({panel}).") + tip = _("Active recording session.") for i in range(self.topLevelItemCount()): item = self.topLevelItem(i) number = item.data(0, self.SESSION_NUMBER_ROLE) - panel_str = self.__active_session_numbers.get(number) - is_active = panel_str is not None + is_active = number is not None and number == self.__active_session_number font = item.font(0) font.setBold(is_active) for col in (0, 1): item.setFont(col, font) item.setBackground(col, active_brush if is_active else normal_brush) - item.setToolTip(col, tip.format(panel=panel_str) if is_active else "") + item.setToolTip(col, tip if is_active else "") def rearrange_tree(self) -> None: """Rearrange the history tree widget""" diff --git a/doc/features/common/historypanel.rst b/doc/features/common/historypanel.rst index 96b3acc95..7ae1b26b7 100644 --- a/doc/features/common/historypanel.rst +++ b/doc/features/common/historypanel.rst @@ -21,11 +21,14 @@ list of either: A recorded session can be: -- **Replayed** silently or **step by step**, with an opportunity to edit - available parameters. New outputs from computation actions are not added to - the data panels. Recorded UI actions are invoked through their own methods - and may reproduce their side effects, including creating, importing, or - duplicating objects, unless an action has a specific replay guard; +- **Replayed** silently or **step by step**. Replaying recomputes each + computation action in place with its recorded parameters: existing output + objects are updated, and deleted outputs whose action is still part of the + history are re-created under their original identifiers, keeping the + downstream processing chain valid. In step-by-step mode, parameters may be + reviewed and edited before each step is recomputed. Recorded UI actions are + invoked through their own methods and may reproduce their side effects, + including creating, importing, or duplicating objects; - **Duplicated** as independent processing chains in new history sessions, with the required signal/image objects cloned as part of the operation; - **Saved to a standalone history file** (``.dlhist``) or **embedded in the @@ -135,18 +138,30 @@ The toolbar at the top of the panel exposes the following actions: session (keyboard shortcut: :kbd:`Ctrl+Left`). - |step_next| **Next step**: select the following action in the current session (keyboard shortcut: :kbd:`Ctrl+Right`). -- |replay| **Replay**: selecting an action replays that action directly; - selecting a session replays the whole session. Compute actions restore their - captured input selection when the translated object identifiers are - compatible and resolvable; UI actions are replayed without restoring their - recorded workspace selection. New objects returned by computation actions - are not added to the data panels. Recorded UI actions may reproduce side - effects, including creating, importing, or duplicating objects, unless an - action has a specific replay guard. -- |step_by_step| **Step-by-step**: replay the selection one step at a time. - Parameters may be reviewed and edited when the action supports it; supported - actions and their dependent branches are then updated or recomputed in - place. +- |replay| **Replay**: recompute the selection in place, silently (no + parameter dialogs). Selecting an action replays that action; selecting a + session replays all of its actions. A selection spanning several actions or + sessions is merged, deduplicated and executed in session order. Each + computation action re-runs with its recorded parameters and updates its + existing output object(s), keeping the same identifiers so that downstream + steps remain valid. Outputs that were deleted from the data panel are + re-created under their original identifiers (a typical workflow: delete a + bad result, edit its parameters, then replay to regenerate it). Actions + whose source objects no longer exist are skipped with a warning, and a + failed action blocks its downstream branch. Actions whose parameters were + changed (in step-by-step mode or from the **Processing** tab) are marked as + outdated; replaying recomputes them and, when parameters were edited, their + downstream dependent actions as well. Analysis actions replay by + recomputing their results on the source objects. UI actions are replayed by + invoking their recorded method and may reproduce side effects, including + creating, importing, or duplicating objects; destructive actions are + skipped when their captured targets no longer resolve. +- |step_by_step| **Step-by-step**: replay the same selection one step at a + time, opening the parameter dialog for each supported action (object + creation, computation, ROI extraction) before recomputing it. Accepted + edits propagate to the downstream dependent actions, which are recomputed + as well. Cancelling a dialog stops the replay and restores the parameter + edits made during that run. - |duplicate| **Duplicate**: duplicate the processing chain containing each selected action, or the processing chains in each selected session. DataLab clones the required objects and creates independent history sessions. @@ -159,9 +174,8 @@ The toolbar at the top of the panel exposes the following actions: .. note:: - Double-clicking a tree item invokes **Replay** for the current selection. It - uses the same action/session and compute/UI selection semantics documented - above. + Double-clicking a tree item invokes **Replay** for the current selection, + with the same in-place recompute semantics documented above. Tree view --------- diff --git a/doc/locale/fr/LC_MESSAGES/features/advanced/proxy.po b/doc/locale/fr/LC_MESSAGES/features/advanced/proxy.po index 6279448b2..d85bea1b5 100644 --- a/doc/locale/fr/LC_MESSAGES/features/advanced/proxy.po +++ b/doc/locale/fr/LC_MESSAGES/features/advanced/proxy.po @@ -6,28 +6,43 @@ #, fuzzy msgid "" msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2026-08-05 10:58+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language: fr\n" +"Language-Team: fr <LL@li.org>\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.18.0\n" msgid "Proxy objects (:mod:`datalab.control.proxy`)" msgstr "" -msgid "The :mod:`datalab.control.proxy` module provides a way to access DataLab features from a proxy class." +msgid "" +"The :mod:`datalab.control.proxy` module provides a way to access DataLab " +"features from a proxy class." msgstr "" msgid "Remote proxy" msgstr "" -msgid "The remote proxy is used when DataLab is started from a different process than the proxy. In this case, the proxy connects to DataLab XML-RPC server." +msgid "" +"The remote proxy is used when DataLab is started from a different process" +" than the proxy. In this case, the proxy connects to DataLab XML-RPC " +"server." msgstr "" msgid "DataLab remote proxy class." msgstr "" -msgid "This class provides access to DataLab features from a proxy class. This is the remote version of proxy, which is used when DataLab is started from a different process than the proxy." +msgid "" +"This class provides access to DataLab features from a proxy class. This " +"is the remote version of proxy, which is used when DataLab is started " +"from a different process than the proxy." msgstr "" msgid "Parameters" @@ -51,7 +66,9 @@ msgstr "" msgid "Examples" msgstr "" -msgid "Here is a simple example of how to use RemoteProxy in a Python script or in a Jupyter notebook:" +msgid "" +"Here is a simple example of how to use RemoteProxy in a Python script or " +"in a Jupyter notebook:" msgstr "" msgid "Add object annotations (annotation plot items)." @@ -63,7 +80,9 @@ msgstr "" msgid "refresh plot. Defaults to True." msgstr "" -msgid "panel name (valid values: \"signal\", \"image\"). If None, current panel is used." +msgid "" +"panel name (valid values: \"signal\", \"image\"). If None, current panel " +"is used." msgstr "" msgid "Add group to DataLab." @@ -168,7 +187,11 @@ msgstr "" msgid "Call computation feature ``name``" msgstr "" -msgid "This calls either the processor's ``compute_<name>`` method (if it exists), or the processor's ``<name>`` computation feature (if it is registered, using the ``run_feature`` method). It looks for the function in all panels, starting with the current one." +msgid "" +"This calls either the processor's ``compute_<name>`` method (if it " +"exists), or the processor's ``<name>`` computation feature (if it is " +"registered, using the ``run_feature`` method). It looks for the function " +"in all panels, starting with the current one." msgstr "" msgid "Compute function name" @@ -183,7 +206,9 @@ msgstr "" msgid "Call a public method on a panel or main window." msgstr "" -msgid "Method resolution order when panel is None: 1. Try main window (DLMainWindow) 2. If not found, try current panel (BaseDataPanel)" +msgid "" +"Method resolution order when panel is None: 1. Try main window " +"(DLMainWindow) 2. If not found, try current panel (BaseDataPanel)" msgstr "" msgid "Name of the method to call" @@ -192,7 +217,9 @@ msgstr "" msgid "Positional arguments to pass to the method" msgstr "" -msgid "Panel name (\"signal\", \"image\", or None for auto-detection). Defaults to None." +msgid "" +"Panel name (\"signal\", \"image\", or None for auto-detection). Defaults " +"to None." msgstr "" msgid "Keyword arguments to pass to the method" @@ -213,13 +240,19 @@ msgstr "" msgid "Try to connect to DataLab XML-RPC server." msgstr "" -msgid "XML-RPC port to connect to. If not specified, the port is automatically retrieved from DataLab configuration." +msgid "" +"XML-RPC port to connect to. If not specified, the port is automatically " +"retrieved from DataLab configuration." msgstr "" -msgid "Maximum time to wait for connection in seconds. Defaults to 5.0. This is the total maximum wait time, not per retry." +msgid "" +"Maximum time to wait for connection in seconds. Defaults to 5.0. This is " +"the total maximum wait time, not per retry." msgstr "" -msgid "Number of retries. Defaults to 10. This parameter is deprecated and will be removed in a future version (kept for backward compatibility)." +msgid "" +"Number of retries. Defaults to 10. This parameter is deprecated and will " +"be removed in a future version (kept for backward compatibility)." msgstr "" msgid "Return a context manager to temporarily disable auto refresh." @@ -270,7 +303,9 @@ msgstr "" msgid "Get object (signal/image) from index." msgstr "" -msgid "Object number, or object id, or object title. Defaults to None (current object)." +msgid "" +"Object number, or object id, or object title. Defaults to None (current " +"object)." msgstr "" msgid "Panel name. Defaults to None (current panel)." @@ -288,10 +323,14 @@ msgstr "" msgid "List of plot item shapes" msgstr "" -msgid "Get object (signal/image) list for current panel. Objects are sorted by group number and object index in group." +msgid "" +"Get object (signal/image) list for current panel. Objects are sorted by " +"group number and object index in group." msgstr "" -msgid "panel name (valid values: \"signal\", \"image\", \"macro\"). If None, current data panel is used (i.e. signal or image panel)." +msgid "" +"panel name (valid values: \"signal\", \"image\", \"macro\"). If None, " +"current data panel is used (i.e. signal or image panel)." msgstr "" msgid "List of object titles" @@ -300,7 +339,9 @@ msgstr "" msgid "if panel not found" msgstr "" -msgid "Get object (signal/image) uuid list for current panel. Objects are sorted by group number and object index in group." +msgid "" +"Get object (signal/image) uuid list for current panel. Objects are sorted" +" by group number and object index in group." msgstr "" msgid "Group number, or group id, or group title. Defaults to None (all groups)." @@ -369,10 +410,15 @@ msgstr "" msgid "Load native DataLab HDF5 workspace files without any GUI elements." msgstr "" -msgid "This method can be safely called from scripts (e.g., internal console, macros) as it does not create any Qt widgets, dialogs, or progress bars." +msgid "" +"This method can be safely called from scripts (e.g., internal console, " +"macros) as it does not create any Qt widgets, dialogs, or progress bars." msgstr "" -msgid "This method only supports native DataLab HDF5 files. For importing arbitrary HDF5 files (non-native), use :meth:`open_h5_files` or :meth:`import_h5_file` instead." +msgid "" +"This method only supports native DataLab HDF5 files. For importing " +"arbitrary HDF5 files (non-native), use :meth:`open_h5_files` or " +":meth:`import_h5_file` instead." msgstr "" msgid "List of native DataLab HDF5 filenames" @@ -429,10 +475,14 @@ msgstr "" msgid "Select groups in current panel." msgstr "" -msgid "List of group numbers (1 to N), or list of group uuids, or None to select all groups. Defaults to None." +msgid "" +"List of group numbers (1 to N), or list of group uuids, or None to select" +" all groups. Defaults to None." msgstr "" -msgid "panel name (valid values: \"signal\", \"image\"). If None, current panel is used. Defaults to None." +msgid "" +"panel name (valid values: \"signal\", \"image\"). If None, current panel " +"is used. Defaults to None." msgstr "" msgid "Select objects in current panel." @@ -450,10 +500,15 @@ msgstr "" msgid "Set object data in DataLab." msgstr "" -msgid "Update an existing object in DataLab with new data from ``obj``. The object is identified by its UUID (which is carried by ``obj`` from a previous :meth:`get_object` call)." +msgid "" +"Update an existing object in DataLab with new data from ``obj``. The " +"object is identified by its UUID (which is carried by ``obj`` from a " +"previous :meth:`get_object` call)." msgstr "" -msgid "Signal or image object (must have the same UUID as an existing object in DataLab)" +msgid "" +"Signal or image object (must have the same UUID as an existing object in " +"DataLab)" msgstr "" msgid "if no object with matching UUID is found" @@ -462,7 +517,9 @@ msgstr "" msgid "Set XML-RPC port to connect to." msgstr "" -msgid "XML-RPC port to connect to. If None, the port is automatically retrieved from DataLab configuration." +msgid "" +"XML-RPC port to connect to. If None, the port is automatically retrieved " +"from DataLab configuration." msgstr "" msgid "Start the WebAPI server." @@ -501,22 +558,51 @@ msgstr "" msgid "Local proxy" msgstr "" -msgid "The local proxy is used when DataLab is started from the same process as the proxy. In this case, the proxy is directly connected to DataLab main window instance. The typical use case is high-level scripting." +msgid "" +"The local proxy is used when DataLab is started from the same process as " +"the proxy. In this case, the proxy is directly connected to DataLab main " +"window instance. The typical use case is high-level scripting." msgstr "" msgid "DataLab local proxy class." msgstr "" -msgid "This class provides access to DataLab features from a proxy class. This is the local version of proxy, which is used when DataLab is started from the same process as the proxy." +msgid "" +"This class provides access to DataLab features from a proxy class. This " +"is the local version of proxy, which is used when DataLab is started from" +" the same process as the proxy." msgstr "" msgid "DLMainWindow instance." msgstr "" +msgid "Source of objects added through this proxy." +msgstr "" + +msgid "Optional history session creation policy" +msgstr "" + +msgid "True if the object was added successfully, False otherwise" +msgstr "" + +msgid "Apply one lazy session decision to a multi-object load." +msgstr "" + +msgid "Target data panel (\"signal\" or \"image\")" +msgstr "" + +msgid "If the panel or session behavior is invalid" +msgstr "" + +msgid "If another multiload session is already active" +msgstr "" + msgid "Compute function parameter. Defaults to None" msgstr "" -msgid "Object number, or object id, or object title. Defaults to None (current object)" +msgid "" +"Object number, or object id, or object title. Defaults to None (current " +"object)" msgstr "" msgid "Panel name. Defaults to None (current panel)" @@ -525,13 +611,18 @@ msgstr "" msgid "refresh plot. Defaults to True" msgstr "" -msgid "panel name (valid values: \"signal\", \"image\"). If None, current panel is used" +msgid "" +"panel name (valid values: \"signal\", \"image\"). If None, current panel " +"is used" msgstr "" msgid "Load HDF5 workspace files without showing file dialog." msgstr "" -msgid "This method loads one or more DataLab native HDF5 files directly, bypassing the file dialog. It is safe to call from the internal console or any context where Qt dialogs would cause threading issues." +msgid "" +"This method loads one or more DataLab native HDF5 files directly, " +"bypassing the file dialog. It is safe to call from the internal console " +"or any context where Qt dialogs would cause threading issues." msgstr "" msgid "Path(s) to HDF5 file(s). Can be a single path string or a list of paths" @@ -546,7 +637,10 @@ msgstr "" msgid "Save workspace to HDF5 file without showing file dialog." msgstr "" -msgid "This method saves the current workspace to a DataLab native HDF5 file directly, bypassing the file dialog. It is safe to call from the internal console or any context where Qt dialogs would cause threading issues." +msgid "" +"This method saves the current workspace to a DataLab native HDF5 file " +"directly, bypassing the file dialog. It is safe to call from the internal" +" console or any context where Qt dialogs would cause threading issues." msgstr "" msgid "Path to the output HDF5 file" @@ -576,19 +670,29 @@ msgstr "" msgid "Proxy context manager" msgstr "" -msgid "The proxy context manager is a convenient way to handle proxy creation and destruction. It is used as follows:" +msgid "" +"The proxy context manager is a convenient way to handle proxy creation " +"and destruction. It is used as follows:" msgstr "" -msgid "The proxy type can be \"local\" or \"remote\". For remote proxy, the port can be specified as \"remote:port\"." +msgid "" +"The proxy type can be \"local\" or \"remote\". For remote proxy, the port" +" can be specified as \"remote:port\"." msgstr "" -msgid "The proxy context manager allows to use the proxy in various contexts (Python script, Jupyter notebook, etc.). It also allows to switch seamlessly between local and remote proxy, keeping the same code inside the context." +msgid "" +"The proxy context manager allows to use the proxy in various contexts " +"(Python script, Jupyter notebook, etc.). It also allows to switch " +"seamlessly between local and remote proxy, keeping the same code inside " +"the context." msgstr "" msgid "Context manager handling DL proxy creation and destruction." msgstr "" -msgid "proxy type (\"local\" or \"remote\") For remote proxy, the port can be specified as \"remote:port\"" +msgid "" +"proxy type (\"local\" or \"remote\") For remote proxy, the port can be " +"specified as \"remote:port\"" msgstr "" msgid "Yields" @@ -597,7 +701,9 @@ msgstr "" msgid "proxy" msgstr "" -msgid "LocalProxy if what == \"local\" RemoteProxy if what == \"remote\" or \"remote:port\"" +msgid "" +"LocalProxy if what == \"local\" RemoteProxy if what == \"remote\" or " +"\"remote:port\"" msgstr "" msgid "with proxy_context(\"local\") as proxy:" @@ -609,7 +715,9 @@ msgstr "" msgid "Calling processor methods using proxy objects" msgstr "" -msgid "All the proxy objects provide access to the DataLab computing methods exposed by the processor classes:" +msgid "" +"All the proxy objects provide access to the DataLab computing methods " +"exposed by the processor classes:" msgstr "" msgid ":class:`datalab.gui.processor.signal.SignalProcessor`" @@ -618,6 +726,8 @@ msgstr "" msgid ":class:`datalab.gui.processor.image.ImageProcessor`" msgstr "" -msgid "To run a computation feature associated to a processor, you can use the :meth:`calc` method of the proxy object:" +msgid "" +"To run a computation feature associated to a processor, you can use the " +":meth:`calc` method of the proxy object:" msgstr "" diff --git a/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po b/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po index 6a93dd4be..09560c8ec 100644 --- a/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po +++ b/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2026-08-05 14:24+0200\n" +"POT-Creation-Date: 2026-08-05 18:58+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language: fr\n" @@ -18,11 +18,19 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.18.0\n" -msgid "History Panel in DataLab, the open-source scientific data analysis and visualization platform" -msgstr "Panneau d'historique de DataLab, la plateforme open-source d'analyse et de visualisation de données scientifiques" +msgid "" +"History Panel in DataLab, the open-source scientific data analysis and " +"visualization platform" +msgstr "" +"Panneau d'historique de DataLab, la plateforme open-source d'analyse et " +"de visualisation de données scientifiques" -msgid "DataLab, history, record, replay, session, scientific, data, analysis, visualization, platform" -msgstr "DataLab, historique, enregistrement, rejeu, session, scientifique, données, analyse, visualisation, plateforme" +msgid "" +"DataLab, history, record, replay, session, scientific, data, analysis, " +"visualization, platform" +msgstr "" +"DataLab, historique, enregistrement, rejeu, session, scientifique, " +"données, analyse, visualisation, plateforme" msgid "History Panel" msgstr "Panneau d'historique" @@ -30,44 +38,132 @@ msgstr "Panneau d'historique" msgid "Overview" msgstr "Vue d'ensemble" -msgid "The \"History Panel\" records the sequence of actions performed by the user on signals and images, organized into **sessions**. Each session is a chronological list of either:" -msgstr "Le « panneau d'historique » enregistre la séquence des actions effectuées par l'utilisateur sur les signaux et les images, organisée en **sessions**. Chaque session est une liste chronologique constituée soit :" +msgid "" +"The \"History Panel\" records the sequence of actions performed by the " +"user on signals and images, organized into **sessions**. Each session is " +"a chronological list of either:" +msgstr "" +"Le « panneau d'historique » enregistre la séquence des actions effectuées" +" par l'utilisateur sur les signaux et les images, organisée en " +"**sessions**. Chaque session est une liste chronologique constituée soit " +":" -msgid "**UI actions** (creating a new signal, removing selected objects, saving the workspace to HDF5, ...), or" -msgstr "d'**actions de l'interface** (création d'un nouveau signal, suppression des objets sélectionnés, enregistrement de l'espace de travail au format HDF5, ...), soit" +msgid "" +"**UI actions** (creating a new signal, removing selected objects, saving " +"the workspace to HDF5, ...), or" +msgstr "" +"d'**actions de l'interface** (création d'un nouveau signal, suppression " +"des objets sélectionnés, enregistrement de l'espace de travail au format " +"HDF5, ...), soit" -msgid "**computations** (FFT, average, Gaussian fit, ...) dispatched by the DataLab processors to Sigima." -msgstr "de **calculs** (FFT, moyenne, ajustement gaussien, ...) dont l'exécution est confiée à Sigima par les processeurs de DataLab." +msgid "" +"**computations** (FFT, average, Gaussian fit, ...) dispatched by the " +"DataLab processors to Sigima." +msgstr "" +"de **calculs** (FFT, moyenne, ajustement gaussien, ...) dont l'exécution " +"est confiée à Sigima par les processeurs de DataLab." msgid "A recorded session can be:" msgstr "Une session enregistrée peut être :" -msgid "**Replayed** silently or **step by step**, with an opportunity to edit available parameters. New outputs from computation actions are not added to the data panels. Recorded UI actions are invoked through their own methods and may reproduce their side effects, including creating, importing, or duplicating objects, unless an action has a specific replay guard;" -msgstr "**rejouée** silencieusement ou **pas à pas**, avec la possibilité de modifier les paramètres disponibles. Les nouvelles sorties des actions de calcul ne sont pas ajoutées aux panneaux de données. Les actions de l'interface enregistrées sont invoquées par leurs propres méthodes et peuvent reproduire leurs effets, notamment créer, importer ou dupliquer des objets, sauf lorsqu'une action dispose d'un mécanisme de protection spécifique lors du rejeu ;" +msgid "" +"**Replayed** silently or **step by step**. Replaying recomputes each " +"computation action in place with its recorded parameters: existing output" +" objects are updated, and deleted outputs whose action is still part of " +"the history are re-created under their original identifiers, keeping the " +"downstream processing chain valid. In step-by-step mode, parameters may " +"be reviewed and edited before each step is recomputed. Recorded UI " +"actions are invoked through their own methods and may reproduce their " +"side effects, including creating, importing, or duplicating objects;" +msgstr "" +"**rejouée** silencieusement ou **pas à pas**. Le rejeu recalcule en place " +"chaque action de calcul avec ses paramètres enregistrés : les objets de " +"sortie existants sont mis à jour, et les sorties supprimées dont l'action " +"fait toujours partie de l'historique sont recréées sous leurs identifiants " +"d'origine, ce qui préserve la validité de la chaîne de traitement en aval. " +"En mode pas à pas, les paramètres peuvent être examinés et modifiés avant " +"le recalcul de chaque étape. Les actions de l'interface enregistrées sont " +"invoquées par leurs propres méthodes et peuvent reproduire leurs effets, " +"notamment créer, importer ou dupliquer des objets ;" -msgid "**Duplicated** as independent processing chains in new history sessions, with the required signal/image objects cloned as part of the operation;" -msgstr "**dupliquée** sous forme de chaînes de traitement indépendantes dans de nouvelles sessions d'historique, les objets signal/image nécessaires étant clonés au cours de l'opération ;" +msgid "" +"**Duplicated** as independent processing chains in new history sessions, " +"with the required signal/image objects cloned as part of the operation;" +msgstr "" +"**dupliquée** sous forme de chaînes de traitement indépendantes dans de " +"nouvelles sessions d'historique, les objets signal/image nécessaires " +"étant clonés au cours de l'opération ;" -msgid "**Saved to a standalone history file** (``.dlhist``) or **embedded in the workspace** when saving to HDF5, so that the full processing chain travels with the data." -msgstr "**sauvegardée dans un fichier d'historique autonome** (``.dlhist``) ou **intégrée à l'espace de travail** lors de l'enregistrement au format HDF5, de sorte que toute la chaîne de traitement accompagne les données." +msgid "" +"**Saved to a standalone history file** (``.dlhist``) or **embedded in the" +" workspace** when saving to HDF5, so that the full processing chain " +"travels with the data." +msgstr "" +"**sauvegardée dans un fichier d'historique autonome** (``.dlhist``) ou " +"**intégrée à l'espace de travail** lors de l'enregistrement au format " +"HDF5, de sorte que toute la chaîne de traitement accompagne les données." -msgid "The History Panel after recording a representative session: create three signals (Voigt, Lorentzian, Lorentzian), remove one of them, create a Gaussian signal, compute the average, add Gaussian noise to the result and run a Gaussian fit." -msgstr "Le panneau d'historique après l'enregistrement d'une session représentative : création de trois signaux (Voigt, lorentzien, lorentzien), suppression de l'un d'eux, création d'un signal gaussien, calcul de la moyenne, ajout d'un bruit gaussien au résultat et ajustement par une gaussienne." +msgid "" +"The History Panel after recording a representative session: create three " +"signals (Voigt, Lorentzian, Lorentzian), remove one of them, create a " +"Gaussian signal, compute the average, add Gaussian noise to the result " +"and run a Gaussian fit." +msgstr "" +"Le panneau d'historique après l'enregistrement d'une session " +"représentative : création de trois signaux (Voigt, lorentzien, " +"lorentzien), suppression de l'un d'eux, création d'un signal gaussien, " +"calcul de la moyenne, ajout d'un bruit gaussien au résultat et ajustement" +" par une gaussienne." msgid "Recording and session lifecycle" msgstr "Enregistrement et cycle de vie des sessions" -msgid "Actions are recorded only while **Record mode** is enabled. Turning record mode off preserves existing sessions but does not add new entries." -msgstr "Les actions ne sont enregistrées que lorsque le **Mode d'enregistrement** est activé. Sa désactivation conserve les sessions existantes, mais n'ajoute aucune nouvelle entrée." +msgid "" +"Actions are recorded only while **Record mode** is enabled. Turning " +"record mode off preserves existing sessions but does not add new entries." +msgstr "" +"Les actions ne sont enregistrées que lorsque le **Mode d'enregistrement**" +" est activé. Sa désactivation conserve les sessions existantes, mais " +"n'ajoute aucune nouvelle entrée." -msgid "The Signals and Images panels each have their own active session. New actions are added to the active session of the data panel they concern, so switching between signals and images does not mix their recording contexts." -msgstr "Les panneaux Signaux et Images disposent chacun de leur propre session active. Les nouvelles actions sont ajoutées à la session active du panneau de données concerné ; ainsi, le passage des signaux aux images ne mélange pas leurs contextes d'enregistrement." +msgid "" +"The Signals and Images panels each have their own active session. New " +"actions are added to the active session of the data panel they concern, " +"so switching between signals and images does not mix their recording " +"contexts." +msgstr "" +"Les panneaux Signaux et Images disposent chacun de leur propre session " +"active. Les nouvelles actions sont ajoutées à la session active du " +"panneau de données concerné ; ainsi, le passage des signaux aux images ne" +" mélange pas leurs contextes d'enregistrement." -msgid "When a new object is created or a file is loaded into a populated active session, a configurable policy determines whether DataLab asks, starts a new session, or continues the current one. Plugin-created objects use separate policies. An explicit plugin multi-load scope supplies one durable session policy for the whole batch. With ordinary **Ask** behavior, repeated prompts for synchronous additions to the same panel are debounced during the current Qt event-loop turn." -msgstr "Lorsqu'un nouvel objet est créé ou qu'un fichier est chargé dans une session active non vide, une politique configurable détermine si DataLab demande quoi faire, démarre une nouvelle session ou continue dans la session courante. Des politiques distinctes s'appliquent aux objets créés par des plugins. Une portée explicite de chargement multiple par un plugin fournit une politique de session unique et durable pour l'ensemble du lot. Avec le comportement **Demander** ordinaire, un mécanisme anti-rebond évite les demandes répétées pour les ajouts synchrones au même panneau pendant le tour courant de la boucle d'événements Qt." +msgid "" +"When a new object is created or a file is loaded into a populated active " +"session, a configurable policy determines whether DataLab asks, starts a " +"new session, or continues the current one. Plugin-created objects use " +"separate policies. An explicit plugin multi-load scope supplies one " +"durable session policy for the whole batch. With ordinary **Ask** " +"behavior, repeated prompts for synchronous additions to the same panel " +"are debounced during the current Qt event-loop turn." +msgstr "" +"Lorsqu'un nouvel objet est créé ou qu'un fichier est chargé dans une " +"session active non vide, une politique configurable détermine si DataLab " +"demande quoi faire, démarre une nouvelle session ou continue dans la " +"session courante. Des politiques distinctes s'appliquent aux objets créés" +" par des plugins. Une portée explicite de chargement multiple par un " +"plugin fournit une politique de session unique et durable pour l'ensemble" +" du lot. Avec le comportement **Demander** ordinaire, un mécanisme anti-" +"rebond évite les demandes répétées pour les ajouts synchrones au même " +"panneau pendant le tour courant de la boucle d'événements Qt." -msgid "These options are available under ``File > Settings > Processing > History sessions``. See :ref:`history-session-settings` for the complete labels and default values." -msgstr "Ces options sont disponibles sous ``Fichier > Préférences > Traitement > Sessions d'historique``. Voir :ref:`history-session-settings` pour la liste complète des libellés et des valeurs par défaut." +msgid "" +"These options are available under ``File > Settings > Processing > " +"History sessions``. See :ref:`history-session-settings` for the complete " +"labels and default values." +msgstr "" +"Ces options sont disponibles sous ``Fichier > Préférences > Traitement > " +"Sessions d'historique``. Voir :ref:`history-session-settings` pour la " +"liste complète des libellés et des valeurs par défaut." msgid "Toolbar" msgstr "Barre d'outils" @@ -75,113 +171,279 @@ msgstr "Barre d'outils" msgid "The toolbar at the top of the panel exposes the following actions:" msgstr "La barre d'outils en haut du panneau expose les actions suivantes :" -msgid "|record| **Record mode**: toggle the recording of new actions. When off, no new entry is added to the history (existing sessions are preserved)." -msgstr "|record| **Mode d'enregistrement** : active ou désactive l'enregistrement des nouvelles actions. Lorsqu'il est désactivé, aucune nouvelle entrée n'est ajoutée à l'historique (les sessions existantes sont conservées)." +msgid "" +"|record| **Record mode**: toggle the recording of new actions. When off, " +"no new entry is added to the history (existing sessions are preserved)." +msgstr "" +"|record| **Mode d'enregistrement** : active ou désactive l'enregistrement" +" des nouvelles actions. Lorsqu'il est désactivé, aucune nouvelle entrée " +"n'est ajoutée à l'historique (les sessions existantes sont conservées)." msgid "record" msgstr "record" -msgid "|new_session| **New session**: start a new active history session for the current data panel." -msgstr "|new_session| **Nouvelle session** : démarre une nouvelle session d'historique active pour le panneau de données actuel." +msgid "" +"|new_session| **New session**: start a new active history session for the" +" current data panel." +msgstr "" +"|new_session| **Nouvelle session** : démarre une nouvelle session " +"d'historique active pour le panneau de données actuel." msgid "new_session" msgstr "new_session" -msgid "|open_history| **Open history file**: load recorded sessions from a standalone ``.dlhist`` file." -msgstr "|open_history| **Ouvrir un fichier d'historique** : charge des sessions enregistrées depuis un fichier ``.dlhist`` autonome." +msgid "" +"|open_history| **Open history file**: load recorded sessions from a " +"standalone ``.dlhist`` file." +msgstr "" +"|open_history| **Ouvrir un fichier d'historique** : charge des sessions " +"enregistrées depuis un fichier ``.dlhist`` autonome." msgid "open_history" msgstr "open_history" -msgid "|save_history| **Save history file**: save the current recorded sessions to a standalone ``.dlhist`` file." -msgstr "|save_history| **Enregistrer un fichier d'historique** : enregistre les sessions actuellement enregistrées dans un fichier ``.dlhist`` autonome." +msgid "" +"|save_history| **Save history file**: save the current recorded sessions " +"to a standalone ``.dlhist`` file." +msgstr "" +"|save_history| **Enregistrer un fichier d'historique** : enregistre les " +"sessions actuellement enregistrées dans un fichier ``.dlhist`` autonome." msgid "save_history" msgstr "save_history" -msgid "|step_prev| **Previous step**: select the preceding action in the current session (keyboard shortcut: :kbd:`Ctrl+Left`)." -msgstr "|step_prev| **Étape précédente** : sélectionne l'action précédente dans la session courante (raccourci clavier : :kbd:`Ctrl+Gauche`)." +msgid "" +"|step_prev| **Previous step**: select the preceding action in the current" +" session (keyboard shortcut: :kbd:`Ctrl+Left`)." +msgstr "" +"|step_prev| **Étape précédente** : sélectionne l'action précédente dans " +"la session courante (raccourci clavier : :kbd:`Ctrl+Gauche`)." msgid "step_prev" msgstr "step_prev" -msgid "|step_next| **Next step**: select the following action in the current session (keyboard shortcut: :kbd:`Ctrl+Right`)." -msgstr "|step_next| **Étape suivante** : sélectionne l'action suivante dans la session courante (raccourci clavier : :kbd:`Ctrl+Droite`)." +msgid "" +"|step_next| **Next step**: select the following action in the current " +"session (keyboard shortcut: :kbd:`Ctrl+Right`)." +msgstr "" +"|step_next| **Étape suivante** : sélectionne l'action suivante dans la " +"session courante (raccourci clavier : :kbd:`Ctrl+Droite`)." msgid "step_next" msgstr "step_next" -msgid "|replay| **Replay**: selecting an action replays that action directly; selecting a session replays the whole session. Compute actions restore their captured input selection when the translated object identifiers are compatible and resolvable; UI actions are replayed without restoring their recorded workspace selection. New objects returned by computation actions are not added to the data panels. Recorded UI actions may reproduce side effects, including creating, importing, or duplicating objects, unless an action has a specific replay guard." -msgstr "|replay| **Rejouer** : sélectionner une action rejoue directement cette action ; sélectionner une session rejoue toute la session. Les actions de calcul restaurent leur sélection d'entrées capturée lorsque les identifiants d'objets remappés sont compatibles et peuvent être résolus ; les actions de l'interface sont rejouées sans restaurer au préalable leur sélection de l'espace de travail enregistrée. Les nouveaux objets renvoyés par les actions de calcul ne sont pas ajoutés aux panneaux de données. Les actions de l'interface enregistrées peuvent reproduire des effets, notamment créer, importer ou dupliquer des objets, sauf lorsqu'une action dispose d'un mécanisme de protection spécifique lors du rejeu." +msgid "" +"|replay| **Replay**: recompute the selection in place, silently (no " +"parameter dialogs). Selecting an action replays that action; selecting a " +"session replays all of its actions. A selection spanning several actions " +"or sessions is merged, deduplicated and executed in session order. Each " +"computation action re-runs with its recorded parameters and updates its " +"existing output object(s), keeping the same identifiers so that " +"downstream steps remain valid. Outputs that were deleted from the data " +"panel are re-created under their original identifiers (a typical " +"workflow: delete a bad result, edit its parameters, then replay to " +"regenerate it). Actions whose source objects no longer exist are skipped " +"with a warning, and a failed action blocks its downstream branch. Actions" +" whose parameters were changed (in step-by-step mode or from the " +"**Processing** tab) are marked as outdated; replaying recomputes them " +"and, when parameters were edited, their downstream dependent actions as " +"well. Analysis actions replay by recomputing their results on the source " +"objects. UI actions are replayed by invoking their recorded method and " +"may reproduce side effects, including creating, importing, or duplicating" +" objects; destructive actions are skipped when their captured targets no " +"longer resolve." +msgstr "" +"|replay| **Rejouer** : recalcule la sélection en place, silencieusement " +"(sans boîtes de dialogue de paramètres). Sélectionner une action rejoue " +"cette action ; sélectionner une session rejoue toutes ses actions. Une " +"sélection couvrant plusieurs actions ou sessions est fusionnée, " +"dédoublonnée et exécutée dans l'ordre des sessions. Chaque action de " +"calcul est réexécutée avec ses paramètres enregistrés et met à jour son ou " +"ses objets de sortie existants, en conservant les mêmes identifiants afin " +"que les étapes en aval restent valides. Les sorties supprimées du panneau " +"de données sont recréées sous leurs identifiants d'origine (flux de " +"travail typique : supprimer un résultat erroné, modifier ses paramètres, " +"puis rejouer pour le régénérer). Les actions dont les objets source " +"n'existent plus sont ignorées avec un avertissement, et une action en " +"échec bloque sa branche en aval. Les actions dont les paramètres ont été " +"modifiés (en mode pas à pas ou depuis l'onglet **Traitement**) sont " +"marquées comme obsolètes ; le rejeu les recalcule et, lorsque les " +"paramètres ont été modifiés, recalcule également leurs actions dépendantes " +"en aval. Les actions d'analyse sont rejouées en recalculant leurs " +"résultats sur les objets source. Les actions de l'interface sont rejouées " +"en invoquant leur méthode enregistrée et peuvent reproduire des effets, " +"notamment créer, importer ou dupliquer des objets ; les actions " +"destructives sont ignorées lorsque leurs cibles capturées ne peuvent plus " +"être résolues." msgid "replay" msgstr "replay" -msgid "|step_by_step| **Step-by-step**: replay the selection one step at a time. Parameters may be reviewed and edited when the action supports it; supported actions and their dependent branches are then updated or recomputed in place." -msgstr "|step_by_step| **Pas à pas** : rejoue la sélection pas à pas. Les paramètres peuvent être examinés et modifiés lorsque l'action le permet ; les actions prises en charge et leurs branches dépendantes sont alors mises à jour ou recalculées sur place." - +msgid "" +"|step_by_step| **Step-by-step**: replay the same selection one step at a " +"time, opening the parameter dialog for each supported action (object " +"creation, computation, ROI extraction) before recomputing it. Accepted " +"edits propagate to the downstream dependent actions, which are recomputed" +" as well. Cancelling a dialog stops the replay and restores the parameter" +" edits made during that run." +msgstr """|step_by_step| **Pas à pas** : rejoue la même sélection étape par étape, " +"en ouvrant la boîte de dialogue des paramètres pour chaque action prise en " +"charge (création d'objet, calcul, extraction de ROI) avant de la " +"recalculer. Les modifications acceptées se propagent aux actions " +"dépendantes en aval, qui sont également recalculées. Annuler une boîte de " +"dialogue interrompt le rejeu et annule les modifications de paramètres " +"effectuées au cours de cette exécution." msgid "step_by_step" msgstr "step_by_step" -msgid "|duplicate| **Duplicate**: duplicate the processing chain containing each selected action, or the processing chains in each selected session. DataLab clones the required objects and creates independent history sessions." -msgstr "|duplicate| **Dupliquer** : duplique la chaîne de traitement contenant chaque action sélectionnée, ou les chaînes de traitement de chaque session sélectionnée. DataLab clone les objets nécessaires et crée des sessions d'historique indépendantes." +msgid "" +"|duplicate| **Duplicate**: duplicate the processing chain containing each" +" selected action, or the processing chains in each selected session. " +"DataLab clones the required objects and creates independent history " +"sessions." +msgstr "" +"|duplicate| **Dupliquer** : duplique la chaîne de traitement contenant " +"chaque action sélectionnée, ou les chaînes de traitement de chaque " +"session sélectionnée. DataLab clone les objets nécessaires et crée des " +"sessions d'historique indépendantes." msgid "duplicate" msgstr "duplicate" -msgid "|remove_incompatible| **Remove incompatible**: remove all actions whose workspace state is no longer compatible with the current workspace. A confirmation dialog shows how many actions will be removed." -msgstr "|remove_incompatible| **Supprimer les actions incompatibles** : supprime toutes les actions dont l'état de l'espace de travail n'est plus compatible avec l'espace de travail actuel. Une boîte de dialogue de confirmation indique combien d'actions seront supprimées." +msgid "" +"|remove_incompatible| **Remove incompatible**: remove all actions whose " +"workspace state is no longer compatible with the current workspace. A " +"confirmation dialog shows how many actions will be removed." +msgstr "" +"|remove_incompatible| **Supprimer les actions incompatibles** : supprime " +"toutes les actions dont l'état de l'espace de travail n'est plus " +"compatible avec l'espace de travail actuel. Une boîte de dialogue de " +"confirmation indique combien d'actions seront supprimées." msgid "remove_incompatible" msgstr "remove_incompatible" -msgid "|delete| **Delete**: remove the selected actions or sessions from the history. Removing an intermediate action splices it out and preserves its downstream steps as an independent chain." -msgstr "|delete| **Supprimer** : retire de l'historique les actions ou sessions sélectionnées. La suppression d'une action intermédiaire la retire de la chaîne et conserve ses étapes en aval sous forme de chaîne indépendante." +msgid "" +"|delete| **Delete**: remove the selected actions or sessions from the " +"history. Removing an intermediate action splices it out and preserves its" +" downstream steps as an independent chain." +msgstr "" +"|delete| **Supprimer** : retire de l'historique les actions ou sessions " +"sélectionnées. La suppression d'une action intermédiaire la retire de la " +"chaîne et conserve ses étapes en aval sous forme de chaîne indépendante." msgid "delete" msgstr "delete" -msgid "Double-clicking a tree item invokes **Replay** for the current selection. It uses the same action/session and compute/UI selection semantics documented above." -msgstr "Un double-clic sur un élément de l'arborescence déclenche **Rejouer** pour la sélection courante. Ce rejeu suit les mêmes règles que celles décrites ci-dessus concernant la sélection d'une action ou d'une session et la restauration des sélections pour les calculs ou l'interface." +msgid "" +"Double-clicking a tree item invokes **Replay** for the current selection," +" with the same in-place recompute semantics documented above." +msgstr "" +"Un double-clic sur un élément de l'arborescence déclenche **Rejouer** pour " +"la sélection courante, avec la même sémantique de recalcul en place que " +"celle documentée ci-dessus." msgid "Tree view" msgstr "Arborescence" msgid "The tree view organizes recorded actions into expandable sessions:" -msgstr "L'arborescence organise les actions enregistrées dans des sessions dépliables :" +msgstr "" +"L'arborescence organise les actions enregistrées dans des sessions " +"dépliables :" -msgid "Each top-level row is a **session** associated with the Signals or Images panel. Sessions may be started when recording is enabled, with **New session**, or according to the configured session policy." -msgstr "Chaque ligne de premier niveau est une **session** associée au panneau Signaux ou Images. Les sessions peuvent être démarrées lorsque l'enregistrement est activé, avec **Nouvelle session**, ou selon la politique de session configurée." +msgid "" +"Each top-level row is a **session** associated with the Signals or Images" +" panel. Sessions may be started when recording is enabled, with **New " +"session**, or according to the configured session policy." +msgstr "" +"Chaque ligne de premier niveau est une **session** associée au panneau " +"Signaux ou Images. Les sessions peuvent être démarrées lorsque " +"l'enregistrement est activé, avec **Nouvelle session**, ou selon la " +"politique de session configurée." -msgid "Each child row is an **action**, with its title, date/time and a description summarising its parameters or resolved call when available. A UI action whose call cannot be resolved may have an empty description." -msgstr "Chaque ligne enfant est une **action**, accompagnée de son titre, de sa date et de son heure, ainsi que d'une description résumant ses paramètres ou l'appel résolu lorsqu'ils sont disponibles. Une action de l'interface dont l'appel ne peut pas être résolu peut avoir une description vide." +msgid "" +"Each child row is an **action**, with its title, date/time and a " +"description summarising its parameters or resolved call when available. A" +" UI action whose call cannot be resolved may have an empty description." +msgstr "" +"Chaque ligne enfant est une **action**, accompagnée de son titre, de sa " +"date et de son heure, ainsi que d'une description résumant ses paramètres" +" ou l'appel résolu lorsqu'ils sont disponibles. Une action de l'interface" +" dont l'appel ne peut pas être résolu peut avoir une description vide." -msgid "The selection of one or several rows determines which entries are targeted by the toolbar and context-menu commands. The context menu exposes the same commands as the toolbar." -msgstr "La sélection d'une ou de plusieurs lignes détermine les entrées ciblées par les commandes de la barre d'outils et du menu contextuel. Le menu contextuel propose les mêmes commandes que la barre d'outils." +msgid "" +"The selection of one or several rows determines which entries are " +"targeted by the toolbar and context-menu commands. The context menu " +"exposes the same commands as the toolbar." +msgstr "" +"La sélection d'une ou de plusieurs lignes détermine les entrées ciblées " +"par les commandes de la barre d'outils et du menu contextuel. Le menu " +"contextuel propose les mêmes commandes que la barre d'outils." -msgid "When an action row is selected, its result object is selected in the corresponding data panel when available; otherwise, its existing input objects are selected. DataLab then switches to that data panel." -msgstr "Lorsqu'une ligne d'action est sélectionnée, son objet résultat est sélectionné dans le panneau de données correspondant s'il est disponible ; sinon, ses objets d'entrée existants sont sélectionnés. DataLab bascule ensuite vers ce panneau de données." +msgid "" +"When an action row is selected, its result object is selected in the " +"corresponding data panel when available; otherwise, its existing input " +"objects are selected. DataLab then switches to that data panel." +msgstr "" +"Lorsqu'une ligne d'action est sélectionnée, son objet résultat est " +"sélectionné dans le panneau de données correspondant s'il est disponible " +"; sinon, ses objets d'entrée existants sont sélectionnés. DataLab bascule" +" ensuite vers ce panneau de données." -msgid "While Record mode is enabled, selecting a session row makes that session active for its data panel." -msgstr "Lorsque le mode d'enregistrement est activé, sélectionner une ligne de session rend cette session active pour son panneau de données." +msgid "" +"While Record mode is enabled, selecting a session row makes that session " +"active for its data panel." +msgstr "" +"Lorsque le mode d'enregistrement est activé, sélectionner une ligne de " +"session rend cette session active pour son panneau de données." -msgid "Actions that are not compatible with the current workspace state (for example because a referenced object identifier no longer exists, or because its data array shape changed) are shown with a disabled foreground and an explanatory tooltip. They cannot be replayed until the workspace matches the recorded state again." -msgstr "Les actions qui ne sont pas compatibles avec l'état courant de l'espace de travail (par exemple parce qu'un identifiant d'objet référencé n'existe plus, ou parce que la forme de son tableau a changé) sont affichées avec un texte désactivé et une infobulle explicative. Elles ne peuvent pas être rejouées tant que l'espace de travail ne correspond pas de nouveau à l'état enregistré." +msgid "" +"Actions that are not compatible with the current workspace state (for " +"example because a referenced object identifier no longer exists, or " +"because its data array shape changed) are shown with a disabled " +"foreground and an explanatory tooltip. They cannot be replayed until the " +"workspace matches the recorded state again." +msgstr "" +"Les actions qui ne sont pas compatibles avec l'état courant de l'espace " +"de travail (par exemple parce qu'un identifiant d'objet référencé " +"n'existe plus, ou parce que la forme de son tableau a changé) sont " +"affichées avec un texte désactivé et une infobulle explicative. Elles ne " +"peuvent pas être rejouées tant que l'espace de travail ne correspond pas " +"de nouveau à l'état enregistré." msgid "Workspace state display" msgstr "Affichage de l'état de l'espace de travail" -msgid "Below the action tree, a split-view widget shows the **workspace state** captured at the time of the selected action:" -msgstr "Sous l'arborescence des actions, un widget en vue divisée affiche l'**état de l'espace de travail** tel qu'il était au moment de l'action sélectionnée :" +msgid "" +"Below the action tree, a split-view widget shows the **workspace state** " +"captured at the time of the selected action:" +msgstr "" +"Sous l'arborescence des actions, un widget en vue divisée affiche " +"l'**état de l'espace de travail** tel qu'il était au moment de l'action " +"sélectionnée :" -msgid "**Left table**: lists the signals that were selected, with their array shape." -msgstr "**Tableau de gauche** : liste les signaux qui étaient sélectionnés, avec la forme de leur tableau." +msgid "" +"**Left table**: lists the signals that were selected, with their array " +"shape." +msgstr "" +"**Tableau de gauche** : liste les signaux qui étaient sélectionnés, avec " +"la forme de leur tableau." -msgid "**Right table**: lists the images that were selected, with their dimensions." -msgstr "**Tableau de droite** : liste les images qui étaient sélectionnées, avec leurs dimensions." +msgid "" +"**Right table**: lists the images that were selected, with their " +"dimensions." +msgstr "" +"**Tableau de droite** : liste les images qui étaient sélectionnées, avec " +"leurs dimensions." -msgid "This information helps the user understand the context in which each action was originally executed and diagnose compatibility issues when replaying the current selection." -msgstr "Ces informations aident l'utilisateur à comprendre le contexte dans lequel chaque action a été exécutée à l'origine et à diagnostiquer les problèmes de compatibilité lors du rejeu de la sélection actuelle." +msgid "" +"This information helps the user understand the context in which each " +"action was originally executed and diagnose compatibility issues when " +"replaying the current selection." +msgstr "" +"Ces informations aident l'utilisateur à comprendre le contexte dans " +"lequel chaque action a été exécutée à l'origine et à diagnostiquer les " +"problèmes de compatibilité lors du rejeu de la sélection actuelle." msgid "Persistence" msgstr "Persistance" @@ -189,44 +451,217 @@ msgstr "Persistance" msgid "The history can be persisted in two complementary ways:" msgstr "L'historique peut être enregistré de deux manières complémentaires :" -msgid "**Embedded in the workspace**: when the workspace is saved to HDF5 (``File > Save to HDF5 file``), the History Panel content is automatically saved alongside the signals and images. Reloading the workspace restores the recorded sessions." -msgstr "**Intégré à l'espace de travail** : lorsque l'espace de travail est enregistré au format HDF5 (``Fichier > Enregistrer dans un fichier HDF5``), le contenu du panneau d'historique est automatiquement sauvegardé aux côtés des signaux et des images. Le rechargement de l'espace de travail restaure les sessions enregistrées." +msgid "" +"**Embedded in the workspace**: when the workspace is saved to HDF5 " +"(``File > Save to HDF5 file``), the History Panel content is " +"automatically saved alongside the signals and images. Reloading the " +"workspace restores the recorded sessions." +msgstr "" +"**Intégré à l'espace de travail** : lorsque l'espace de travail est " +"enregistré au format HDF5 (``Fichier > Enregistrer dans un fichier " +"HDF5``), le contenu du panneau d'historique est automatiquement " +"sauvegardé aux côtés des signaux et des images. Le rechargement de " +"l'espace de travail restaure les sessions enregistrées." -msgid "**Standalone history file** (``.dlhist``): the file embeds both the recorded sessions **and** all objects currently present in both the Signals and Images panels, whether or not an action references them. This makes the file fully self-contained:" -msgstr "**Fichier d'historique autonome** (``.dlhist``) : le fichier embarque à la fois les sessions enregistrées **et** tous les objets actuellement présents dans les panneaux Signaux et Images, qu'une action y fasse référence ou non. Le fichier est ainsi entièrement autonome :" +msgid "" +"**Standalone history file** (``.dlhist``): the file embeds both the " +"recorded sessions **and** all objects currently present in both the " +"Signals and Images panels, whether or not an action references them. This" +" makes the file fully self-contained:" +msgstr "" +"**Fichier d'historique autonome** (``.dlhist``) : le fichier embarque à " +"la fois les sessions enregistrées **et** tous les objets actuellement " +"présents dans les panneaux Signaux et Images, qu'une action y fasse " +"référence ou non. Le fichier est ainsi entièrement autonome :" -msgid "Opening a ``.dlhist`` into a **pristine workspace** (with no data objects and no existing history sessions) restores the saved objects and sessions directly." -msgstr "L'ouverture d'un fichier ``.dlhist`` dans un **espace de travail vierge** (sans objet de données ni session d'historique existante) restaure directement les objets et les sessions enregistrés." +msgid "" +"Opening a ``.dlhist`` into a **pristine workspace** (with no data objects" +" and no existing history sessions) restores the saved objects and " +"sessions directly." +msgstr "" +"L'ouverture d'un fichier ``.dlhist`` dans un **espace de travail vierge**" +" (sans objet de données ni session d'historique existante) restaure " +"directement les objets et les sessions enregistrés." -msgid "If the workspace is **already in use** (it contains any data object or history session), DataLab imports the objects into new signal/image groups, remaps their identifiers to avoid collisions, and appends imported history sessions that reference those fresh identifiers." -msgstr "Si l'espace de travail est **déjà utilisé** (il contient un objet de données ou une session d'historique), DataLab importe les objets dans de nouveaux groupes signal/image, réaffecte leurs identifiants afin d'éviter les collisions et ajoute les sessions d'historique importées qui référencent ces nouveaux identifiants." +msgid "" +"If the workspace is **already in use** (it contains any data object or " +"history session), DataLab imports the objects into new signal/image " +"groups, remaps their identifiers to avoid collisions, and appends " +"imported history sessions that reference those fresh identifiers." +msgstr "" +"Si l'espace de travail est **déjà utilisé** (il contient un objet de " +"données ou une session d'historique), DataLab importe les objets dans de " +"nouveaux groupes signal/image, réaffecte leurs identifiants afin d'éviter" +" les collisions et ajoute les sessions d'historique importées qui " +"référencent ces nouveaux identifiants." -msgid "Replaying a session that depends on external files (e.g. opening a dataset from disk) will only succeed if those files are still available at the same locations as when the session was recorded." -msgstr "Le rejeu d'une session qui dépend de fichiers externes (par exemple l'ouverture d'un jeu de données depuis le disque) ne réussira que si ces fichiers sont toujours disponibles aux mêmes emplacements qu'au moment de l'enregistrement de la session." +msgid "" +"Replaying a session that depends on external files (e.g. opening a " +"dataset from disk) will only succeed if those files are still available " +"at the same locations as when the session was recorded." +msgstr "" +"Le rejeu d'une session qui dépend de fichiers externes (par exemple " +"l'ouverture d'un jeu de données depuis le disque) ne réussira que si ces " +"fichiers sont toujours disponibles aux mêmes emplacements qu'au moment de" +" l'enregistrement de la session." msgid "Chain reconnection on deletion" msgstr "Reconnexion de la chaîne lors d'une suppression" -msgid "When a result object is deleted from the **signal or image panel** (not from the History Panel tree), and that object was produced by a recorded processing step, the History Panel automatically reconnects the processing chain:" -msgstr "Lorsqu'un objet résultat est supprimé depuis le **panneau signal ou image** (et non depuis l'arborescence du panneau d'historique), et que cet objet a été produit par une étape de traitement enregistrée, le panneau d'historique reconnecte automatiquement la chaîne de traitement :" +msgid "" +"When a result object is deleted from the **signal or image panel** (not " +"from the History Panel tree), and that object was produced by a recorded " +"processing step, the History Panel automatically reconnects the " +"processing chain:" +msgstr "" +"Lorsqu'un objet résultat est supprimé depuis le **panneau signal ou " +"image** (et non depuis l'arborescence du panneau d'historique), et que " +"cet objet a été produit par une étape de traitement enregistrée, le " +"panneau d'historique reconnecte automatiquement la chaîne de traitement :" -msgid "All downstream steps that consumed the deleted object are rewired to use the source of the deleted step as their new input." -msgstr "Toutes les étapes aval qui consommaient l'objet supprimé sont recâblées pour utiliser la source de l'étape supprimée comme nouvelle entrée." +msgid "" +"All downstream steps that consumed the deleted object are rewired to use " +"the source of the deleted step as their new input." +msgstr "" +"Toutes les étapes aval qui consommaient l'objet supprimé sont recâblées " +"pour utiliser la source de l'étape supprimée comme nouvelle entrée." -msgid "For ``2_to_1`` operations (e.g. *difference*), the first source is used for reconnection." -msgstr "Pour les opérations ``2_to_1`` (par exemple *différence*), la première source est utilisée pour la reconnexion." +msgid "" +"For ``2_to_1`` operations (e.g. *difference*), the first source is used " +"for reconnection." +msgstr "" +"Pour les opérations ``2_to_1`` (par exemple *différence*), la première " +"source est utilisée pour la reconnexion." -msgid "If no valid source can be determined (e.g. the source itself was already deleted), a warning is displayed listing the unreconnectable operations, but the deletion is allowed to proceed." -msgstr "Si aucune source valide ne peut être déterminée (par exemple la source elle-même a déjà été supprimée), un avertissement est affiché listant les opérations non reconnectables, mais la suppression est néanmoins autorisée." +msgid "" +"If no valid source can be determined (e.g. the source itself was already " +"deleted), a warning is displayed listing the unreconnectable operations, " +"but the deletion is allowed to proceed." +msgstr "" +"Si aucune source valide ne peut être déterminée (par exemple la source " +"elle-même a déjà été supprimée), un avertissement est affiché listant les" +" opérations non reconnectables, mais la suppression est néanmoins " +"autorisée." -msgid "This behaviour mirrors removing a link from a chain: the adjacent links reconnect to preserve the processing flow." -msgstr "Ce comportement reproduit la suppression d'un maillon d'une chaîne : les maillons adjacents se reconnectent pour préserver le flux de traitement." +msgid "" +"This behaviour mirrors removing a link from a chain: the adjacent links " +"reconnect to preserve the processing flow." +msgstr "" +"Ce comportement reproduit la suppression d'un maillon d'une chaîne : les " +"maillons adjacents se reconnectent pour préserver le flux de traitement." -msgid "Reconnection is only triggered by deletions initiated from the signal/image panels. Deleting an action directly from the History Panel tree behaves differently: the selected action is spliced out instead of truncating the session. If downstream steps depend on it, DataLab preserves them as an independent chain by cloning the required intermediate object and reconnecting those steps to the clone. Deleting a session removes that complete session." -msgstr "La reconnexion n'est déclenchée que par les suppressions effectuées depuis les panneaux Signaux ou Images. La suppression d'une action directement depuis l'arborescence du panneau d'historique suit un autre comportement : l'action sélectionnée est retirée de la chaîne au lieu de tronquer la session. Si des étapes en aval en dépendent, DataLab les conserve sous forme de chaîne indépendante en clonant l'objet intermédiaire nécessaire et en reconnectant ces étapes au clone. La suppression d'une session supprime cette session dans son intégralité." +msgid "" +"Reconnection is only triggered by deletions initiated from the " +"signal/image panels. Deleting an action directly from the History Panel " +"tree behaves differently: the selected action is spliced out instead of " +"truncating the session. If downstream steps depend on it, DataLab " +"preserves them as an independent chain by cloning the required " +"intermediate object and reconnecting those steps to the clone. Deleting a" +" session removes that complete session." +msgstr "" +"La reconnexion n'est déclenchée que par les suppressions effectuées " +"depuis les panneaux Signaux ou Images. La suppression d'une action " +"directement depuis l'arborescence du panneau d'historique suit un autre " +"comportement : l'action sélectionnée est retirée de la chaîne au lieu de " +"tronquer la session. Si des étapes en aval en dépendent, DataLab les " +"conserve sous forme de chaîne indépendante en clonant l'objet " +"intermédiaire nécessaire et en reconnectant ces étapes au clone. La " +"suppression d'une session supprime cette session dans son intégralité." msgid "Auto-recompute" msgstr "Recalcul automatique" -msgid "When a result object is selected in the signal/image panel and it has processing parameters (i.e. was produced by a 1-to-1 computation), a **Processing** tab appears in the Properties panel. Checking **Auto-recompute on edit** in that tab will re-run the computation automatically 300 ms after any parameter modification." -msgstr "Lorsqu'un objet résultat est sélectionné dans le panneau signal/image et qu'il possède des paramètres de traitement (c'est-à-dire qu'il a été produit par un calcul 1-à-1), un onglet **Traitement** apparaît dans le panneau Propriétés. Cocher **Recalcul automatique lors de l'édition** dans cet onglet relancera automatiquement le calcul 300 ms après toute modification d'un paramètre." +msgid "" +"When a result object is selected in the signal/image panel and it has " +"processing parameters (i.e. was produced by a 1-to-1 computation), a " +"**Processing** tab appears in the Properties panel. Checking **Auto-" +"recompute on edit** in that tab will re-run the computation automatically" +" 300 ms after any parameter modification." +msgstr "" +"Lorsqu'un objet résultat est sélectionné dans le panneau signal/image et " +"qu'il possède des paramètres de traitement (c'est-à-dire qu'il a été " +"produit par un calcul 1-à-1), un onglet **Traitement** apparaît dans le " +"panneau Propriétés. Cocher **Recalcul automatique lors de l'édition** " +"dans cet onglet relancera automatiquement le calcul 300 ms après toute " +"modification d'un paramètre." + +#~ msgid "" +#~ "**Replayed** silently or **step by " +#~ "step**, with an opportunity to edit " +#~ "available parameters. New outputs from " +#~ "computation actions are not added to " +#~ "the data panels. Recorded UI actions " +#~ "are invoked through their own methods" +#~ " and may reproduce their side " +#~ "effects, including creating, importing, or " +#~ "duplicating objects, unless an action " +#~ "has a specific replay guard;" +#~ msgstr "" +#~ "**rejouée** silencieusement ou **pas à " +#~ "pas**, avec la possibilité de modifier" +#~ " les paramètres disponibles. Les nouvelles" +#~ " sorties des actions de calcul ne " +#~ "sont pas ajoutées aux panneaux de " +#~ "données. Les actions de l'interface " +#~ "enregistrées sont invoquées par leurs " +#~ "propres méthodes et peuvent reproduire " +#~ "leurs effets, notamment créer, importer " +#~ "ou dupliquer des objets, sauf lorsqu'une" +#~ " action dispose d'un mécanisme de " +#~ "protection spécifique lors du rejeu ;" + +#~ msgid "" +#~ "|replay| **Replay**: selecting an action " +#~ "replays that action directly; selecting " +#~ "a session replays the whole session. " +#~ "Compute actions restore their captured " +#~ "input selection when the translated " +#~ "object identifiers are compatible and " +#~ "resolvable; UI actions are replayed " +#~ "without restoring their recorded workspace " +#~ "selection. New objects returned by " +#~ "computation actions are not added to " +#~ "the data panels. Recorded UI actions " +#~ "may reproduce side effects, including " +#~ "creating, importing, or duplicating objects," +#~ " unless an action has a specific " +#~ "replay guard." +#~ msgstr "" +#~ "|replay| **Rejouer** : sélectionner une " +#~ "action rejoue directement cette action ;" +#~ " sélectionner une session rejoue toute " +#~ "la session. Les actions de calcul " +#~ "restaurent leur sélection d'entrées capturée" +#~ " lorsque les identifiants d'objets remappés" +#~ " sont compatibles et peuvent être " +#~ "résolus ; les actions de l'interface " +#~ "sont rejouées sans restaurer au " +#~ "préalable leur sélection de l'espace de" +#~ " travail enregistrée. Les nouveaux objets" +#~ " renvoyés par les actions de calcul" +#~ " ne sont pas ajoutés aux panneaux " +#~ "de données. Les actions de l'interface" +#~ " enregistrées peuvent reproduire des " +#~ "effets, notamment créer, importer ou " +#~ "dupliquer des objets, sauf lorsqu'une " +#~ "action dispose d'un mécanisme de " +#~ "protection spécifique lors du rejeu." + +#~ msgid "" +#~ "|step_by_step| **Step-by-step**: replay " +#~ "the selection one step at a time." +#~ " Parameters may be reviewed and " +#~ "edited when the action supports it; " +#~ "supported actions and their dependent " +#~ "branches are then updated or recomputed" +#~ " in place." +#~ msgstr "" +#~ "|step_by_step| **Pas à pas** : rejoue" +#~ " la sélection pas à pas. Les " +#~ "paramètres peuvent être examinés et " +#~ "modifiés lorsque l'action le permet ;" +#~ " les actions prises en charge et " +#~ "leurs branches dépendantes sont alors " +#~ "mises à jour ou recalculées sur " +#~ "place." + diff --git a/doc/locale/fr/LC_MESSAGES/requirements.po b/doc/locale/fr/LC_MESSAGES/requirements.po index 9686e4201..1c822e5bb 100644 --- a/doc/locale/fr/LC_MESSAGES/requirements.po +++ b/doc/locale/fr/LC_MESSAGES/requirements.po @@ -6,11 +6,18 @@ #, fuzzy msgid "" msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2026-08-05 10:58+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language: fr\n" +"Language-Team: fr <LL@li.org>\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.18.0\n" msgid "The `datalab-platform` package requires the following Python modules:" msgstr "Le paquet `datalab-platform` nécessite les modules Python suivants :" @@ -40,7 +47,9 @@ msgid ">= 3.14.4" msgstr "" msgid "Automatic GUI generation for easy dataset editing and display" -msgstr "Génération automatique d'interface graphique pour l'édition et l'affichage de jeux de données" +msgstr "" +"Génération automatique d'interface graphique pour l'édition et " +"l'affichage de jeux de données" msgid "PlotPy" msgstr "" @@ -54,10 +63,12 @@ msgstr "Outils de tracé de courbes et d'images pour les applications Python/Qt" msgid "Sigima" msgstr "" -msgid ">= 1.1.4" +msgid ">= 1.1.6" msgstr "" -msgid "Scientific computing engine for 1D signals and 2D images, part of the DataLab open-source platform." +msgid "" +"Scientific computing engine for 1D signals and 2D images, part of the " +"DataLab open-source platform." msgstr "" msgid "NumPy" @@ -129,7 +140,9 @@ msgstr "" msgid ">= 0.110.0" msgstr "" -msgid "FastAPI framework, high performance, easy to learn, fast to code, ready for production" +msgid "" +"FastAPI framework, high performance, easy to learn, fast to code, ready " +"for production" msgstr "" msgid "uvicorn[standard]" @@ -190,7 +203,9 @@ msgid "ruff" msgstr "" msgid "An extremely fast Python linter and code formatter, written in Rust." -msgstr "Analyseur de code et formateur de code Python extrêmement rapide, écrit en Rust." +msgstr "" +"Analyseur de code et formateur de code Python extrêmement rapide, écrit " +"en Rust." msgid "pre-commit" msgstr "" @@ -211,7 +226,9 @@ msgid "sphinx_intl" msgstr "" msgid "Sphinx utility that make it easy to translate and to apply translation." -msgstr "Utilitaire Sphinx qui facilite la traduction et l'application de la traduction." +msgstr "" +"Utilitaire Sphinx qui facilite la traduction et l'application de la " +"traduction." msgid "sphinx-sitemap" msgstr "" @@ -228,8 +245,12 @@ msgstr "Un analyseur étendu compatible [CommonMark](https://spec.commonmark.org msgid "sphinx_design" msgstr "" -msgid "A sphinx extension for designing beautiful, view size responsive web components." -msgstr "Une extension sphinx pour concevoir des composants web soignés et adaptés à la taille de l'écran." +msgid "" +"A sphinx extension for designing beautiful, view size responsive web " +"components." +msgstr "" +"Une extension sphinx pour concevoir des composants web soignés et adaptés" +" à la taille de l'écran." msgid "sphinx-copybutton" msgstr "" @@ -267,3 +288,6 @@ msgstr "" msgid "The next generation HTTP client." msgstr "" +#~ msgid ">= 1.1.4" +#~ msgstr "" + From 46de55b261ffaa8dbf797f32dcf7e30854a51dea Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Wed, 5 Aug 2026 19:32:16 +0200 Subject: [PATCH 073/108] Fix: Restore in History panel leaves stale actions outdated In edit mode, restoring an action or session only recomputed actions that had pending parameter edits, so actions previously marked stale (orange) stayed outdated even after a successful restore. Similarly, cancelling a dialog during a step-by-step replay rolled back parameter edits but left the already-recomputed downstream actions marked stale, with no way to bring the chain back up to date short of a full replay. Restore now recomputes every targeted action unconditionally so stale markers are cleared on success, and the step-by-step cancel path silently recomputes the stale actions in the selection after rolling back edits. In both paths, cascade warnings are flushed and the UI state refreshed even if a recompute fails. * [FIX] : Recompute every targeted action in restore_action_params, even without pending parameter edits, so stale markers are cleared on success; flush cascade warnings and update the actions state in a try/finally * [FIX] : Silently recompute stale actions in the selection after a step-by-step dialog cancel, via the new _recompute_stale_actions helper (also resolves excessive nesting reported by pylint) * [CHG] : Add regression test test_restore_recomputes_stale_action_without_pending_edits * [DOC] : Document the step-by-step cancel behavior in the History panel documentation and update the French translation; update UI translation catalog (reworded "Active recording session" tooltip, fuzzy cleanup) and refresh sphinx-intl line references --- .../gui/panel/history/interactive_replay.py | 53 +- datalab/locale/fr/LC_MESSAGES/datalab.po | 900 ++++---- .../features/common/history_workflow_test.py | 23 + doc/features/common/historypanel.rst | 5 +- .../features/common/historypanel.po | 81 +- .../LC_MESSAGES/features/validation/status.po | 2051 +++++++++++++++-- .../fr/LC_MESSAGES/intro/installation.po | 433 +++- .../LC_MESSAGES/intro/tutorials/laser_beam.po | 507 +++- 8 files changed, 3151 insertions(+), 902 deletions(-) diff --git a/datalab/gui/panel/history/interactive_replay.py b/datalab/gui/panel/history/interactive_replay.py index 1a0d1c0cf..37edf70a2 100644 --- a/datalab/gui/panel/history/interactive_replay.py +++ b/datalab/gui/panel/history/interactive_replay.py @@ -110,6 +110,25 @@ def prompt_edit_action_params( return True +def _recompute_stale_actions(panel: HistoryPanel, ordered: list[HistoryAction]) -> None: + """Recompute stale actions in place after a dialog rollback. + + Args: + panel: History panel instance + ordered: Selected actions in session order + """ + stale_actions = [a for a in ordered if a.is_stale] + if not stale_actions: + return + try: + for stale_action in stale_actions: + success = hrec.recompute_action_in_place(panel, stale_action) + stale_action.is_stale = not success + panel.tree.refresh_action_item(stale_action) + finally: + hrec.flush_cascade_warnings(panel) + + def replay_actions( panel: HistoryPanel, actions: list[HistoryAction], prompt: bool = True ) -> None: @@ -175,6 +194,7 @@ def replay_actions( selected_action.kwargs = kwargs selected_action.saved_kwargs = saved_kwargs panel.tree.refresh_action_item(selected_action) + _recompute_stale_actions(panel, ordered) return if result is True: edited_actions.append(action) @@ -241,7 +261,11 @@ def order_selected_actions( def restore_action_params( panel: HistoryPanel, item: HistoryAction | HistorySession ) -> None: - """Restore original kwargs from snapshot and recompute in-place.""" + """Restore original kwargs from snapshot and recompute in-place. + + Every targeted action is recomputed unconditionally, even when it has no + pending parameter edits, so that stale markers are cleared on success. + """ actions: list[HistoryAction] if isinstance(item, HistorySession): actions = [ @@ -255,16 +279,17 @@ def restore_action_params( ] else: actions = [item] - for action in actions: - if not action.has_pending_edits: - continue - action.restore_kwargs() - panel.tree.refresh_action_item(action) - success = hrec.recompute_action_in_place(panel, action) - action.is_stale = not success - panel.tree.refresh_action_item(action) - if not success: - break - if not isinstance(item, HistorySession): - hrec.recompute_cascade(panel, action) - panel.ui.update_actions_state() + try: + for action in actions: + action.restore_kwargs() + panel.tree.refresh_action_item(action) + success = hrec.recompute_action_in_place(panel, action) + action.is_stale = not success + panel.tree.refresh_action_item(action) + if not success: + break + if not isinstance(item, HistorySession): + hrec.recompute_cascade(panel, action) + finally: + hrec.flush_cascade_warnings(panel) + panel.ui.update_actions_state() diff --git a/datalab/locale/fr/LC_MESSAGES/datalab.po b/datalab/locale/fr/LC_MESSAGES/datalab.po index a1ac503ff..fbfa2f9e6 100644 --- a/datalab/locale/fr/LC_MESSAGES/datalab.po +++ b/datalab/locale/fr/LC_MESSAGES/datalab.po @@ -374,6 +374,12 @@ msgstr "Sélectionner le ou les objets source utilisés pour créer l'objet %s s msgid "Edit title of selected %s or group" msgstr "Modifier le titre de l'objet %s ou du groupe sélectionné" +msgid "Reset to computed title" +msgstr "Réinitialiser au titre calculé" + +msgid "Restore the title generated by the processing operation" +msgstr "Restaurer le titre généré par l'opération de traitement" + msgid "New group..." msgstr "Nouveau groupe..." @@ -949,9 +955,6 @@ msgstr "Tapez pour rechercher une commande…" msgid "Search a command…" msgstr "Rechercher une commande…" -msgid "Custom signal" -msgstr "Signal personnalisé" - msgid "Process signal" msgstr "Traiter le signal" @@ -965,46 +968,6 @@ msgstr "Troncature de données uint32 en int32." msgid "No supported data available in HDF5 file(s)." msgstr "Aucune donnée prise en charge dans le(s) fichier(s) HDF5." -msgid "A new object was loaded. Start a new history session?" -msgstr "Un nouvel objet a été chargé. Démarrer une nouvelle session d'historique ?" - -msgid "A new object was created. Start a new history session?" -msgstr "Un nouvel objet a été créé. Démarrer une nouvelle session d'historique ?" - -msgid "New history session" -msgstr "Nouvelle session d'historique" - -msgid "Initial state" -msgstr "État initial" - -msgid "Chain copy" -msgstr "Copie de chaîne" - -msgid "" -"Do you really want to delete the selected items?\n" -"\n" -"Note: deleting an intermediate action splits its processing chain; downstream steps become an independent chain." -msgstr "" -"Êtes-vous sûr de vouloir supprimer les éléments sélectionnés ?\n" -"\n" -"Remarque : la suppression d'une action intermédiaire divise sa chaîne de traitement ; les étapes en aval deviennent une chaîne indépendante." - -msgid "Do you really want to delete the selected items?" -msgstr "Êtes-vous sûr de vouloir supprimer le(s) groupe(s) sélectionné(s) ?" - -msgid "The deleted action(s) produced object(s) still present in the workspace. Do you want to remove the associated object(s) as well?" -msgstr "La ou les actions supprimées ont produit des objets encore présents dans l'espace de travail. Voulez-vous également supprimer le ou les objets associés ?" - -msgid "Remove incompatible" -msgstr "Supprimer les actions incompatibles" - -msgid "All actions are compatible with the current workspace." -msgstr "Toutes les actions sont compatibles avec l'espace de travail actuel." - -#, python-format -msgid "%d incompatible action(s) will be removed. Continue?" -msgstr "%d action(s) incompatible(s) seront supprimées. Continuer ?" - msgid "Macro simple example" msgstr "Exemple simple de macro" @@ -1251,9 +1214,6 @@ msgstr "Console" msgid "Macro Panel" msgstr "Gestionnaire de Macros" -msgid "History Panel" -msgstr "Historique" - msgid "Disable auto-refresh?" msgstr "Désactiver le rafraîchissement automatique ?" @@ -1291,17 +1251,6 @@ msgstr "Ouvrir" msgid "HDF5 files (*.h5 *.hdf5 *.hdf *.he5);;All files (*)" msgstr "Fichiers HDF5 (*.h5 *.hdf5 *.hdf *.he5);;Tous les fichiers (*)" -#, python-format -msgid "Open %d HDF5 files" -msgstr "Ouvrir %d fichiers HDF5" - -msgid "Open HDF5 file" -msgstr "Ouvrir un fichier HDF5" - -#, python-format -msgid "New %s" -msgstr "Créer un nouvel objet %s" - msgid "not started" msgstr "non démarré" @@ -1365,6 +1314,9 @@ msgstr "Modifier la courbe graphiquement" msgid "Insert point" msgstr "Insérer un point" +msgid "Custom signal" +msgstr "Signal personnalisé" + msgid "Object metadata" msgstr "Métadonnées de l'objet" @@ -1377,6 +1329,12 @@ msgstr "groupe" msgid "Source objects" msgstr "Objets source" +msgid "deleted" +msgstr "supprimé" + +msgid "Deleted source objects" +msgstr "Objets source supprimés" + msgid "Drag files here to open" msgstr "Déposer des fichiers ici pour les ouvrir" @@ -1448,6 +1406,15 @@ msgstr "" "Échec de la conversion des paramètres de création historiques :\n" "%s" +msgid "Signal was modified in-place." +msgstr "Le signal a été modifié en place." + +msgid "Image was modified in-place." +msgstr "L'image a été modifiée en place." + +msgid "If computation were performed based on this object, they may need to be redone." +msgstr "Si des calculs ont été effectués à partir de cet objet, il peut être nécessaire de les refaire." + #, python-format msgid "" "Failed to recreate object with new parameters:\n" @@ -1456,67 +1423,12 @@ msgstr "" "Échec de la recréation de l'objet avec les nouveaux paramètres :\n" "%s" -msgid "Signal was recreated." -msgstr "Le signal a été recréé." - -msgid "Image was recreated." -msgstr "L'image a été recréée." - msgid "Processing Parameters" msgstr "Paramètres de traitement" -msgid "Auto-recompute on edit" -msgstr "Recalcul automatique lors de l'édition" - -msgid "Automatically re-run processing when parameters are modified" -msgstr "Relancer automatiquement le traitement à chaque modification de paramètre" - -msgid "Analysis Parameters" -msgstr "Paramètres d'analyse" - -msgid "Analysis metadata is incomplete." -msgstr "Les métadonnées d'analyse sont incomplètes." - -#, python-format -msgid "" -"Failed to recompute analysis:\n" -"%s" -msgstr "" -"Échec du recalcul de l'analyse :\n" -"%s" - -msgid "Failed to recompute analysis." -msgstr "Échec du recalcul de l'analyse." - -msgid "Analysis was recomputed." -msgstr "L'analyse a été recalculée." - msgid "No processing object available." msgstr "Aucun objet de traitement disponible." -msgid "Processing metadata is incomplete." -msgstr "Les métadonnées de traitement sont incomplètes." - -msgid "Source object no longer exists." -msgstr "L'objet source n'existe plus." - -msgid "The object that was used to create this processed object has been deleted and cannot be used for reprocessing." -msgstr "L'objet qui a été utilisé pour créer cet objet traité a été supprimé et ne peut pas être utilisé pour le retraitement." - -#, python-format -msgid "" -"Failed to reprocess object:\n" -"%s" -msgstr "" -"Échec du retraitement de l'objet :\n" -"%s" - -msgid "Processing was cancelled." -msgstr "Le traitement a été annulé." - -msgid "Failed to reprocess object." -msgstr "Échec du retraitement de l'objet." - msgid "Geometry results" msgstr "Résultats géométriques" @@ -1529,9 +1441,6 @@ msgstr "Autres métadonnées" msgid "Save to directory" msgstr "Enregistrer dans un répertoire" -msgid "Pattern help" -msgstr "Aide sur le motif" - msgid "Directory" msgstr "Répertoire" @@ -1583,9 +1492,6 @@ msgstr "Modèle de valeur" msgid "Conversion" msgstr "Conversion" -msgid "Duplicate object or group" -msgstr "Dupliquer l'objet ou le groupe" - msgid "Select what to keep from the clipboard.<br><br>Result shapes and annotations, if kept, will be merged with existing ones. <u>All other metadata will be replaced</u>." msgstr "Sélectionnez ce que vous souhaitez conserver dans le presse-papier.<br><br>Les formes graphiques et les annotations, si conservées, seront fusionnées avec celles existantes. <u>Toutes les autres métadonnées seront remplacées</u>." @@ -1595,9 +1501,6 @@ msgstr "Supprimer le(s) groupe(s)" msgid "Are you sure you want to delete the selected group(s)?" msgstr "Êtes-vous sûr de vouloir supprimer le(s) groupe(s) sélectionné(s) ?" -msgid "Remove selected objects" -msgstr "Supprimer les objets sélectionnés" - #, python-format msgid "Do you want to delete all objects (%s)?" msgstr "Souhaitez-vous supprimer tous les objets (%s) ?" @@ -1608,18 +1511,11 @@ msgstr "Supprimer les métadonnées" msgid "Some selected objects have regions of interest.<br>Do you want to delete them as well?" msgstr "Certains objets sélectionnés ont des régions d'intérêt.<br>Souhaitez-vous les supprimer également ?" -msgid "New group" -msgstr "Nouveau groupe" - msgid "Group name:" msgstr "Nom du groupe :" -#, python-format -msgid "New group \"%s\"" -msgstr "Nouveau groupe \"%s\"" - -msgid "Rename selected object or group" -msgstr "Renommer l'objet ou le groupe sélectionné" +msgid "New group" +msgstr "Nouveau groupe" msgid "Rename object" msgstr "Renommer l'objet" @@ -1630,10 +1526,6 @@ msgstr "Nom de l'objet :" msgid "Rename group" msgstr "Renommer le groupe" -#, python-format -msgid "Set current object title to \"%s\"" -msgstr "Définir le titre de l'objet courant à \"%s\"" - msgid "Reading objects from file" msgstr "Lecture des objets depuis le fichier" @@ -1643,25 +1535,9 @@ msgstr "Ajout d'objets à l'espace de travail" msgid "Scanning directory" msgstr "Analyse du répertoire" -#, python-format -msgid "Load from %d files" -msgstr "Charger depuis %d fichiers" - -#, python-format -msgid "Load \"%s\"" -msgstr "Charger \"%s\"" - msgid "Save as" msgstr "Enregistrer sous" -#, python-format -msgid "Save to %d different files" -msgstr "Enregistrer dans %d fichiers différents" - -#, python-format -msgid "Save to \"%s\"" -msgstr "Enregistrer dans \"%s\"" - msgid "Saving..." msgstr "Enregistrement en cours..." @@ -1686,18 +1562,15 @@ msgstr "Souhaitez-vous continuer avec l'objet suivant ?" msgid "Recomputing analyses" msgstr "Recalcul des analyses" -msgid "Analysis computation failed." -msgstr "Le calcul de l'analyse a échoué." - -msgid "Failed to recompute analysis" -msgstr "Échec du recalcul de l'analyse" - msgid "Selected object does not have processing metadata." msgstr "L'objet sélectionné n'a pas de métadonnées de traitement." msgid "Selected object does not have source object references." msgstr "L'objet sélectionné n'a pas de références d'objet source." +msgid "Source object no longer exists." +msgstr "L'objet source n'existe plus." + msgid "Source objects no longer exist." msgstr "Les objets source n'existent plus." @@ -1749,203 +1622,50 @@ msgstr "Tous les objets associés aux résultats doivent avoir les mêmes ROIs p msgid "Are you sure you want to delete all results of the selected object(s)?" msgstr "Êtes-vous sûr de vouloir supprimer tous les résultats des objets sélectionnés ?" -msgid "Add object title to plot" -msgstr "Ajouter le titre de l'objet au graphique" - -msgid "Add label with title" -msgstr "Ajouter une étiquette avec le titre" - msgid "Annotation added" msgstr "Annotation ajoutée" msgid "The label has been added as an annotation. You can edit or remove it using the annotation editing window.<br><br>Choosing to ignore this message will prevent it from being displayed again." msgstr "L'étiquette a été ajoutée comme annotation. Vous pouvez la modifier ou la supprimer en utilisant la fenêtre d'édition des annotations.<br><br>Ignorer ce message empêchera son affichage ultérieur." -#, python-format -msgid "“%s” has dependent operations but no valid source to reconnect to — downstream results are left unchanged." -msgstr "« %s » possède des opérations dépendantes mais aucune source valide à laquelle se reconnecter — les résultats en aval restent inchangés." +msgid "Recent macros" +msgstr "Macros récentes" -msgid "Some operations could not be reconnected after deletion:" -msgstr "Certaines opérations n'ont pas pu être reconnectées après la suppression :" +msgid "Clear all" +msgstr "Tout effacer" -msgid "Commit edit mode changes?" -msgstr "Valider les modifications du mode d'édition ?" +msgid "Untitled" +msgstr "Sans titre" -msgid "" -"You are about to exit Edit mode.\n" -"\n" -"All parameter changes made during this session will be permanently kept.\n" -"This action cannot be undone — Restore will no longer be available.\n" -"\n" -"Do you want to continue?" -msgstr "" -"Vous êtes sur le point de quitter le mode d'édition.\n" -"\n" -"Toutes les modifications de paramètres effectuées lors de cette session seront conservées de façon permanente.\n" -"Cette action est irréversible — la fonction Restaurer ne sera plus disponible.\n" -"\n" -"Souhaitez-vous continuer ?" +msgid "Clear all recent macros?" +msgstr "Effacer toutes les macros récentes ?" -msgid "The current workspace state is not compatible with the action." -msgstr "L'état actuel de l'espace de travail n'est pas compatible avec l'action." +msgid "Macro panel" +msgstr "Panneau des macros" -msgid "Parameters" -msgstr "Paramètres" +msgid "Python files" +msgstr "Fichiers Python" -#, python-format -msgid "Action %s has no recorded pattern and cannot be replayed." -msgstr "L'action %s n'a pas de motif enregistré et ne peut pas être rejouée." +msgid "Clear console" +msgstr "Effacer la console" -msgid "History panel" -msgstr "Panneau d'historique" +msgid "-***- Macro Console -***-" +msgstr "-***- Console des macros -***-" -msgid "History files" -msgstr "Fichiers d'historique" +msgid "Run macro" +msgstr "Exécuter la macro" -#, python-format -msgid "Action %s has been edited but its target output object(s) no longer exist — skipping." -msgstr "L'action %s a été modifiée mais son ou ses objets de sortie cibles n'existent plus — ignorée." +msgid "Stop macro" +msgstr "Arrêter la macro" -#, python-format -msgid "Action %s uses pattern %r which is not recomputable yet." -msgstr "L'action %s utilise le motif %r qui n'est pas encore recalculable." +msgid "New macro" +msgstr "Nouvelle macro" -#, python-format -msgid "Action %s could not be fully recomputed." -msgstr "L'action %s n'a pas pu être entièrement recalculée." +msgid "Rename macro" +msgstr "Renommer la macro" -#, python-format -msgid "Recompute failed for action %s: %s" -msgstr "Échec du recalcul pour l'action %s : %s" - -#, python-format -msgid "" -"Action %(name)s skipped: plugin '%(loc)s' is missing.\n" -"Required parameter class: %(param)s\n" -"Reinstall the plugin to re-enable this action." -msgstr "" -"Action %(name)s ignorée : le plugin '%(loc)s' est manquant.\n" -"Classe de paramètre requise : %(param)s\n" -"Réinstallez le plugin pour réactiver cette action." - -#, python-format -msgid "Action %s: source object was deleted — skipping." -msgstr "Action %s : l'objet source a été supprimé — ignorée." - -#, python-format -msgid "Action %s: recompute returned %d output(s), expected %d." -msgstr "Action %s : le recalcul a renvoyé %d sortie(s), %d attendue(s)." - -#, python-format -msgid "Action %s: source object(s) were deleted — skipping." -msgstr "Action %s : le ou les objets source ont été supprimés — ignorée." - -#, python-format -msgid "Action %s: missing source(s) for output #%d — skipping." -msgstr "Action %s : source(s) manquante(s) pour la sortie n°%d — ignorée." - -#, python-format -msgid "Action %s: %d analysed object(s) were deleted — skipping." -msgstr "Action %s : %d objet(s) analysé(s) ont été supprimés — ignorée." - -msgid "Cascade recompute" -msgstr "Recalcul en cascade" - -msgid "Some downstream actions could not be recomputed:" -msgstr "Certaines actions en aval n'ont pas pu être recalculées :" - -msgid "Record mode" -msgstr "Mode d'enregistrement" - -msgid "New session" -msgstr "Nouvelle session" - -msgid "Start a new history session" -msgstr "Démarrer une nouvelle session d'historique" - -msgid "Open history file..." -msgstr "Ouvrir un fichier d'historique..." - -msgid "Open history from a standalone .dlhist file" -msgstr "Ouvrir l'historique depuis un fichier .dlhist autonome" - -msgid "Save history file..." -msgstr "Enregistrer un fichier d'historique..." - -msgid "Save history to a standalone .dlhist file" -msgstr "Enregistrer l'historique dans un fichier .dlhist autonome" - -msgid "Duplicate selected history action/session" -msgstr "Dupliquer l'action ou la session d'historique sélectionnée" - -msgid "Previous step" -msgstr "Étape précédente" - -msgid "Select the previous action in the current session" -msgstr "Sélectionner l'action précédente dans la session courante" - -msgid "Next step" -msgstr "Étape suivante" - -msgid "Select the next action in the current session" -msgstr "Sélectionner l'action suivante dans la session courante" - -msgid "Remove actions incompatible with the current workspace" -msgstr "Supprimer les actions incompatibles avec l'espace de travail courant" - -msgid "Replay" -msgstr "Rejouer" - -msgid "Replay the selection silently (no parameter dialogs)" -msgstr "Rejouer la sélection silencieusement (sans boîtes de dialogue de paramètres)" - -msgid "Step-by-step" -msgstr "Pas à pas" - -msgid "Replay the selection step by step, editing parameters at each step" -msgstr "Rejouer la sélection pas à pas, en modifiant les paramètres à chaque étape" - -msgid "New image" -msgstr "Nouvelle image" - -msgid "Recent macros" -msgstr "Macros récentes" - -msgid "Clear all" -msgstr "Tout effacer" - -msgid "Untitled" -msgstr "Sans titre" - -msgid "Clear all recent macros?" -msgstr "Effacer toutes les macros récentes ?" - -msgid "Macro panel" -msgstr "Panneau des macros" - -msgid "Python files" -msgstr "Fichiers Python" - -msgid "Clear console" -msgstr "Effacer la console" - -msgid "-***- Macro Console -***-" -msgstr "-***- Console des macros -***-" - -msgid "Run macro" -msgstr "Exécuter la macro" - -msgid "Stop macro" -msgstr "Arrêter la macro" - -msgid "New macro" -msgstr "Nouvelle macro" - -msgid "Rename macro" -msgstr "Renommer la macro" - -msgid "Duplicate macro" -msgstr "Dupliquer la macro" +msgid "Duplicate macro" +msgstr "Dupliquer la macro" msgid "Import macro from file" msgstr "Importer la macro depuis un fichier" @@ -2001,9 +1721,6 @@ msgstr "Lorsqu'elle est fermée, une macro est <u>détruite de manière définit msgid "Do you want to continue?" msgstr "Souhaitez-vous vraiment continuer ?" -msgid "New signal" -msgstr "Nouveau signal" - msgid "Creating geometric shapes" msgstr "Création des formes géométriques" @@ -2154,9 +1871,29 @@ msgstr "" msgid "Yes to All" msgstr "Oui à tout" +msgid "Processing metadata is incomplete." +msgstr "Les métadonnées de traitement sont incomplètes." + msgid "Processing metadata is incomplete (missing source UUID)." msgstr "Les métadonnées de traitement sont incomplètes (UUID source manquant)." +msgid "The object that was used to create this processed object has been deleted and cannot be used for reprocessing." +msgstr "L'objet qui a été utilisé pour créer cet objet traité a été supprimé et ne peut pas être utilisé pour le retraitement." + +#, python-format +msgid "" +"Failed to reprocess object:\n" +"%s" +msgstr "" +"Échec du retraitement de l'objet :\n" +"%s" + +msgid "Processing was cancelled." +msgstr "Le traitement a été annulé." + +msgid "Failed to reprocess object." +msgstr "Échec du retraitement de l'objet." + msgid "Signal was reprocessed." msgstr "Le signal a été retraité." @@ -2182,6 +1919,9 @@ msgstr "En mode 'pairwise', vous devez sélectionner des objets dans au moins de msgid "In pairwise mode, you need to select the same number of objects in each group." msgstr "En mode 'pairwise', vous devez sélectionner le même nombre d'objets dans chaque groupe." +msgid "Parameters" +msgstr "Paramètres" + #, python-format msgid "Calculating: %s" msgstr "Calcul : %s" @@ -3136,42 +2876,6 @@ msgstr "Interpoler systématiquement" msgid "Behavior when X-axis arrays are incompatible in multi-signal computations:<ul><li><b>Ask</b>: display confirmation dialog (default)</li><li><b>Interpolate</b>: automatically interpolate signals</li></ul>" msgstr "Comportement lorsque les tableaux des X sont incompatibles dans les calculs multi-signaux :<ul><li><b>Demander</b> : afficher une boîte de dialogue de confirmation (par défaut)</li><li><b>Interpoler</b> : interpoler automatiquement les signaux</li></ul>" -msgid "History sessions" -msgstr "Sessions d'historique" - -msgid "New object or file" -msgstr "Nouvel objet ou fichier" - -msgid "Ask" -msgstr "Demander" - -msgid "Always start a new session" -msgstr "Toujours démarrer une nouvelle session" - -msgid "Continue in the current session" -msgstr "Continuer dans la session courante" - -msgid "Behavior when a new object or file is added to a populated history session." -msgstr "Comportement lorsqu'un nouvel objet ou fichier est ajouté à une session d'historique non vide." - -msgid "Plugin-created object" -msgstr "Objet créé par un plugin" - -msgid "Behavior when a plugin adds an object to a populated history session." -msgstr "Comportement lorsqu'un plugin ajoute un objet à une session d'historique non vide." - -msgid "Plugin multi-load" -msgstr "Chargement multiple par un plugin" - -msgid "Ask once" -msgstr "Demander une seule fois" - -msgid "Start a new session" -msgstr "Démarrer une nouvelle session" - -msgid "Behavior when a plugin loads multiple objects into a populated history session." -msgstr "Comportement lorsqu'un plugin charge plusieurs objets dans une session d'historique non vide." - msgid "Settings for results management" msgstr "Réglages de la gestion des résultats" @@ -3190,6 +2894,18 @@ msgstr "Afficher automatiquement la boîte de dialogue des résultats après le msgid "If enabled, the results dialog will be shown automatically after each processing operation producing results.<br>If disabled, the results dialog will not be shown automatically." msgstr "Si activé, la boîte de dialogue des résultats sera affichée automatiquement après chaque opération de traitement produisant des résultats.<br>Si désactivé, la boîte de dialogue des résultats ne sera pas affichée automatiquement." +msgid "Result titles" +msgstr "Titres des résultats" + +msgid "Source object short identifier" +msgstr "Identifiant court de l'objet source" + +msgid "Source object title" +msgstr "Titre de l'objet source" + +msgid "How source objects are referenced in result titles after a computation (display only):<ul><li><b>Short identifier</b>: e.g. <i>fft(s001)</i> (default)</li><li><b>Title</b>: e.g. <i>fft(My signal)</i></li></ul>Result titles update automatically when a source object is renamed." +msgstr "Manière dont les objets source sont référencés dans les titres des résultats après un calcul (affichage uniquement) :<ul><li><b>Identifiant court</b> : par ex. <i>fft(s001)</i> (par défaut)</li><li><b>Titre</b> : par ex. <i>fft(Mon signal)</i></li></ul>Les titres des résultats sont mis à jour automatiquement lorsqu'un objet source est renommé." + msgid "Default image visualization settings" msgstr "Réglages d'affichage d'images par défaut" @@ -3528,23 +3244,6 @@ msgstr "C'est la fin de la visite guidée !" msgid "You can show the tour again, or close this dialog box." msgstr "Vous pouvez afficher la visite guidée à nouveau, ou fermer cette boîte de dialogue." -msgid "Save history file" -msgstr "Enregistrer un fichier d'historique" - -msgid "Open history file" -msgstr "Ouvrir un fichier d'historique" - -msgid "Imported" -msgstr "Importé" - -#, python-format -msgid "Failed to deserialize history DataSet kwarg %r." -msgstr "Échec de la désérialisation de l'argument DataSet de l'historique %r." - -#, python-format -msgid "Failed to deserialize history DataSet-list kwarg %r." -msgstr "Échec de la désérialisation de l'argument DataSet-list de l'historique %r." - msgid "Registered plugins:" msgstr "Plugins enregistrés :" @@ -3686,12 +3385,12 @@ msgstr "Cliquer sur OK pour démarrer la démo.<br><br><u>Note :</u><br>- La dé msgid "Click OK to end demo." msgstr "Cliquer sur OK pour terminer la démo." -msgid "Error:" -msgstr "Erreur:" - msgid "Context" msgstr "Contexte" +msgid "Error:" +msgstr "Erreur:" + #, python-format msgid "The file %s could not be read:" msgstr "Le fichier %s n'a pas pu être ouvert :" @@ -3908,18 +3607,18 @@ msgstr "Déplier la sélection" msgid "HDF5 Browser" msgstr "Explorateur HDF5" -msgid "Size" -msgstr "Taille" - -msgid "Type" -msgstr "Type" - msgid "Value" msgstr "Valeur" msgid "Name" msgstr "Nom" +msgid "Size" +msgstr "Taille" + +msgid "Type" +msgstr "Type" + msgid "Unsupported data" msgstr "Données non prises en charge" @@ -3956,28 +3655,6 @@ msgstr "Afficher uniquement les données prises en charge" msgid "Show values" msgstr "Afficher les valeurs" -msgid "Show details" -msgstr "Afficher les détails" - -msgid "Hide details" -msgstr "Masquer les détails" - -msgid "Date and time" -msgstr "Date et heure" - -msgid "Title" -msgstr "Titre" - -msgid "Action is compatible with the current workspace state." -msgstr "L'action est compatible avec l'état actuel de l'espace de travail." - -msgid "Action is not compatible with the current workspace state." -msgstr "L'action n'est pas compatible avec l'état actuel de l'espace de travail." - -#, python-brace-format -msgid "Active recording session ({panel})." -msgstr "Session d'enregistrement active ({panel})." - msgid "Image background selection" msgstr "Sélection de l'arrière-plan de l'image" @@ -4262,6 +3939,9 @@ msgstr "Tout sélectionner" msgid "Adding data to the plot" msgstr "Ajout des données au graphique" +msgid "Title" +msgstr "Titre" + msgid "X label" msgstr "Titre X" @@ -4352,18 +4032,6 @@ msgstr "Merci de sélectionner le fichier à importer." msgid "Example Wizard" msgstr "Assistant exemple" -msgid "Signal" -msgstr "Signal" - -msgid "Shape" -msgstr "Forme" - -msgid "Image" -msgstr "Image" - -msgid "Dimensions" -msgstr "Dimensions" - msgid "Minimum value" msgstr "Valeur minimum" @@ -4412,3 +4080,367 @@ msgstr "Aucun contour n'a été trouvé pour la plage de niveaux sélectionnée. msgid "Show contour plot..." msgstr "Afficher le tracé de contours..." +msgid "A new object was loaded. Start a new history session?" +msgstr "Un nouvel objet a été chargé. Démarrer une nouvelle session d'historique ?" + +msgid "A new object was created. Start a new history session?" +msgstr "Un nouvel objet a été créé. Démarrer une nouvelle session d'historique ?" + +msgid "New history session" +msgstr "Nouvelle session d'historique" + +msgid "Initial state" +msgstr "État initial" + +msgid "Chain copy" +msgstr "Copie de chaîne" + +msgid "" +"Do you really want to delete the selected items?\n" +"\n" +"Note: deleting an intermediate action splits its processing chain; downstream steps become an independent chain." +msgstr "" +"Êtes-vous sûr de vouloir supprimer les éléments sélectionnés ?\n" +"\n" +"Remarque : la suppression d'une action intermédiaire divise sa chaîne de traitement ; les étapes en aval deviennent une chaîne indépendante." + +msgid "Do you really want to delete the selected items?" +msgstr "Êtes-vous sûr de vouloir supprimer le(s) groupe(s) sélectionné(s) ?" + +msgid "The deleted action(s) produced object(s) still present in the workspace. Do you want to remove the associated object(s) as well?" +msgstr "La ou les actions supprimées ont produit des objets encore présents dans l'espace de travail. Voulez-vous également supprimer le ou les objets associés ?" + +msgid "Remove incompatible" +msgstr "Supprimer les actions incompatibles" + +msgid "All actions are compatible with the current workspace." +msgstr "Toutes les actions sont compatibles avec l'espace de travail actuel." + +#, python-format +msgid "%d incompatible action(s) will be removed. Continue?" +msgstr "%d action(s) incompatible(s) seront supprimées. Continuer ?" + +msgid "History Panel" +msgstr "Historique" + +#, python-format +msgid "Open %d HDF5 files" +msgstr "Ouvrir %d fichiers HDF5" + +msgid "Open HDF5 file" +msgstr "Ouvrir un fichier HDF5" + +#, python-format +msgid "New %s" +msgstr "Créer un nouvel objet %s" + +msgid "Signal was recreated." +msgstr "Le signal a été recréé." + +msgid "Image was recreated." +msgstr "L'image a été recréée." + +msgid "Auto-recompute on edit" +msgstr "Recalcul automatique lors de l'édition" + +msgid "Automatically re-run processing when parameters are modified" +msgstr "Relancer automatiquement le traitement à chaque modification de paramètre" + +msgid "Analysis Parameters" +msgstr "Paramètres d'analyse" + +msgid "Analysis metadata is incomplete." +msgstr "Les métadonnées d'analyse sont incomplètes." + +#, python-format +msgid "" +"Failed to recompute analysis:\n" +"%s" +msgstr "" +"Échec du recalcul de l'analyse :\n" +"%s" + +msgid "Failed to recompute analysis." +msgstr "Échec du recalcul de l'analyse." + +msgid "Analysis was recomputed." +msgstr "L'analyse a été recalculée." + +msgid "Pattern help" +msgstr "Aide sur le motif" + +msgid "Duplicate object or group" +msgstr "Dupliquer l'objet ou le groupe" + +msgid "Remove selected objects" +msgstr "Supprimer les objets sélectionnés" + +#, python-format +msgid "New group \"%s\"" +msgstr "Nouveau groupe \"%s\"" + +msgid "Rename selected object or group" +msgstr "Renommer l'objet ou le groupe sélectionné" + +#, python-format +msgid "Set current object title to \"%s\"" +msgstr "Définir le titre de l'objet courant à \"%s\"" + +#, python-format +msgid "Load from %d files" +msgstr "Charger depuis %d fichiers" + +#, python-format +msgid "Load \"%s\"" +msgstr "Charger \"%s\"" + +#, python-format +msgid "Save to %d different files" +msgstr "Enregistrer dans %d fichiers différents" + +#, python-format +msgid "Save to \"%s\"" +msgstr "Enregistrer dans \"%s\"" + +msgid "Analysis computation failed." +msgstr "Le calcul de l'analyse a échoué." + +msgid "Failed to recompute analysis" +msgstr "Échec du recalcul de l'analyse" + +msgid "Add object title to plot" +msgstr "Ajouter le titre de l'objet au graphique" + +msgid "Add label with title" +msgstr "Ajouter une étiquette avec le titre" + +#, python-format +msgid "“%s” has dependent operations but no valid source to reconnect to — downstream results are left unchanged." +msgstr "« %s » possède des opérations dépendantes mais aucune source valide à laquelle se reconnecter — les résultats en aval restent inchangés." + +msgid "Some operations could not be reconnected after deletion:" +msgstr "Certaines opérations n'ont pas pu être reconnectées après la suppression :" + +msgid "Commit edit mode changes?" +msgstr "Valider les modifications du mode d'édition ?" + +msgid "" +"You are about to exit Edit mode.\n" +"\n" +"All parameter changes made during this session will be permanently kept.\n" +"This action cannot be undone — Restore will no longer be available.\n" +"\n" +"Do you want to continue?" +msgstr "" +"Vous êtes sur le point de quitter le mode d'édition.\n" +"\n" +"Toutes les modifications de paramètres effectuées lors de cette session seront conservées de façon permanente.\n" +"Cette action est irréversible — la fonction Restaurer ne sera plus disponible.\n" +"\n" +"Souhaitez-vous continuer ?" + +msgid "The current workspace state is not compatible with the action." +msgstr "L'état actuel de l'espace de travail n'est pas compatible avec l'action." + +#, python-format +msgid "Action %s has no recorded pattern and cannot be replayed." +msgstr "L'action %s n'a pas de motif enregistré et ne peut pas être rejouée." + +msgid "History panel" +msgstr "Panneau d'historique" + +msgid "History files" +msgstr "Fichiers d'historique" + +#, python-format +msgid "Action %s has been edited but its target output object(s) no longer exist — skipping." +msgstr "L'action %s a été modifiée mais son ou ses objets de sortie cibles n'existent plus — ignorée." + +#, python-format +msgid "Action %s uses pattern %r which is not recomputable yet." +msgstr "L'action %s utilise le motif %r qui n'est pas encore recalculable." + +#, python-format +msgid "Action %s could not be fully recomputed." +msgstr "L'action %s n'a pas pu être entièrement recalculée." + +#, python-format +msgid "Recompute failed for action %s: %s" +msgstr "Échec du recalcul pour l'action %s : %s" + +#, python-format +msgid "" +"Action %(name)s skipped: plugin '%(loc)s' is missing.\n" +"Required parameter class: %(param)s\n" +"Reinstall the plugin to re-enable this action." +msgstr "" +"Action %(name)s ignorée : le plugin '%(loc)s' est manquant.\n" +"Classe de paramètre requise : %(param)s\n" +"Réinstallez le plugin pour réactiver cette action." + +#, python-format +msgid "Action %s: source object was deleted — skipping." +msgstr "Action %s : l'objet source a été supprimé — ignorée." + +#, python-format +msgid "Action %s: recompute returned %d output(s), expected %d." +msgstr "Action %s : le recalcul a renvoyé %d sortie(s), %d attendue(s)." + +#, python-format +msgid "Action %s: source object(s) were deleted — skipping." +msgstr "Action %s : le ou les objets source ont été supprimés — ignorée." + +#, python-format +msgid "Action %s: missing source(s) for output #%d — skipping." +msgstr "Action %s : source(s) manquante(s) pour la sortie n°%d — ignorée." + +#, python-format +msgid "Action %s: %d analysed object(s) were deleted — skipping." +msgstr "Action %s : %d objet(s) analysé(s) ont été supprimés — ignorée." + +msgid "Cascade recompute" +msgstr "Recalcul en cascade" + +msgid "Some downstream actions could not be recomputed:" +msgstr "Certaines actions en aval n'ont pas pu être recalculées :" + +msgid "Record mode" +msgstr "Mode d'enregistrement" + +msgid "New session" +msgstr "Nouvelle session" + +msgid "Start a new history session" +msgstr "Démarrer une nouvelle session d'historique" + +msgid "Open history file..." +msgstr "Ouvrir un fichier d'historique..." + +msgid "Open history from a standalone .dlhist file" +msgstr "Ouvrir l'historique depuis un fichier .dlhist autonome" + +msgid "Save history file..." +msgstr "Enregistrer un fichier d'historique..." + +msgid "Save history to a standalone .dlhist file" +msgstr "Enregistrer l'historique dans un fichier .dlhist autonome" + +msgid "Duplicate selected history action/session" +msgstr "Dupliquer l'action ou la session d'historique sélectionnée" + +msgid "Previous step" +msgstr "Étape précédente" + +msgid "Select the previous action in the current session" +msgstr "Sélectionner l'action précédente dans la session courante" + +msgid "Next step" +msgstr "Étape suivante" + +msgid "Select the next action in the current session" +msgstr "Sélectionner l'action suivante dans la session courante" + +msgid "Remove actions incompatible with the current workspace" +msgstr "Supprimer les actions incompatibles avec l'espace de travail courant" + +msgid "Replay" +msgstr "Rejouer" + +msgid "Replay the selection silently (no parameter dialogs)" +msgstr "Rejouer la sélection silencieusement (sans boîtes de dialogue de paramètres)" + +msgid "Step-by-step" +msgstr "Pas à pas" + +msgid "Replay the selection step by step, editing parameters at each step" +msgstr "Rejouer la sélection pas à pas, en modifiant les paramètres à chaque étape" + +msgid "New image" +msgstr "Nouvelle image" + +msgid "New signal" +msgstr "Nouveau signal" + +msgid "History sessions" +msgstr "Sessions d'historique" + +msgid "New object or file" +msgstr "Nouvel objet ou fichier" + +msgid "Ask" +msgstr "Demander" + +msgid "Always start a new session" +msgstr "Toujours démarrer une nouvelle session" + +msgid "Continue in the current session" +msgstr "Continuer dans la session courante" + +msgid "Behavior when a new object or file is added to a populated history session." +msgstr "Comportement lorsqu'un nouvel objet ou fichier est ajouté à une session d'historique non vide." + +msgid "Plugin-created object" +msgstr "Objet créé par un plugin" + +msgid "Behavior when a plugin adds an object to a populated history session." +msgstr "Comportement lorsqu'un plugin ajoute un objet à une session d'historique non vide." + +msgid "Plugin multi-load" +msgstr "Chargement multiple par un plugin" + +msgid "Ask once" +msgstr "Demander une seule fois" + +msgid "Start a new session" +msgstr "Démarrer une nouvelle session" + +msgid "Behavior when a plugin loads multiple objects into a populated history session." +msgstr "Comportement lorsqu'un plugin charge plusieurs objets dans une session d'historique non vide." + +msgid "Save history file" +msgstr "Enregistrer un fichier d'historique" + +msgid "Open history file" +msgstr "Ouvrir un fichier d'historique" + +msgid "Imported" +msgstr "Importé" + +#, python-format +msgid "Failed to deserialize history DataSet kwarg %r." +msgstr "Échec de la désérialisation de l'argument DataSet de l'historique %r." + +#, python-format +msgid "Failed to deserialize history DataSet-list kwarg %r." +msgstr "Échec de la désérialisation de l'argument DataSet-list de l'historique %r." + +msgid "Show details" +msgstr "Afficher les détails" + +msgid "Hide details" +msgstr "Masquer les détails" + +msgid "Date and time" +msgstr "Date et heure" + +msgid "Action is compatible with the current workspace state." +msgstr "L'action est compatible avec l'état actuel de l'espace de travail." + +msgid "Action is not compatible with the current workspace state." +msgstr "L'action n'est pas compatible avec l'état actuel de l'espace de travail." + +msgid "Active recording session." +msgstr "Session d'enregistrement active." + +msgid "Signal" +msgstr "Signal" + +msgid "Shape" +msgstr "Forme" + +msgid "Image" +msgstr "Image" + +msgid "Dimensions" +msgstr "Dimensions" + diff --git a/datalab/tests/features/common/history_workflow_test.py b/datalab/tests/features/common/history_workflow_test.py index 655efce4c..c449b5855 100644 --- a/datalab/tests/features/common/history_workflow_test.py +++ b/datalab/tests/features/common/history_workflow_test.py @@ -704,6 +704,29 @@ def test_restore_failure_marks_action_stale_without_cascade() -> None: assert action.is_stale is True +def test_restore_recomputes_stale_action_without_pending_edits() -> None: + """Recompute a stale action on restore even without pending edits.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + history.toggle_edit_mode(True) + action = build_signal_chain(panel, history).actions[0] + action.is_stale = True + assert not action.has_pending_edits + + with ( + patch.object( + hrec, "recompute_action_in_place", return_value=True + ) as recompute, + patch.object(hrec, "recompute_cascade") as recompute_cascade, + ): + hireplay.restore_action_params(history, action) + + recompute.assert_called_once_with(history, action) + recompute_cascade.assert_called_once_with(history, action) + assert action.is_stale is False + + def test_empty_analysis_result_is_successful() -> None: """Treat an executed analysis with no detections as successful.""" with datalab_test_app_context(history=True) as win: diff --git a/doc/features/common/historypanel.rst b/doc/features/common/historypanel.rst index 7ae1b26b7..50c1b3904 100644 --- a/doc/features/common/historypanel.rst +++ b/doc/features/common/historypanel.rst @@ -160,8 +160,9 @@ The toolbar at the top of the panel exposes the following actions: time, opening the parameter dialog for each supported action (object creation, computation, ROI extraction) before recomputing it. Accepted edits propagate to the downstream dependent actions, which are recomputed - as well. Cancelling a dialog stops the replay and restores the parameter - edits made during that run. + as well. Cancelling a dialog stops the replay, restores the parameter + edits made during that run, and silently recomputes any actions left + outdated so the chain stays up to date. - |duplicate| **Duplicate**: duplicate the processing chain containing each selected action, or the processing chains in each selected session. DataLab clones the required objects and creates independent history sessions. diff --git a/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po b/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po index 09560c8ec..68f1f9280 100644 --- a/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po +++ b/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2026-08-05 18:58+0200\n" +"POT-Creation-Date: 2026-08-05 19:29+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language: fr\n" @@ -76,15 +76,16 @@ msgid "" "actions are invoked through their own methods and may reproduce their " "side effects, including creating, importing, or duplicating objects;" msgstr "" -"**rejouée** silencieusement ou **pas à pas**. Le rejeu recalcule en place " -"chaque action de calcul avec ses paramètres enregistrés : les objets de " -"sortie existants sont mis à jour, et les sorties supprimées dont l'action " -"fait toujours partie de l'historique sont recréées sous leurs identifiants " -"d'origine, ce qui préserve la validité de la chaîne de traitement en aval. " -"En mode pas à pas, les paramètres peuvent être examinés et modifiés avant " -"le recalcul de chaque étape. Les actions de l'interface enregistrées sont " -"invoquées par leurs propres méthodes et peuvent reproduire leurs effets, " -"notamment créer, importer ou dupliquer des objets ;" +"**rejouée** silencieusement ou **pas à pas**. Le rejeu recalcule en place" +" chaque action de calcul avec ses paramètres enregistrés : les objets de " +"sortie existants sont mis à jour, et les sorties supprimées dont l'action" +" fait toujours partie de l'historique sont recréées sous leurs " +"identifiants d'origine, ce qui préserve la validité de la chaîne de " +"traitement en aval. En mode pas à pas, les paramètres peuvent être " +"examinés et modifiés avant le recalcul de chaque étape. Les actions de " +"l'interface enregistrées sont invoquées par leurs propres méthodes et " +"peuvent reproduire leurs effets, notamment créer, importer ou dupliquer " +"des objets ;" msgid "" "**Duplicated** as independent processing chains in new history sessions, " @@ -258,23 +259,23 @@ msgstr "" "cette action ; sélectionner une session rejoue toutes ses actions. Une " "sélection couvrant plusieurs actions ou sessions est fusionnée, " "dédoublonnée et exécutée dans l'ordre des sessions. Chaque action de " -"calcul est réexécutée avec ses paramètres enregistrés et met à jour son ou " -"ses objets de sortie existants, en conservant les mêmes identifiants afin " -"que les étapes en aval restent valides. Les sorties supprimées du panneau " -"de données sont recréées sous leurs identifiants d'origine (flux de " -"travail typique : supprimer un résultat erroné, modifier ses paramètres, " -"puis rejouer pour le régénérer). Les actions dont les objets source " -"n'existent plus sont ignorées avec un avertissement, et une action en " -"échec bloque sa branche en aval. Les actions dont les paramètres ont été " -"modifiés (en mode pas à pas ou depuis l'onglet **Traitement**) sont " +"calcul est réexécutée avec ses paramètres enregistrés et met à jour son " +"ou ses objets de sortie existants, en conservant les mêmes identifiants " +"afin que les étapes en aval restent valides. Les sorties supprimées du " +"panneau de données sont recréées sous leurs identifiants d'origine (flux " +"de travail typique : supprimer un résultat erroné, modifier ses " +"paramètres, puis rejouer pour le régénérer). Les actions dont les objets " +"source n'existent plus sont ignorées avec un avertissement, et une action" +" en échec bloque sa branche en aval. Les actions dont les paramètres ont " +"été modifiés (en mode pas à pas ou depuis l'onglet **Traitement**) sont " "marquées comme obsolètes ; le rejeu les recalcule et, lorsque les " -"paramètres ont été modifiés, recalcule également leurs actions dépendantes " -"en aval. Les actions d'analyse sont rejouées en recalculant leurs " -"résultats sur les objets source. Les actions de l'interface sont rejouées " -"en invoquant leur méthode enregistrée et peuvent reproduire des effets, " -"notamment créer, importer ou dupliquer des objets ; les actions " -"destructives sont ignorées lorsque leurs cibles capturées ne peuvent plus " -"être résolues." +"paramètres ont été modifiés, recalcule également leurs actions " +"dépendantes en aval. Les actions d'analyse sont rejouées en recalculant " +"leurs résultats sur les objets source. Les actions de l'interface sont " +"rejouées en invoquant leur méthode enregistrée et peuvent reproduire des " +"effets, notamment créer, importer ou dupliquer des objets ; les actions " +"destructives sont ignorées lorsque leurs cibles capturées ne peuvent plus" +" être résolues." msgid "replay" msgstr "replay" @@ -284,15 +285,19 @@ msgid "" "time, opening the parameter dialog for each supported action (object " "creation, computation, ROI extraction) before recomputing it. Accepted " "edits propagate to the downstream dependent actions, which are recomputed" -" as well. Cancelling a dialog stops the replay and restores the parameter" -" edits made during that run." -msgstr """|step_by_step| **Pas à pas** : rejoue la même sélection étape par étape, " -"en ouvrant la boîte de dialogue des paramètres pour chaque action prise en " -"charge (création d'objet, calcul, extraction de ROI) avant de la " -"recalculer. Les modifications acceptées se propagent aux actions " -"dépendantes en aval, qui sont également recalculées. Annuler une boîte de " -"dialogue interrompt le rejeu et annule les modifications de paramètres " -"effectuées au cours de cette exécution." +" as well. Cancelling a dialog stops the replay, restores the parameter " +"edits made during that run, and silently recomputes any actions left " +"outdated so the chain stays up to date." +msgstr "" +"|step_by_step| **Pas à pas** : rejoue la même sélection étape par " +"étape, en ouvrant la boîte de dialogue des paramètres pour chaque action " +"prise en charge (création d'objet, calcul, extraction de ROI) avant de la" +" recalculer. Les modifications acceptées se propagent aux actions " +"dépendantes en aval, qui sont également recalculées. L'annulation d'une " +"boîte de dialogue interrompt le rejeu, restaure les modifications de " +"paramètres effectuées durant cette exécution et recalcule silencieusement" +" les actions restées obsolètes afin que la chaîne reste à jour." + msgid "step_by_step" msgstr "step_by_step" @@ -339,9 +344,9 @@ msgid "" "Double-clicking a tree item invokes **Replay** for the current selection," " with the same in-place recompute semantics documented above." msgstr "" -"Un double-clic sur un élément de l'arborescence déclenche **Rejouer** pour " -"la sélection courante, avec la même sémantique de recalcul en place que " -"celle documentée ci-dessus." +"Un double-clic sur un élément de l'arborescence déclenche **Rejouer** " +"pour la sélection courante, avec la même sémantique de recalcul en place " +"que celle documentée ci-dessus." msgid "Tree view" msgstr "Arborescence" diff --git a/doc/locale/fr/LC_MESSAGES/features/validation/status.po b/doc/locale/fr/LC_MESSAGES/features/validation/status.po index e0a849268..aee38071a 100644 --- a/doc/locale/fr/LC_MESSAGES/features/validation/status.po +++ b/doc/locale/fr/LC_MESSAGES/features/validation/status.po @@ -6,14 +6,25 @@ #, fuzzy msgid "" msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2026-08-05 10:58+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language: fr\n" +"Language-Team: fr <LL@li.org>\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.18.0\n" -msgid "Validation in DataLab, the open-source scientific data analysis and visualization platform" -msgstr "Validation dans DataLab, la plateforme open-source d'analyse et de visualisation de données scientifiques" +msgid "" +"Validation in DataLab, the open-source scientific data analysis and " +"visualization platform" +msgstr "" +"Validation dans DataLab, la plateforme open-source d'analyse et de " +"visualisation de données scientifiques" msgid "DataLab, scientific, data, analysis, validation, ground-truth, analytical" msgstr "DataLab, scientifique, données, analyse, validation, analytique" @@ -24,8 +35,12 @@ msgstr "Etat de validation de DataLab" msgid "Functional validation" msgstr "Validation fonctionnelle" -msgid "In DataLab, functional validation is based on a classic test strategy (see :ref:`functional_validation`)." -msgstr "Dans DataLab, la validation fonctionnelle est basée sur une stratégie de test classique (voir :ref:`functional_validation`)." +msgid "" +"In DataLab, functional validation is based on a classic test strategy " +"(see :ref:`functional_validation`)." +msgstr "" +"Dans DataLab, la validation fonctionnelle est basée sur une stratégie de " +"test classique (voir :ref:`functional_validation`)." msgid "Package" msgstr "Package" @@ -57,14 +72,44 @@ msgstr "" msgid "Technical validation" msgstr "Validation technique" -msgid "This paragraph provides the validation status of compute functions in DataLab (this is what we call technical validation, see :ref:`scientific_validation`)." -msgstr "Ce paragraphe fournit l'état de validation des fonctions de calcul dans DataLab (c'est ce que nous appelons validation technique, voir :ref:`scientific_validation`)." +msgid "" +"This paragraph provides the validation status of compute functions in " +"DataLab (this is what we call technical validation, see " +":ref:`scientific_validation`)." +msgstr "" +"Ce paragraphe fournit l'état de validation des fonctions de calcul dans " +"DataLab (c'est ce que nous appelons validation technique, voir " +":ref:`scientific_validation`)." -msgid "This is a work in progress: the tables below are updated continuously as new functions are validated or test code is adapted (the tables are generated from the test code). Some functions are already validated but do not appear in the list below yet, while others are still in the validation process." -msgstr "Il s'agit d'un travail en cours : les tableaux ci-dessous sont mis à jour en continu à mesure que de nouvelles fonctions sont validées ou que le code de test est adapté (les tableaux sont générés à partir du code de test). Certaines fonctions sont déjà validées mais n'apparaissent pas encore dans la liste ci-dessous, tandis que d'autres sont encore en cours de validation." +msgid "" +"This is a work in progress: the tables below are updated continuously as " +"new functions are validated or test code is adapted (the tables are " +"generated from the test code). Some functions are already validated but " +"do not appear in the list below yet, while others are still in the " +"validation process." +msgstr "" +"Il s'agit d'un travail en cours : les tableaux ci-dessous sont mis à jour" +" en continu à mesure que de nouvelles fonctions sont validées ou que le " +"code de test est adapté (les tableaux sont générés à partir du code de " +"test). Certaines fonctions sont déjà validées mais n'apparaissent pas " +"encore dans la liste ci-dessous, tandis que d'autres sont encore en cours" +" de validation." -msgid "The validation status must not be confused with the test coverage. The validation status indicates whether the function has been validated against ground-truth data or analytical models. The test coverage indicates the percentage of the code that is executed by the test suite, but it does not necessarily take into account the correctness of the results (DataLab's test coverage is around 90%)." -msgstr "L'état de validation ne doit pas être confondu avec la couverture de test. L'état de validation indique si la fonction a été validée par rapport à des données de référence ou des modèles analytiques. La couverture de test indique le pourcentage du code qui est exécuté par la suite de tests, mais elle ne prend pas nécessairement en compte la justesse des résultats (la couverture de test de DataLab est d'environ 90%)." +msgid "" +"The validation status must not be confused with the test coverage. The " +"validation status indicates whether the function has been validated " +"against ground-truth data or analytical models. The test coverage " +"indicates the percentage of the code that is executed by the test suite, " +"but it does not necessarily take into account the correctness of the " +"results (DataLab's test coverage is around 90%)." +msgstr "" +"L'état de validation ne doit pas être confondu avec la couverture de " +"test. L'état de validation indique si la fonction a été validée par " +"rapport à des données de référence ou des modèles analytiques. La " +"couverture de test indique le pourcentage du code qui est exécuté par la " +"suite de tests, mais elle ne prend pas nécessairement en compte la " +"justesse des résultats (la couverture de test de DataLab est d'environ " +"90%)." msgid "Validation Statistics" msgstr "Statistiques de validation" @@ -105,8 +150,13 @@ msgstr "" msgid "Signal Compute Functions" msgstr "Fonctions de calcul signal" -msgid "The table below shows the validation status of signal compute functions in DataLab. It is automatically generated from the source code." -msgstr "Le tableau ci-dessous montre l'état de validation des fonctions de calcul signal dans DataLab. Il est généré automatiquement à partir du code source." +msgid "" +"The table below shows the validation status of signal compute functions " +"in DataLab. It is automatically generated from the source code." +msgstr "" +"Le tableau ci-dessous montre l'état de validation des fonctions de calcul" +" signal dans DataLab. Il est généré automatiquement à partir du code " +"source." msgid "Validation status of signal compute functions" msgstr "Etat de validation de DataLab" @@ -126,7 +176,9 @@ msgstr "" msgid "Compute absolute value with :py:data:`numpy.absolute`" msgstr "" -msgid "`test_signal_absolute <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L229>`_" +msgid "" +"`test_signal_absolute <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/operation_unit_test.py#L229>`_" msgstr "" msgid ":py:func:`add_gaussian_noise <sigima.proc.signal.add_gaussian_noise>`" @@ -135,7 +187,9 @@ msgstr "" msgid "Add normal noise to the input signal" msgstr "" -msgid "`test_signal_add_gaussian_noise <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/noise_unit_test.py#L21>`_" +msgid "" +"`test_signal_add_gaussian_noise <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/noise_unit_test.py#L21>`_" msgstr "" msgid ":py:func:`add_poisson_noise <sigima.proc.signal.add_poisson_noise>`" @@ -144,7 +198,9 @@ msgstr "" msgid "Add Poisson noise to the input signal" msgstr "" -msgid "`test_signal_add_poisson_noise <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/noise_unit_test.py#L54>`_" +msgid "" +"`test_signal_add_poisson_noise <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/noise_unit_test.py#L54>`_" msgstr "" msgid ":py:func:`add_uniform_noise <sigima.proc.signal.add_uniform_noise>`" @@ -153,7 +209,9 @@ msgstr "" msgid "Add uniform noise to the input signal" msgstr "" -msgid "`test_signal_add_uniform_noise <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/noise_unit_test.py#L88>`_" +msgid "" +"`test_signal_add_uniform_noise <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/noise_unit_test.py#L88>`_" msgstr "" msgid ":py:func:`addition <sigima.proc.signal.addition>`" @@ -162,7 +220,9 @@ msgstr "" msgid "Compute the element-wise sum of multiple signals" msgstr "" -msgid "`test_signal_addition <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L78>`_" +msgid "" +"`test_signal_addition <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/operation_unit_test.py#L78>`_" msgstr "" msgid ":py:func:`addition_constant <sigima.proc.signal.addition_constant>`" @@ -171,7 +231,9 @@ msgstr "" msgid "Compute the sum of a signal and a constant value" msgstr "" -msgid "`test_signal_addition_constant <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L171>`_" +msgid "" +"`test_signal_addition_constant <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/operation_unit_test.py#L171>`_" msgstr "" msgid ":py:func:`allan_deviation <sigima.proc.signal.allan_deviation>`" @@ -180,7 +242,9 @@ msgstr "" msgid "Compute Allan deviation" msgstr "Calculer la déviation d'Allan" -msgid "`test_signal_allan_deviation <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/stability_unit_test.py#L153>`_" +msgid "" +"`test_signal_allan_deviation <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/stability_unit_test.py#L157>`_" msgstr "" msgid ":py:func:`allan_variance <sigima.proc.signal.allan_variance>`" @@ -189,7 +253,9 @@ msgstr "" msgid "Compute Allan variance" msgstr "" -msgid "`test_signal_allan_variance <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/stability_unit_test.py#L102>`_" +msgid "" +"`test_signal_allan_variance <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/stability_unit_test.py#L140>`_" msgstr "" msgid ":py:func:`apply_window <sigima.proc.signal.apply_window>`" @@ -198,7 +264,9 @@ msgstr "" msgid "Compute windowing" msgstr "Calculer la fenêtrage" -msgid "`test_signal_apply_window <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L564>`_" +msgid "" +"`test_signal_apply_window <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/processing_unit_test.py#L564>`_" msgstr "" msgid ":py:func:`arithmetic <sigima.proc.signal.arithmetic>`" @@ -207,7 +275,9 @@ msgstr "" msgid "Perform an arithmetic operation on two signals" msgstr "" -msgid "`test_signal_arithmetic <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L398>`_" +msgid "" +"`test_signal_arithmetic <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/operation_unit_test.py#L398>`_" msgstr "" msgid ":py:func:`astype <sigima.proc.signal.astype>`" @@ -216,7 +286,9 @@ msgstr "" msgid "Convert data type" msgstr "" -msgid "`test_signal_astype <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L355>`_" +msgid "" +"`test_signal_astype <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/operation_unit_test.py#L355>`_" msgstr "" msgid ":py:func:`average <sigima.proc.signal.average>`" @@ -225,7 +297,9 @@ msgstr "" msgid "Compute the element-wise average of multiple signals" msgstr "" -msgid "`test_signal_average <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L92>`_" +msgid "" +"`test_signal_average <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/operation_unit_test.py#L92>`_" msgstr "" msgid ":py:func:`bandpass <sigima.proc.signal.bandpass>`" @@ -234,7 +308,9 @@ msgstr "" msgid "Compute band-pass filter" msgstr "" -msgid "`test_signal_bandpass <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/filters_unit_test.py#L290>`_" +msgid "" +"`test_signal_bandpass <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/filters_unit_test.py#L290>`_" msgstr "" msgid ":py:func:`bandstop <sigima.proc.signal.bandstop>`" @@ -243,7 +319,9 @@ msgstr "" msgid "Compute band-stop filter" msgstr "" -msgid "`test_signal_bandstop <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/filters_unit_test.py#L248>`_" +msgid "" +"`test_signal_bandstop <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/filters_unit_test.py#L248>`_" msgstr "" msgid ":py:func:`bandwidth_3db <sigima.proc.signal.bandwidth_3db>`" @@ -252,7 +330,9 @@ msgstr "" msgid "Compute bandwidth at -3 dB" msgstr "" -msgid "`test_signal_bandwidth_3db <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/analysis_unit_test.py#L33>`_" +msgid "" +"`test_signal_bandwidth_3db <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/analysis_unit_test.py#L33>`_" msgstr "" msgid ":py:func:`calibration <sigima.proc.signal.calibration>`" @@ -261,7 +341,9 @@ msgstr "" msgid "Compute linear calibration" msgstr "" -msgid "`test_signal_calibration <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L38>`_" +msgid "" +"`test_signal_calibration <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/processing_unit_test.py#L38>`_" msgstr "" msgid ":py:func:`cdf_fit <sigima.proc.signal.cdf_fit>`" @@ -270,7 +352,9 @@ msgstr "" msgid "Compute CDF fit" msgstr "" -msgid "`test_signal_cdf_fit <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fitting_unit_test.py#L457>`_" +msgid "" +"`test_signal_cdf_fit <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/fitting_unit_test.py#L503>`_" msgstr "" msgid ":py:func:`clip <sigima.proc.signal.clip>`" @@ -279,25 +363,35 @@ msgstr "" msgid "Compute maximum data clipping" msgstr "" -msgid "`test_signal_clip <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L192>`_" +msgid "" +"`test_signal_clip <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/processing_unit_test.py#L192>`_" msgstr "" -msgid ":py:func:`complex_from_magnitude_phase <sigima.proc.signal.complex_from_magnitude_phase>`" +msgid "" +":py:func:`complex_from_magnitude_phase " +"<sigima.proc.signal.complex_from_magnitude_phase>`" msgstr "" msgid "Combine magnitude and phase signals into a complex signal" msgstr "" -msgid "`test_signal_complex_from_magnitude_phase <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L320>`_" +msgid "" +"`test_signal_complex_from_magnitude_phase <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/operation_unit_test.py#L320>`_" msgstr "" -msgid ":py:func:`complex_from_real_imag <sigima.proc.signal.complex_from_real_imag>`" +msgid "" +":py:func:`complex_from_real_imag " +"<sigima.proc.signal.complex_from_real_imag>`" msgstr "" msgid "Combine two real signals into a complex signal using real + i * imag" msgstr "" -msgid "`test_signal_complex_from_real_imag <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L253>`_" +msgid "" +"`test_signal_complex_from_real_imag <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/operation_unit_test.py#L253>`_" msgstr "" msgid ":py:func:`contrast <sigima.proc.signal.contrast>`" @@ -306,7 +400,9 @@ msgstr "" msgid "Compute contrast" msgstr "Calculer le contraste" -msgid "`test_signal_contrast <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/analysis_unit_test.py#L88>`_" +msgid "" +"`test_signal_contrast <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/analysis_unit_test.py#L88>`_" msgstr "" msgid ":py:func:`convolution <sigima.proc.signal.convolution>`" @@ -315,7 +411,9 @@ msgstr "" msgid "Compute convolution of two signals" msgstr "" -msgid "`test_signal_convolution <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/convolution_unit_test.py#L106>`_" +msgid "" +"`test_signal_convolution <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/convolution_unit_test.py#L106>`_" msgstr "" msgid ":py:func:`deconvolution <sigima.proc.signal.deconvolution>`" @@ -324,7 +422,9 @@ msgstr "" msgid "Compute deconvolution" msgstr "Calculer la déconvolution" -msgid "`test_signal_deconvolution <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/convolution_unit_test.py#L267>`_" +msgid "" +"`test_signal_deconvolution <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/convolution_unit_test.py#L267>`_" msgstr "" msgid ":py:func:`derivative <sigima.proc.signal.derivative>`" @@ -333,7 +433,9 @@ msgstr "" msgid "Compute derivative" msgstr "Calculer la dérivée" -msgid "`test_signal_derivative <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L205>`_" +msgid "" +"`test_signal_derivative <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/processing_unit_test.py#L205>`_" msgstr "" msgid ":py:func:`detrending <sigima.proc.signal.detrending>`" @@ -342,7 +444,9 @@ msgstr "" msgid "Detrend data" msgstr "" -msgid "`test_signal_detrending <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L248>`_" +msgid "" +"`test_signal_detrending <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/processing_unit_test.py#L248>`_" msgstr "" msgid ":py:func:`difference <sigima.proc.signal.difference>`" @@ -351,7 +455,9 @@ msgstr "" msgid "Compute the element-wise difference between two signals" msgstr "" -msgid "`test_signal_difference <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L141>`_" +msgid "" +"`test_signal_difference <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/operation_unit_test.py#L141>`_" msgstr "" msgid ":py:func:`difference_constant <sigima.proc.signal.difference_constant>`" @@ -360,7 +466,9 @@ msgstr "" msgid "Compute the difference between a signal and a constant value" msgstr "" -msgid "`test_signal_difference_constant <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L193>`_" +msgid "" +"`test_signal_difference_constant <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/operation_unit_test.py#L193>`_" msgstr "" msgid ":py:func:`division <sigima.proc.signal.division>`" @@ -369,7 +477,9 @@ msgstr "" msgid "Compute the element-wise division between two signals" msgstr "" -msgid "`test_signal_division <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L159>`_" +msgid "" +"`test_signal_division <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/operation_unit_test.py#L159>`_" msgstr "" msgid ":py:func:`division_constant <sigima.proc.signal.division_constant>`" @@ -378,7 +488,9 @@ msgstr "" msgid "Compute the division of a signal by a constant value" msgstr "" -msgid "`test_signal_division_constant <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L203>`_" +msgid "" +"`test_signal_division_constant <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/operation_unit_test.py#L203>`_" msgstr "" msgid ":py:func:`dynamic_parameters <sigima.proc.signal.dynamic_parameters>`" @@ -387,7 +499,9 @@ msgstr "" msgid "Compute Dynamic parameters" msgstr "" -msgid "`test_dynamic_parameters <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/analysis_unit_test.py#L62>`_" +msgid "" +"`test_dynamic_parameters <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/analysis_unit_test.py#L62>`_" msgstr "" msgid ":py:func:`evaluate_fit <sigima.proc.signal.evaluate_fit>`" @@ -396,7 +510,9 @@ msgstr "" msgid "Evaluate fit function from src1 on the x-axis of src2" msgstr "" -msgid "`test_signal_evaluate_fit <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fitting_unit_test.py#L846>`_" +msgid "" +"`test_signal_evaluate_fit <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/fitting_unit_test.py#L931>`_" msgstr "" msgid ":py:func:`exp <sigima.proc.signal.exp>`" @@ -405,7 +521,9 @@ msgstr "" msgid "Compute exponential with :py:data:`numpy.exp`" msgstr "" -msgid "`test_signal_exp <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L365>`_" +msgid "" +"`test_signal_exp <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/operation_unit_test.py#L365>`_" msgstr "" msgid ":py:func:`exponential_fit <sigima.proc.signal.exponential_fit>`" @@ -414,16 +532,22 @@ msgstr "" msgid "Compute exponential fit" msgstr "Calculer l'ajustement exponentiel" -msgid "`test_signal_exponential_fit <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fitting_unit_test.py#L308>`_" +msgid "" +"`test_signal_exponential_fit <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/fitting_unit_test.py#L354>`_" msgstr "" -msgid ":py:func:`extract_pulse_features <sigima.proc.signal.extract_pulse_features>`" +msgid "" +":py:func:`extract_pulse_features " +"<sigima.proc.signal.extract_pulse_features>`" msgstr "" msgid "Extract pulse features" msgstr "" -msgid "`test_signal_extract_pulse_features <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/pulse/pulse_unit_test.py#L1729>`_" +msgid "" +"`test_signal_extract_pulse_features <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/pulse/pulse_unit_test.py#L1729>`_" msgstr "" msgid ":py:func:`extract_roi <sigima.proc.signal.extract_roi>`" @@ -432,7 +556,9 @@ msgstr "" msgid "Extract single region of interest from data" msgstr "" -msgid "`test_signal_extract_roi <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/roi_advanced_unit_test.py#L198>`_" +msgid "" +"`test_signal_extract_roi <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/roi_advanced_unit_test.py#L198>`_" msgstr "" msgid ":py:func:`extract_rois <sigima.proc.signal.extract_rois>`" @@ -441,7 +567,9 @@ msgstr "" msgid "Extract multiple regions of interest from data" msgstr "" -msgid "`test_signal_extract_rois <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/roi_advanced_unit_test.py#L169>`_" +msgid "" +"`test_signal_extract_rois <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/roi_advanced_unit_test.py#L169>`_" msgstr "" msgid ":py:func:`fft <sigima.proc.signal.fft>`" @@ -450,13 +578,17 @@ msgstr "" msgid "Compute FFT" msgstr "Calculer la FFT" -msgid "`test_signal_fft <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fft1d_unit_test.py#L138>`_" +msgid "" +"`test_signal_fft <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/fft1d_unit_test.py#L138>`_" msgstr "" msgid ":py:func:`full_width_at_y <sigima.proc.signal.full_width_at_y>`" msgstr "" -msgid "`test_signal_full_width_at_y <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fwhm_unit_test.py#L143>`_" +msgid "" +"`test_signal_full_width_at_y <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/fwhm_unit_test.py#L172>`_" msgstr "" msgid ":py:func:`fw1e2 <sigima.proc.signal.fw1e2>`" @@ -465,7 +597,9 @@ msgstr "" msgid "Compute FW at 1/e²" msgstr "" -msgid "`test_signal_fw1e2 <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fwhm_unit_test.py#L133>`_" +msgid "" +"`test_signal_fw1e2 <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/fwhm_unit_test.py#L134>`_" msgstr "" msgid ":py:func:`fwhm <sigima.proc.signal.fwhm>`" @@ -474,7 +608,9 @@ msgstr "" msgid "Compute FWHM" msgstr "Fonctions de calcul" -msgid "`test_signal_fwhm <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fwhm_unit_test.py#L61>`_" +msgid "" +"`test_signal_fwhm <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/fwhm_unit_test.py#L62>`_" msgstr "" msgid ":py:func:`gaussian_filter <sigima.proc.signal.gaussian_filter>`" @@ -483,7 +619,9 @@ msgstr "" msgid "Compute gaussian filter" msgstr "" -msgid "`test_signal_gaussian_filter <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L271>`_" +msgid "" +"`test_signal_gaussian_filter <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/processing_unit_test.py#L271>`_" msgstr "" msgid ":py:func:`gaussian_fit <sigima.proc.signal.gaussian_fit>`" @@ -492,7 +630,9 @@ msgstr "" msgid "Compute Gaussian fit" msgstr "Calculer la déviation d'Allan" -msgid "`test_signal_gaussian_fit <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fitting_unit_test.py#L197>`_" +msgid "" +"`test_signal_gaussian_fit <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/fitting_unit_test.py#L220>`_" msgstr "" msgid ":py:func:`hadamard_variance <sigima.proc.signal.hadamard_variance>`" @@ -501,7 +641,9 @@ msgstr "" msgid "Compute Hadamard variance" msgstr "" -msgid "`test_signal_hadamard_variance <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/stability_unit_test.py#L301>`_" +msgid "" +"`test_signal_hadamard_variance <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/stability_unit_test.py#L215>`_" msgstr "" msgid ":py:func:`highpass <sigima.proc.signal.highpass>`" @@ -510,7 +652,9 @@ msgstr "" msgid "Compute high-pass filter" msgstr "" -msgid "`test_signal_highpass <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/filters_unit_test.py#L209>`_" +msgid "" +"`test_signal_highpass <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/filters_unit_test.py#L209>`_" msgstr "" msgid ":py:func:`histogram <sigima.proc.signal.histogram>`" @@ -519,7 +663,9 @@ msgstr "" msgid "Compute histogram" msgstr "Calculer l'histogramme" -msgid "`test_signal_histogram <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L388>`_" +msgid "" +"`test_signal_histogram <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/processing_unit_test.py#L388>`_" msgstr "" msgid ":py:func:`ifft <sigima.proc.signal.ifft>`" @@ -528,7 +674,9 @@ msgstr "" msgid "Compute the inverse FFT" msgstr "" -msgid "`test_signal_ifft <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fft1d_unit_test.py#L158>`_" +msgid "" +"`test_signal_ifft <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/fft1d_unit_test.py#L158>`_" msgstr "" msgid ":py:func:`imag <sigima.proc.signal.imag>`" @@ -537,7 +685,9 @@ msgstr "" msgid "Compute imaginary part" msgstr "" -msgid "`test_signal_imag <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L245>`_" +msgid "" +"`test_signal_imag <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/operation_unit_test.py#L245>`_" msgstr "" msgid ":py:func:`integral <sigima.proc.signal.integral>`" @@ -546,7 +696,9 @@ msgstr "" msgid "Compute integral" msgstr "Calculer l'intégrale" -msgid "`test_signal_integral <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L224>`_" +msgid "" +"`test_signal_integral <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/processing_unit_test.py#L224>`_" msgstr "" msgid ":py:func:`interpolate <sigima.proc.signal.interpolate>`" @@ -555,7 +707,9 @@ msgstr "" msgid "Interpolate data" msgstr "" -msgid "`test_signal_interpolate <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L486>`_" +msgid "" +"`test_signal_interpolate <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/processing_unit_test.py#L486>`_" msgstr "" msgid ":py:func:`inverse <sigima.proc.signal.inverse>`" @@ -564,7 +718,9 @@ msgstr "" msgid "Compute the element-wise inverse of a signal" msgstr "" -msgid "`test_signal_inverse <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L214>`_" +msgid "" +"`test_signal_inverse <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/operation_unit_test.py#L214>`_" msgstr "" msgid ":py:func:`linear_fit <sigima.proc.signal.linear_fit>`" @@ -573,7 +729,9 @@ msgstr "" msgid "Compute linear fit" msgstr "Calculer l'ajustement linéaire" -msgid "`test_signal_linear_fit <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fitting_unit_test.py#L114>`_" +msgid "" +"`test_signal_linear_fit <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/fitting_unit_test.py#L137>`_" msgstr "" msgid ":py:func:`log10 <sigima.proc.signal.log10>`" @@ -582,7 +740,9 @@ msgstr "" msgid "Compute Log10 with :py:data:`numpy.log10`" msgstr "" -msgid "`test_signal_log10 <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L373>`_" +msgid "" +"`test_signal_log10 <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/operation_unit_test.py#L373>`_" msgstr "" msgid ":py:func:`lorentzian_fit <sigima.proc.signal.lorentzian_fit>`" @@ -591,7 +751,9 @@ msgstr "" msgid "Compute Lorentzian fit" msgstr "Calculer l'ajustement lorentzien" -msgid "`test_signal_lorentzian_fit <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fitting_unit_test.py#L239>`_" +msgid "" +"`test_signal_lorentzian_fit <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/fitting_unit_test.py#L260>`_" msgstr "" msgid ":py:func:`lowpass <sigima.proc.signal.lowpass>`" @@ -600,7 +762,9 @@ msgstr "" msgid "Compute low-pass filter" msgstr "" -msgid "`test_signal_lowpass <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/filters_unit_test.py#L177>`_" +msgid "" +"`test_signal_lowpass <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/filters_unit_test.py#L177>`_" msgstr "" msgid ":py:func:`magnitude_spectrum <sigima.proc.signal.magnitude_spectrum>`" @@ -609,16 +773,22 @@ msgstr "" msgid "Compute magnitude spectrum" msgstr "" -msgid "`test_signal_magnitude_spectrum <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fft1d_unit_test.py#L203>`_" +msgid "" +"`test_signal_magnitude_spectrum <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/fft1d_unit_test.py#L203>`_" msgstr "" -msgid ":py:func:`modified_allan_variance <sigima.proc.signal.modified_allan_variance>`" +msgid "" +":py:func:`modified_allan_variance " +"<sigima.proc.signal.modified_allan_variance>`" msgstr "" msgid "Compute Modified Allan variance" msgstr "" -msgid "`test_signal_modified_allan_variance <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/stability_unit_test.py#L264>`_" +msgid "" +"`test_signal_modified_allan_variance <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/stability_unit_test.py#L192>`_" msgstr "" msgid ":py:func:`moving_average <sigima.proc.signal.moving_average>`" @@ -627,7 +797,9 @@ msgstr "" msgid "Compute moving average" msgstr "" -msgid "`test_signal_moving_average <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L282>`_" +msgid "" +"`test_signal_moving_average <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/processing_unit_test.py#L282>`_" msgstr "" msgid ":py:func:`moving_median <sigima.proc.signal.moving_median>`" @@ -636,7 +808,9 @@ msgstr "" msgid "Compute moving median" msgstr "" -msgid "`test_signal_moving_median <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L307>`_" +msgid "" +"`test_signal_moving_median <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/processing_unit_test.py#L307>`_" msgstr "" msgid ":py:func:`normalize <sigima.proc.signal.normalize>`" @@ -645,25 +819,35 @@ msgstr "" msgid "Normalize data" msgstr "" -msgid "`test_signal_normalize <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L157>`_" +msgid "" +"`test_signal_normalize <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/processing_unit_test.py#L157>`_" msgstr "" msgid ":py:func:`offset_correction <sigima.proc.signal.offset_correction>`" msgstr "" -msgid "Correct offset: subtract the mean value of the signal in the specified range" +msgid "" +"Correct offset: subtract the mean value of the signal in the specified " +"range" msgstr "" -msgid "`test_signal_offset_correction <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/offset_correction_unit_test.py#L20>`_" +msgid "" +"`test_signal_offset_correction <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/offset_correction_unit_test.py#L20>`_" msgstr "" -msgid ":py:func:`overlapping_allan_variance <sigima.proc.signal.overlapping_allan_variance>`" +msgid "" +":py:func:`overlapping_allan_variance " +"<sigima.proc.signal.overlapping_allan_variance>`" msgstr "" msgid "Compute Overlapping Allan variance" msgstr "" -msgid "`test_signal_overlapping_allan_variance <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/stability_unit_test.py#L204>`_" +msgid "" +"`test_signal_overlapping_allan_variance <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/stability_unit_test.py#L174>`_" msgstr "" msgid ":py:func:`peak_detection <sigima.proc.signal.peak_detection>`" @@ -672,7 +856,9 @@ msgstr "" msgid "Peak detection" msgstr "" -msgid "`test_signal_peak_detection <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/peakdetection_unit_test.py#L23>`_" +msgid "" +"`test_signal_peak_detection <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/peakdetection_unit_test.py#L23>`_" msgstr "" msgid ":py:func:`phase <sigima.proc.signal.phase>`" @@ -681,7 +867,9 @@ msgstr "" msgid "Compute the phase (argument) of a complex signal" msgstr "" -msgid "`test_signal_phase <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L273>`_" +msgid "" +"`test_signal_phase <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/operation_unit_test.py#L273>`_" msgstr "" msgid ":py:func:`phase_spectrum <sigima.proc.signal.phase_spectrum>`" @@ -690,16 +878,22 @@ msgstr "" msgid "Compute phase spectrum" msgstr "" -msgid "`test_signal_phase_spectrum <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fft1d_unit_test.py#L244>`_" +msgid "" +"`test_signal_phase_spectrum <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/fft1d_unit_test.py#L244>`_" msgstr "" -msgid ":py:func:`piecewiseexponential_fit <sigima.proc.signal.piecewiseexponential_fit>`" +msgid "" +":py:func:`piecewiseexponential_fit " +"<sigima.proc.signal.piecewiseexponential_fit>`" msgstr "" msgid "Compute piecewise exponential fit (raise-decay)" msgstr "Calculer l'ajustement exponentiel par morceaux (augmentation-décroissance)" -msgid "`test_signal_piecewiseexponential_fit <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fitting_unit_test.py#L341>`_" +msgid "" +"`test_signal_piecewiseexponential_fit <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/fitting_unit_test.py#L387>`_" msgstr "" msgid ":py:func:`planckian_fit <sigima.proc.signal.planckian_fit>`" @@ -708,7 +902,9 @@ msgstr "" msgid "Compute Planckian fit" msgstr "Calculer l'ajustement de Planck" -msgid "`test_signal_planckian_fit <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fitting_unit_test.py#L377>`_" +msgid "" +"`test_signal_planckian_fit <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/fitting_unit_test.py#L423>`_" msgstr "" msgid ":py:func:`polynomial_fit <sigima.proc.signal.polynomial_fit>`" @@ -717,7 +913,9 @@ msgstr "" msgid "Compute polynomial fit" msgstr "Calculer l'ajustement polynomial" -msgid "`test_polynomial_fit <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fitting_unit_test.py#L148>`_" +msgid "" +"`test_polynomial_fit <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/fitting_unit_test.py#L171>`_" msgstr "" msgid ":py:func:`power <sigima.proc.signal.power>`" @@ -726,7 +924,9 @@ msgstr "" msgid "Compute power with :py:data:`numpy.power`" msgstr "" -msgid "`test_signal_power <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L389>`_" +msgid "" +"`test_signal_power <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/operation_unit_test.py#L389>`_" msgstr "" msgid ":py:func:`product <sigima.proc.signal.product>`" @@ -735,7 +935,9 @@ msgstr "" msgid "Compute the element-wise product of multiple signals" msgstr "" -msgid "`test_signal_product <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L127>`_" +msgid "" +"`test_signal_product <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/operation_unit_test.py#L127>`_" msgstr "" msgid ":py:func:`product_constant <sigima.proc.signal.product_constant>`" @@ -744,7 +946,9 @@ msgstr "" msgid "Compute the product of a signal and a constant value" msgstr "" -msgid "`test_signal_product_constant <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L181>`_" +msgid "" +"`test_signal_product_constant <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/operation_unit_test.py#L181>`_" msgstr "" msgid ":py:func:`psd <sigima.proc.signal.psd>`" @@ -753,7 +957,9 @@ msgstr "" msgid "Compute power spectral density" msgstr "" -msgid "`test_signal_psd <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fft1d_unit_test.py#L270>`_" +msgid "" +"`test_signal_psd <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/fft1d_unit_test.py#L270>`_" msgstr "" msgid ":py:func:`quadratic_difference <sigima.proc.signal.quadratic_difference>`" @@ -762,7 +968,9 @@ msgstr "" msgid "Compute the normalized difference between two signals" msgstr "" -msgid "`test_signal_quadratic_difference <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L151>`_" +msgid "" +"`test_signal_quadratic_difference <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/operation_unit_test.py#L151>`_" msgstr "" msgid ":py:func:`real <sigima.proc.signal.real>`" @@ -771,7 +979,9 @@ msgstr "" msgid "Compute real part" msgstr "Calculer la partie réelle" -msgid "`test_signal_real <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L237>`_" +msgid "" +"`test_signal_real <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/operation_unit_test.py#L237>`_" msgstr "" msgid ":py:func:`replace_x_by_other_y <sigima.proc.signal.replace_x_by_other_y>`" @@ -780,7 +990,9 @@ msgstr "" msgid "Create a new signal using Y from src1 and Y from src2 as X coordinates" msgstr "" -msgid "`test_replace_x_by_other_y <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/replace_x_by_other_y_unit_test.py#L28>`_" +msgid "" +"`test_replace_x_by_other_y <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/replace_x_by_other_y_unit_test.py#L28>`_" msgstr "" msgid ":py:func:`resampling <sigima.proc.signal.resampling>`" @@ -789,7 +1001,9 @@ msgstr "" msgid "Resample data" msgstr "" -msgid "`test_signal_resampling <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L332>`_" +msgid "" +"`test_signal_resampling <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/processing_unit_test.py#L332>`_" msgstr "" msgid ":py:func:`reverse_x <sigima.proc.signal.reverse_x>`" @@ -798,7 +1012,9 @@ msgstr "" msgid "Reverse x-axis" msgstr "" -msgid "`test_signal_reverse_x <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L78>`_" +msgid "" +"`test_signal_reverse_x <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/processing_unit_test.py#L78>`_" msgstr "" msgid ":py:func:`sampling_rate_period <sigima.proc.signal.sampling_rate_period>`" @@ -807,7 +1023,9 @@ msgstr "" msgid "Compute sampling rate and period" msgstr "" -msgid "`test_signal_sampling_rate_period <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/analysis_unit_test.py#L78>`_" +msgid "" +"`test_signal_sampling_rate_period <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/analysis_unit_test.py#L78>`_" msgstr "" msgid ":py:func:`sigmoid_fit <sigima.proc.signal.sigmoid_fit>`" @@ -816,7 +1034,9 @@ msgstr "" msgid "Compute sigmoid fit" msgstr "Calculer l'ajustement sigmoïde" -msgid "`test_signal_sigmoid_fit <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fitting_unit_test.py#L494>`_" +msgid "" +"`test_signal_sigmoid_fit <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/fitting_unit_test.py#L540>`_" msgstr "" msgid ":py:func:`signals_to_image <sigima.proc.signal.signals_to_image>`" @@ -825,7 +1045,9 @@ msgstr "" msgid "Combine multiple signals into an image" msgstr "" -msgid "`test_signal_signals_to_image <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L424>`_" +msgid "" +"`test_signal_signals_to_image <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/operation_unit_test.py#L424>`_" msgstr "" msgid ":py:func:`sinusoidal_fit <sigima.proc.signal.sinusoidal_fit>`" @@ -834,7 +1056,9 @@ msgstr "" msgid "Compute sinusoidal fit" msgstr "Calculer l'ajustement sinusoïdal" -msgid "`test_sinusoidal_fit <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fitting_unit_test.py#L753>`_" +msgid "" +"`test_sinusoidal_fit <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/fitting_unit_test.py#L825>`_" msgstr "" msgid ":py:func:`sqrt <sigima.proc.signal.sqrt>`" @@ -843,7 +1067,9 @@ msgstr "" msgid "Compute square root with :py:data:`numpy.sqrt`" msgstr "" -msgid "`test_signal_sqrt <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L381>`_" +msgid "" +"`test_signal_sqrt <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/operation_unit_test.py#L381>`_" msgstr "" msgid ":py:func:`standard_deviation <sigima.proc.signal.standard_deviation>`" @@ -852,7 +1078,9 @@ msgstr "" msgid "Compute the element-wise standard deviation of multiple signals" msgstr "" -msgid "`test_signal_standard_deviation <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L107>`_" +msgid "" +"`test_signal_standard_deviation <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/operation_unit_test.py#L107>`_" msgstr "" msgid ":py:func:`stats <sigima.proc.signal.stats>`" @@ -861,7 +1089,9 @@ msgstr "" msgid "Compute statistics on a signal" msgstr "" -msgid "`test_signal_stats_unit <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/common/stat_unit_test.py#L81>`_" +msgid "" +"`test_signal_stats_unit <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/common/stat_unit_test.py#L81>`_" msgstr "" msgid ":py:func:`time_deviation <sigima.proc.signal.time_deviation>`" @@ -870,7 +1100,9 @@ msgstr "" msgid "Compute Time Deviation (TDEV)" msgstr "" -msgid "`test_signal_time_deviation <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/stability_unit_test.py#L376>`_" +msgid "" +"`test_signal_time_deviation <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/stability_unit_test.py#L254>`_" msgstr "" msgid ":py:func:`to_cartesian <sigima.proc.signal.to_cartesian>`" @@ -879,7 +1111,9 @@ msgstr "" msgid "Convert polar coordinates to Cartesian coordinates" msgstr "" -msgid "`test_signal_to_cartesian <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L139>`_" +msgid "" +"`test_signal_to_cartesian <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/processing_unit_test.py#L139>`_" msgstr "" msgid ":py:func:`to_polar <sigima.proc.signal.to_polar>`" @@ -888,7 +1122,9 @@ msgstr "" msgid "Convert Cartesian coordinates to polar coordinates" msgstr "" -msgid "`test_signal_to_polar <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L123>`_" +msgid "" +"`test_signal_to_polar <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/processing_unit_test.py#L123>`_" msgstr "" msgid ":py:func:`total_variance <sigima.proc.signal.total_variance>`" @@ -897,7 +1133,9 @@ msgstr "" msgid "Compute Total variance" msgstr "" -msgid "`test_signal_total_variance <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/stability_unit_test.py#L344>`_" +msgid "" +"`test_signal_total_variance <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/stability_unit_test.py#L233>`_" msgstr "" msgid ":py:func:`transpose <sigima.proc.signal.transpose>`" @@ -906,7 +1144,9 @@ msgstr "" msgid "Transpose signal (swap X and Y axes)" msgstr "" -msgid "`test_signal_transpose <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L68>`_" +msgid "" +"`test_signal_transpose <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/processing_unit_test.py#L68>`_" msgstr "" msgid ":py:func:`twohalfgaussian_fit <sigima.proc.signal.twohalfgaussian_fit>`" @@ -915,7 +1155,9 @@ msgstr "" msgid "Compute two-half-Gaussian fit" msgstr "" -msgid "`test_signal_twohalfgaussian_fit <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fitting_unit_test.py#L530>`_" +msgid "" +"`test_signal_twohalfgaussian_fit <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/fitting_unit_test.py#L576>`_" msgstr "" msgid ":py:func:`voigt_fit <sigima.proc.signal.voigt_fit>`" @@ -924,7 +1166,9 @@ msgstr "" msgid "Compute Voigt fit" msgstr "Calculer l'ajustement de Voigt" -msgid "`test_signal_voigt_fit <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fitting_unit_test.py#L272>`_" +msgid "" +"`test_signal_voigt_fit <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/fitting_unit_test.py#L291>`_" msgstr "" msgid ":py:func:`wiener <sigima.proc.signal.wiener>`" @@ -933,19 +1177,25 @@ msgstr "" msgid "Compute Wiener filter" msgstr "" -msgid "`test_signal_wiener <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L323>`_" +msgid "" +"`test_signal_wiener <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/processing_unit_test.py#L323>`_" msgstr "" msgid ":py:func:`x_at_minmax <sigima.proc.signal.x_at_minmax>`" msgstr "" -msgid "`test_signal_x_at_minmax <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/analysis_unit_test.py#L143>`_" +msgid "" +"`test_signal_x_at_minmax <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/analysis_unit_test.py#L143>`_" msgstr "" msgid ":py:func:`x_at_y <sigima.proc.signal.x_at_y>`" msgstr "" -msgid "`test_signal_x_at_y <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/analysis_unit_test.py#L153>`_" +msgid "" +"`test_signal_x_at_y <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/analysis_unit_test.py#L153>`_" msgstr "" msgid ":py:func:`xy_mode <sigima.proc.signal.xy_mode>`" @@ -954,13 +1204,17 @@ msgstr "" msgid "Simulate the X-Y mode of an oscilloscope" msgstr "" -msgid "`test_signal_xy_mode <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L360>`_" +msgid "" +"`test_signal_xy_mode <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/processing_unit_test.py#L360>`_" msgstr "" msgid ":py:func:`y_at_x <sigima.proc.signal.y_at_x>`" msgstr "" -msgid "`test_signal_y_at_x <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/analysis_unit_test.py#L166>`_" +msgid "" +"`test_signal_y_at_x <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/analysis_unit_test.py#L166>`_" msgstr "" msgid ":py:func:`zero_padding <sigima.proc.signal.zero_padding>`" @@ -969,14 +1223,21 @@ msgstr "" msgid "Compute zero padding" msgstr "" -msgid "`test_signal_zero_padding <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fft1d_unit_test.py#L26>`_" +msgid "" +"`test_signal_zero_padding <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/signal/fft1d_unit_test.py#L26>`_" msgstr "" msgid "Image Compute Functions" msgstr "Fonctions de calcul image" -msgid "The table below shows the validation status of image compute functions in DataLab. It is automatically generated from the source code." -msgstr "Le tableau ci-dessous montre l'état de validation des fonctions de calcul image dans DataLab. Il est généré automatiquement à partir du code source." +msgid "" +"The table below shows the validation status of image compute functions in" +" DataLab. It is automatically generated from the source code." +msgstr "" +"Le tableau ci-dessous montre l'état de validation des fonctions de calcul" +" image dans DataLab. Il est généré automatiquement à partir du code " +"source." msgid "Validation status of image compute functions" msgstr "Etat de validation des fonctions de calcul image" @@ -984,7 +1245,9 @@ msgstr "Etat de validation des fonctions de calcul image" msgid ":py:func:`absolute <sigima.proc.image.absolute>`" msgstr "" -msgid "`test_image_absolute <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L284>`_" +msgid "" +"`test_image_absolute <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/operation_unit_test.py#L284>`_" msgstr "" msgid ":py:func:`add_gaussian_noise <sigima.proc.image.add_gaussian_noise>`" @@ -993,7 +1256,9 @@ msgstr "" msgid "Add Gaussian (normal) noise to the input image" msgstr "" -msgid "`test_image_add_gaussian_noise <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/noise_unit_test.py#L21>`_" +msgid "" +"`test_image_add_gaussian_noise <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/noise_unit_test.py#L21>`_" msgstr "" msgid ":py:func:`add_poisson_noise <sigima.proc.image.add_poisson_noise>`" @@ -1002,7 +1267,9 @@ msgstr "" msgid "Add Poisson noise to the input image" msgstr "" -msgid "`test_image_add_poisson_noise <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/noise_unit_test.py#L59>`_" +msgid "" +"`test_image_add_poisson_noise <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/noise_unit_test.py#L59>`_" msgstr "" msgid ":py:func:`add_uniform_noise <sigima.proc.image.add_uniform_noise>`" @@ -1011,7 +1278,9 @@ msgstr "" msgid "Add uniform noise to the input image" msgstr "" -msgid "`test_image_add_uniform_noise <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/noise_unit_test.py#L97>`_" +msgid "" +"`test_image_add_uniform_noise <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/noise_unit_test.py#L97>`_" msgstr "" msgid ":py:func:`addition <sigima.proc.image.addition>`" @@ -1020,7 +1289,9 @@ msgstr "" msgid "Add images in the list and return the result image object" msgstr "" -msgid "`test_image_addition <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L47>`_" +msgid "" +"`test_image_addition <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/operation_unit_test.py#L47>`_" msgstr "" msgid ":py:func:`addition_constant <sigima.proc.image.addition_constant>`" @@ -1029,7 +1300,9 @@ msgstr "" msgid "Add **dst** and a constant value and return the new result image object" msgstr "" -msgid "`test_image_addition_constant <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L184>`_" +msgid "" +"`test_image_addition_constant <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/operation_unit_test.py#L184>`_" msgstr "" msgid ":py:func:`adjust_gamma <sigima.proc.image.adjust_gamma>`" @@ -1038,7 +1311,9 @@ msgstr "" msgid "Gamma correction" msgstr "" -msgid "`test_adjust_gamma <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/exposure_unit_test.py#L21>`_" +msgid "" +"`test_adjust_gamma <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/exposure_unit_test.py#L21>`_" msgstr "" msgid ":py:func:`adjust_log <sigima.proc.image.adjust_log>`" @@ -1047,7 +1322,9 @@ msgstr "" msgid "Compute log correction" msgstr "Calculer l'ajustement logarithmique" -msgid "`test_adjust_log <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/exposure_unit_test.py#L33>`_" +msgid "" +"`test_adjust_log <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/exposure_unit_test.py#L33>`_" msgstr "" msgid ":py:func:`adjust_sigmoid <sigima.proc.image.adjust_sigmoid>`" @@ -1056,7 +1333,9 @@ msgstr "" msgid "Compute sigmoid correction" msgstr "Calculer l'ajustement sigmoïde" -msgid "`test_adjust_sigmoid <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/exposure_unit_test.py#L45>`_" +msgid "" +"`test_adjust_sigmoid <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/exposure_unit_test.py#L45>`_" msgstr "" msgid ":py:func:`arithmetic <sigima.proc.image.arithmetic>`" @@ -1065,7 +1344,9 @@ msgstr "" msgid "Compute arithmetic operation on two images" msgstr "" -msgid "`test_image_arithmetic <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L234>`_" +msgid "" +"`test_image_arithmetic <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/operation_unit_test.py#L234>`_" msgstr "" msgid ":py:func:`astype <sigima.proc.image.astype>`" @@ -1074,16 +1355,22 @@ msgstr "" msgid "Convert image data type" msgstr "" -msgid "`test_image_astype <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L438>`_" +msgid "" +"`test_image_astype <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/operation_unit_test.py#L438>`_" msgstr "" msgid ":py:func:`average <sigima.proc.image.average>`" msgstr "" -msgid "Compute the average of images in the list and return the result image object" +msgid "" +"Compute the average of images in the list and return the result image " +"object" msgstr "" -msgid "`test_image_average <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L67>`_" +msgid "" +"`test_image_average <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/operation_unit_test.py#L67>`_" msgstr "" msgid ":py:func:`average_profile <sigima.proc.image.average_profile>`" @@ -1092,7 +1379,9 @@ msgstr "" msgid "Compute horizontal or vertical average profile" msgstr "" -msgid "`test_average_profile <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/profile_unit_test.py#L70>`_" +msgid "" +"`test_average_profile <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/profile_unit_test.py#L70>`_" msgstr "" msgid ":py:func:`binning <sigima.proc.image.binning>`" @@ -1101,7 +1390,9 @@ msgstr "" msgid "Binning: image pixel binning (or aggregation)" msgstr "" -msgid "`test_binning <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/binning_unit_test.py#L71>`_" +msgid "" +"`test_binning <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/binning_unit_test.py#L71>`_" msgstr "" msgid ":py:func:`black_tophat <sigima.proc.image.black_tophat>`" @@ -1110,7 +1401,9 @@ msgstr "" msgid "Compute Black Top-Hat" msgstr "" -msgid "`test_black_tophat <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/morphology_unit_test.py#L43>`_" +msgid "" +"`test_black_tophat <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/morphology_unit_test.py#L43>`_" msgstr "" msgid ":py:func:`blob_dog <sigima.proc.image.blob_dog>`" @@ -1119,7 +1412,9 @@ msgstr "" msgid "Compute blobs using Difference of Gaussian method" msgstr "" -msgid "`test_image_blob_dog <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/blob_detection_unit_test.py#L110>`_" +msgid "" +"`test_image_blob_dog <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/blob_detection_unit_test.py#L110>`_" msgstr "" msgid ":py:func:`blob_doh <sigima.proc.image.blob_doh>`" @@ -1128,7 +1423,9 @@ msgstr "" msgid "Compute blobs using Determinant of Hessian method" msgstr "" -msgid "`test_image_blob_doh <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/blob_detection_unit_test.py#L187>`_" +msgid "" +"`test_image_blob_doh <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/blob_detection_unit_test.py#L187>`_" msgstr "" msgid ":py:func:`blob_log <sigima.proc.image.blob_log>`" @@ -1137,7 +1434,9 @@ msgstr "" msgid "Compute blobs using Laplacian of Gaussian method" msgstr "" -msgid "`test_image_blob_log <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/blob_detection_unit_test.py#L226>`_" +msgid "" +"`test_image_blob_log <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/blob_detection_unit_test.py#L226>`_" msgstr "" msgid ":py:func:`blob_opencv <sigima.proc.image.blob_opencv>`" @@ -1146,7 +1445,9 @@ msgstr "" msgid "Compute blobs using OpenCV" msgstr "" -msgid "`test_image_blob_opencv <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/blob_detection_unit_test.py#L266>`_" +msgid "" +"`test_image_blob_opencv <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/blob_detection_unit_test.py#L266>`_" msgstr "" msgid ":py:func:`butterworth <sigima.proc.image.butterworth>`" @@ -1155,7 +1456,9 @@ msgstr "" msgid "Compute Butterworth filter" msgstr "" -msgid "`test_butterworth <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/filtering_unit_test.py#L70>`_" +msgid "" +"`test_butterworth <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/filtering_unit_test.py#L70>`_" msgstr "" msgid ":py:func:`calibration <sigima.proc.image.calibration>`" @@ -1164,7 +1467,9 @@ msgstr "" msgid "Compute polynomial calibration" msgstr "Calculer l'étalonnage polynomial" -msgid "`test_image_calibration <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/geometry_unit_test.py#L578>`_" +msgid "" +"`test_image_calibration <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/geometry_unit_test.py#L658>`_" msgstr "" msgid ":py:func:`canny <sigima.proc.image.canny>`" @@ -1173,7 +1478,9 @@ msgstr "" msgid "Compute Canny filter" msgstr "" -msgid "`test_canny <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/edges_unit_test.py#L21>`_" +msgid "" +"`test_canny <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/edges_unit_test.py#L21>`_" msgstr "" msgid ":py:func:`centroid <sigima.proc.image.centroid>`" @@ -1182,7 +1489,9 @@ msgstr "" msgid "Compute centroid" msgstr "" -msgid "`test_image_centroid <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/centroid_unit_test.py#L147>`_" +msgid "" +"`test_image_centroid <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/centroid_unit_test.py#L147>`_" msgstr "" msgid ":py:func:`clip <sigima.proc.image.clip>`" @@ -1191,7 +1500,9 @@ msgstr "" msgid "Apply clipping" msgstr "" -msgid "`test_image_clip <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/exposure_unit_test.py#L158>`_" +msgid "" +"`test_image_clip <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/exposure_unit_test.py#L158>`_" msgstr "" msgid ":py:func:`closing <sigima.proc.image.closing>`" @@ -1200,25 +1511,35 @@ msgstr "" msgid "Compute morphological closing" msgstr "" -msgid "`test_closing <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/morphology_unit_test.py#L67>`_" +msgid "" +"`test_closing <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/morphology_unit_test.py#L67>`_" msgstr "" -msgid ":py:func:`complex_from_magnitude_phase <sigima.proc.image.complex_from_magnitude_phase>`" +msgid "" +":py:func:`complex_from_magnitude_phase " +"<sigima.proc.image.complex_from_magnitude_phase>`" msgstr "" msgid "Combine magnitude and phase images into a complex image" msgstr "" -msgid "`test_image_complex_from_magnitude_phase <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L399>`_" +msgid "" +"`test_image_complex_from_magnitude_phase <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/operation_unit_test.py#L399>`_" msgstr "" -msgid ":py:func:`complex_from_real_imag <sigima.proc.image.complex_from_real_imag>`" +msgid "" +":py:func:`complex_from_real_imag " +"<sigima.proc.image.complex_from_real_imag>`" msgstr "" msgid "Combine two real images into a complex image using real + i * imag" msgstr "" -msgid "`test_image_complex_from_real_imag <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L317>`_" +msgid "" +"`test_image_complex_from_real_imag <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/operation_unit_test.py#L317>`_" msgstr "" msgid ":py:func:`contour_shape <sigima.proc.image.contour_shape>`" @@ -1228,7 +1549,9 @@ msgstr "" msgid "Compute contour shape" msgstr "Calculer le contraste" -msgid "`test_contour_shape <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/contour_unit_test.py#L55>`_" +msgid "" +"`test_contour_shape <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/contour_unit_test.py#L55>`_" msgstr "" msgid ":py:func:`convolution <sigima.proc.image.convolution>`" @@ -1237,7 +1560,9 @@ msgstr "" msgid "Convolve an image with a kernel" msgstr "" -msgid "`test_image_convolution <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/convolution_unit_test.py#L107>`_" +msgid "" +"`test_image_convolution <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/convolution_unit_test.py#L107>`_" msgstr "" msgid ":py:func:`deconvolution <sigima.proc.image.deconvolution>`" @@ -1246,7 +1571,9 @@ msgstr "" msgid "Deconvolve a kernel from an image using Fast Fourier Transform (FFT)" msgstr "" -msgid "`test_image_deconvolution <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/convolution_unit_test.py#L139>`_" +msgid "" +"`test_image_deconvolution <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/convolution_unit_test.py#L139>`_" msgstr "" msgid ":py:func:`denoise_bilateral <sigima.proc.image.denoise_bilateral>`" @@ -1255,7 +1582,9 @@ msgstr "" msgid "Compute bilateral filter denoising" msgstr "" -msgid "`test_denoise_bilateral <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/restoration_unit_test.py#L41>`_" +msgid "" +"`test_denoise_bilateral <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/restoration_unit_test.py#L41>`_" msgstr "" msgid ":py:func:`denoise_tophat <sigima.proc.image.denoise_tophat>`" @@ -1264,7 +1593,9 @@ msgstr "" msgid "Denoise using White Top-Hat" msgstr "" -msgid "`test_denoise_tophat <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/restoration_unit_test.py#L81>`_" +msgid "" +"`test_denoise_tophat <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/restoration_unit_test.py#L81>`_" msgstr "" msgid ":py:func:`denoise_tv <sigima.proc.image.denoise_tv>`" @@ -1273,7 +1604,9 @@ msgstr "" msgid "Compute Total Variation denoising" msgstr "" -msgid "`test_denoise_tv <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/restoration_unit_test.py#L22>`_" +msgid "" +"`test_denoise_tv <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/restoration_unit_test.py#L22>`_" msgstr "" msgid ":py:func:`denoise_wavelet <sigima.proc.image.denoise_wavelet>`" @@ -1282,7 +1615,9 @@ msgstr "" msgid "Compute Wavelet denoising" msgstr "" -msgid "`test_denoise_wavelet <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/restoration_unit_test.py#L58>`_" +msgid "" +"`test_denoise_wavelet <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/restoration_unit_test.py#L58>`_" msgstr "" msgid ":py:func:`difference <sigima.proc.image.difference>`" @@ -1291,16 +1626,22 @@ msgstr "" msgid "Compute difference between two images" msgstr "" -msgid "`test_image_difference <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L103>`_" +msgid "" +"`test_image_difference <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/operation_unit_test.py#L103>`_" msgstr "" msgid ":py:func:`difference_constant <sigima.proc.image.difference_constant>`" msgstr "" -msgid "Subtract a constant value from an image and return the new result image object" +msgid "" +"Subtract a constant value from an image and return the new result image " +"object" msgstr "" -msgid "`test_image_difference_constant <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L197>`_" +msgid "" +"`test_image_difference_constant <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/operation_unit_test.py#L197>`_" msgstr "" msgid ":py:func:`dilation <sigima.proc.image.dilation>`" @@ -1309,7 +1650,9 @@ msgstr "" msgid "Compute Dilation" msgstr "Calculer la dilatation" -msgid "`test_dilation <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/morphology_unit_test.py#L55>`_" +msgid "" +"`test_dilation <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/morphology_unit_test.py#L55>`_" msgstr "" msgid ":py:func:`division <sigima.proc.image.division>`" @@ -1318,7 +1661,9 @@ msgstr "" msgid "Compute division between two images" msgstr "" -msgid "`test_image_division <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L147>`_" +msgid "" +"`test_image_division <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/operation_unit_test.py#L147>`_" msgstr "" msgid ":py:func:`division_constant <sigima.proc.image.division_constant>`" @@ -1327,7 +1672,9 @@ msgstr "" msgid "Divide an image by a constant value and return the new result image object" msgstr "" -msgid "`test_image_division_constant <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L222>`_" +msgid "" +"`test_image_division_constant <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/operation_unit_test.py#L222>`_" msgstr "" msgid ":py:func:`enclosing_circle <sigima.proc.image.enclosing_circle>`" @@ -1336,7 +1683,9 @@ msgstr "" msgid "Compute minimum enclosing circle" msgstr "" -msgid "`test_image_enclosing_circle <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/enclosingcircle_unit_test.py#L55>`_" +msgid "" +"`test_image_enclosing_circle <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/enclosingcircle_unit_test.py#L55>`_" msgstr "" msgid ":py:func:`equalize_adapthist <sigima.proc.image.equalize_adapthist>`" @@ -1345,7 +1694,9 @@ msgstr "" msgid "Adaptive histogram equalization" msgstr "" -msgid "`test_equalize_adapthist <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/exposure_unit_test.py#L84>`_" +msgid "" +"`test_equalize_adapthist <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/exposure_unit_test.py#L84>`_" msgstr "" msgid ":py:func:`equalize_hist <sigima.proc.image.equalize_hist>`" @@ -1354,7 +1705,9 @@ msgstr "" msgid "Histogram equalization" msgstr "" -msgid "`test_equalize_hist <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/exposure_unit_test.py#L72>`_" +msgid "" +"`test_equalize_hist <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/exposure_unit_test.py#L72>`_" msgstr "" msgid ":py:func:`erase <sigima.proc.image.erase>`" @@ -1363,7 +1716,9 @@ msgstr "" msgid "Erase an area of the image using the mean value of the image" msgstr "" -msgid "`test_erase <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/restoration_unit_test.py#L93>`_" +msgid "" +"`test_erase <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/restoration_unit_test.py#L93>`_" msgstr "" msgid ":py:func:`erosion <sigima.proc.image.erosion>`" @@ -1372,13 +1727,17 @@ msgstr "" msgid "Compute Erosion" msgstr "Calculer l'érosion" -msgid "`test_erosion <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/morphology_unit_test.py#L49>`_" +msgid "" +"`test_erosion <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/morphology_unit_test.py#L49>`_" msgstr "" msgid ":py:func:`exp <sigima.proc.image.exp>`" msgstr "" -msgid "`test_image_exp <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L459>`_" +msgid "" +"`test_image_exp <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/operation_unit_test.py#L459>`_" msgstr "" msgid ":py:func:`extract_roi <sigima.proc.image.extract_roi>`" @@ -1387,13 +1746,17 @@ msgstr "" msgid "Extract single ROI" msgstr "" -msgid "`test_image_extract_roi <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/roi_advanced_unit_test.py#L231>`_" +msgid "" +"`test_image_extract_roi <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/roi_advanced_unit_test.py#L231>`_" msgstr "" msgid ":py:func:`extract_rois <sigima.proc.image.extract_rois>`" msgstr "" -msgid "`test_image_extract_rois <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/roi_advanced_unit_test.py#L201>`_" +msgid "" +"`test_image_extract_rois <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/roi_advanced_unit_test.py#L201>`_" msgstr "" msgid ":py:func:`farid <sigima.proc.image.farid>`" @@ -1402,7 +1765,9 @@ msgstr "" msgid "Compute Farid filter" msgstr "" -msgid "`test_farid <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/edges_unit_test.py#L118>`_" +msgid "" +"`test_farid <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/edges_unit_test.py#L118>`_" msgstr "" msgid ":py:func:`farid_h <sigima.proc.image.farid_h>`" @@ -1411,7 +1776,9 @@ msgstr "" msgid "Compute horizontal Farid filter" msgstr "" -msgid "`test_farid_h <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/edges_unit_test.py#L124>`_" +msgid "" +"`test_farid_h <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/edges_unit_test.py#L124>`_" msgstr "" msgid ":py:func:`farid_v <sigima.proc.image.farid_v>`" @@ -1420,13 +1787,17 @@ msgstr "" msgid "Compute vertical Farid filter" msgstr "" -msgid "`test_farid_v <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/edges_unit_test.py#L130>`_" +msgid "" +"`test_farid_v <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/edges_unit_test.py#L130>`_" msgstr "" msgid ":py:func:`fft <sigima.proc.image.fft>`" msgstr "" -msgid "`test_image_fft <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/fft2d_unit_test.py#L118>`_" +msgid "" +"`test_image_fft <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/fft2d_unit_test.py#L118>`_" msgstr "" msgid ":py:func:`flatfield <sigima.proc.image.flatfield>`" @@ -1435,7 +1806,9 @@ msgstr "" msgid "Compute flat field correction" msgstr "Calculer la correction de champ plat" -msgid "`test_flatfield <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/exposure_unit_test.py#L96>`_" +msgid "" +"`test_flatfield <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/exposure_unit_test.py#L96>`_" msgstr "" msgid ":py:func:`fliph <sigima.proc.image.fliph>`" @@ -1444,7 +1817,9 @@ msgstr "" msgid "Flip data horizontally" msgstr "" -msgid "`test_image_fliph <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/geometry_unit_test.py#L48>`_" +msgid "" +"`test_image_fliph <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/geometry_unit_test.py#L48>`_" msgstr "" msgid ":py:func:`flipv <sigima.proc.image.flipv>`" @@ -1453,13 +1828,17 @@ msgstr "" msgid "Flip data vertically" msgstr "" -msgid "`test_image_flipv <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/geometry_unit_test.py#L54>`_" +msgid "" +"`test_image_flipv <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/geometry_unit_test.py#L54>`_" msgstr "" msgid ":py:func:`gaussian_filter <sigima.proc.image.gaussian_filter>`" msgstr "" -msgid "`test_image_gaussian_filter <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/filtering_unit_test.py#L26>`_" +msgid "" +"`test_image_gaussian_filter <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/filtering_unit_test.py#L26>`_" msgstr "" msgid ":py:func:`gaussian_freq_filter <sigima.proc.image.gaussian_freq_filter>`" @@ -1468,7 +1847,9 @@ msgstr "" msgid "Apply a Gaussian filter in the frequency domain" msgstr "" -msgid "`test_gaussian_freq_filter <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/filtering_unit_test.py#L116>`_" +msgid "" +"`test_gaussian_freq_filter <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/filtering_unit_test.py#L116>`_" msgstr "" msgid ":py:func:`histogram <sigima.proc.image.histogram>`" @@ -1477,16 +1858,22 @@ msgstr "" msgid "Compute histogram of the image data," msgstr "" -msgid "`test_image_histogram <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/exposure_unit_test.py#L171>`_" +msgid "" +"`test_image_histogram <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/exposure_unit_test.py#L171>`_" msgstr "" msgid ":py:func:`horizontal_projection <sigima.proc.image.horizontal_projection>`" msgstr "" -msgid "Compute the sum of pixel intensities along each col. (projection on the x-axis)" +msgid "" +"Compute the sum of pixel intensities along each col. (projection on the " +"x-axis)" msgstr "" -msgid "`test_image_horizontal_projection <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/projections_unit_test.py#L17>`_" +msgid "" +"`test_image_horizontal_projection <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/projections_unit_test.py#L17>`_" msgstr "" msgid ":py:func:`hough_circle_peaks <sigima.proc.image.hough_circle_peaks>`" @@ -1495,7 +1882,9 @@ msgstr "" msgid "Compute Hough circles" msgstr "" -msgid "`test_image_hough_circle_peaks <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/hough_circle_unit_test.py#L60>`_" +msgid "" +"`test_image_hough_circle_peaks <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/hough_circle_unit_test.py#L60>`_" msgstr "" msgid ":py:func:`ifft <sigima.proc.image.ifft>`" @@ -1504,13 +1893,17 @@ msgstr "" msgid "Compute inverse FFT" msgstr "" -msgid "`test_image_ifft <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/fft2d_unit_test.py#L134>`_" +msgid "" +"`test_image_ifft <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/fft2d_unit_test.py#L134>`_" msgstr "" msgid ":py:func:`imag <sigima.proc.image.imag>`" msgstr "" -msgid "`test_image_imag <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L306>`_" +msgid "" +"`test_image_imag <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/operation_unit_test.py#L306>`_" msgstr "" msgid ":py:func:`inverse <sigima.proc.image.inverse>`" @@ -1519,7 +1912,9 @@ msgstr "" msgid "Compute the inverse of an image and return the new result image object" msgstr "" -msgid "`test_image_inverse <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L270>`_" +msgid "" +"`test_image_inverse <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/operation_unit_test.py#L270>`_" msgstr "" msgid ":py:func:`laplace <sigima.proc.image.laplace>`" @@ -1528,7 +1923,9 @@ msgstr "" msgid "Compute Laplace filter" msgstr "" -msgid "`test_laplace <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/edges_unit_test.py#L136>`_" +msgid "" +"`test_laplace <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/edges_unit_test.py#L136>`_" msgstr "" msgid ":py:func:`line_profile <sigima.proc.image.line_profile>`" @@ -1537,7 +1934,9 @@ msgstr "" msgid "Compute horizontal or vertical profile" msgstr "" -msgid "`test_line_profile <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/profile_unit_test.py#L19>`_" +msgid "" +"`test_line_profile <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/profile_unit_test.py#L19>`_" msgstr "" msgid ":py:func:`log10 <sigima.proc.image.log10>`" @@ -1546,7 +1945,9 @@ msgstr "" msgid "Compute log10 with :py:data:`numpy.log10`" msgstr "" -msgid "`test_image_log10 <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L471>`_" +msgid "" +"`test_image_log10 <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/operation_unit_test.py#L471>`_" msgstr "" msgid ":py:func:`log10_z_plus_n <sigima.proc.image.log10_z_plus_n>`" @@ -1555,31 +1956,41 @@ msgstr "" msgid "Compute log10(z+n) with :py:data:`numpy.log10`" msgstr "" -msgid "`test_image_log10_z_plus_n <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L483>`_" +msgid "" +"`test_image_log10_z_plus_n <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/operation_unit_test.py#L483>`_" msgstr "" msgid ":py:func:`magnitude_spectrum <sigima.proc.image.magnitude_spectrum>`" msgstr "" -msgid "`test_image_magnitude_spectrum <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/fft2d_unit_test.py#L143>`_" +msgid "" +"`test_image_magnitude_spectrum <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/fft2d_unit_test.py#L143>`_" msgstr "" msgid ":py:func:`moving_average <sigima.proc.image.moving_average>`" msgstr "" -msgid "`test_image_moving_average <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/filtering_unit_test.py#L37>`_" +msgid "" +"`test_image_moving_average <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/filtering_unit_test.py#L37>`_" msgstr "" msgid ":py:func:`moving_median <sigima.proc.image.moving_median>`" msgstr "" -msgid "`test_image_moving_median <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/filtering_unit_test.py#L49>`_" +msgid "" +"`test_image_moving_median <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/filtering_unit_test.py#L49>`_" msgstr "" msgid ":py:func:`normalize <sigima.proc.image.normalize>`" msgstr "" -msgid "`test_image_normalize <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/exposure_unit_test.py#L122>`_" +msgid "" +"`test_image_normalize <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/exposure_unit_test.py#L122>`_" msgstr "" msgid ":py:func:`offset_correction <sigima.proc.image.offset_correction>`" @@ -1588,7 +1999,9 @@ msgstr "" msgid "Apply offset correction" msgstr "" -msgid "`test_image_offset_correction <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/exposure_unit_test.py#L199>`_" +msgid "" +"`test_image_offset_correction <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/exposure_unit_test.py#L199>`_" msgstr "" msgid ":py:func:`opening <sigima.proc.image.opening>`" @@ -1597,7 +2010,9 @@ msgstr "" msgid "Compute morphological opening" msgstr "" -msgid "`test_opening <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/morphology_unit_test.py#L61>`_" +msgid "" +"`test_opening <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/morphology_unit_test.py#L61>`_" msgstr "" msgid ":py:func:`peak_detection <sigima.proc.image.peak_detection>`" @@ -1606,7 +2021,9 @@ msgstr "" msgid "Compute 2D peak detection" msgstr "" -msgid "`test_image_peak_detection <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/peak2d_unit_test.py#L84>`_" +msgid "" +"`test_image_peak_detection <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/peak2d_unit_test.py#L84>`_" msgstr "" msgid ":py:func:`phase <sigima.proc.image.phase>`" @@ -1615,13 +2032,17 @@ msgstr "" msgid "Compute the phase (argument) of a complex image" msgstr "" -msgid "`test_image_phase <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L334>`_" +msgid "" +"`test_image_phase <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/operation_unit_test.py#L334>`_" msgstr "" msgid ":py:func:`phase_spectrum <sigima.proc.image.phase_spectrum>`" msgstr "" -msgid "`test_image_phase_spectrum <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/fft2d_unit_test.py#L158>`_" +msgid "" +"`test_image_phase_spectrum <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/fft2d_unit_test.py#L158>`_" msgstr "" msgid ":py:func:`prewitt <sigima.proc.image.prewitt>`" @@ -1630,7 +2051,9 @@ msgstr "" msgid "Compute Prewitt filter" msgstr "" -msgid "`test_prewitt <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/edges_unit_test.py#L64>`_" +msgid "" +"`test_prewitt <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/edges_unit_test.py#L64>`_" msgstr "" msgid ":py:func:`prewitt_h <sigima.proc.image.prewitt_h>`" @@ -1639,7 +2062,9 @@ msgstr "" msgid "Compute horizontal Prewitt filter" msgstr "" -msgid "`test_prewitt_h <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/edges_unit_test.py#L70>`_" +msgid "" +"`test_prewitt_h <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/edges_unit_test.py#L70>`_" msgstr "" msgid ":py:func:`prewitt_v <sigima.proc.image.prewitt_v>`" @@ -1648,7 +2073,9 @@ msgstr "" msgid "Compute vertical Prewitt filter" msgstr "" -msgid "`test_prewitt_v <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/edges_unit_test.py#L76>`_" +msgid "" +"`test_prewitt_v <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/edges_unit_test.py#L76>`_" msgstr "" msgid ":py:func:`product <sigima.proc.image.product>`" @@ -1657,22 +2084,30 @@ msgstr "" msgid "Multiply images in the list and return the result image object" msgstr "" -msgid "`test_image_product <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L127>`_" +msgid "" +"`test_image_product <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/operation_unit_test.py#L127>`_" msgstr "" msgid ":py:func:`product_constant <sigima.proc.image.product_constant>`" msgstr "" -msgid "Multiply **dst** by a constant value and return the new result image object" +msgid "" +"Multiply **dst** by a constant value and return the new result image " +"object" msgstr "" -msgid "`test_image_product_constant <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L210>`_" +msgid "" +"`test_image_product_constant <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/operation_unit_test.py#L210>`_" msgstr "" msgid ":py:func:`psd <sigima.proc.image.psd>`" msgstr "" -msgid "`test_image_psd <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/fft2d_unit_test.py#L170>`_" +msgid "" +"`test_image_psd <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/fft2d_unit_test.py#L170>`_" msgstr "" msgid ":py:func:`quadratic_difference <sigima.proc.image.quadratic_difference>`" @@ -1681,7 +2116,9 @@ msgstr "" msgid "Compute quadratic difference between two images" msgstr "" -msgid "`test_image_quadratic_difference <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L115>`_" +msgid "" +"`test_image_quadratic_difference <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/operation_unit_test.py#L115>`_" msgstr "" msgid ":py:func:`radial_profile <sigima.proc.image.radial_profile>`" @@ -1690,13 +2127,17 @@ msgstr "" msgid "Compute radial profile around the centroid" msgstr "" -msgid "`test_radial_profile <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/profile_unit_test.py#L123>`_" +msgid "" +"`test_radial_profile <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/profile_unit_test.py#L123>`_" msgstr "" msgid ":py:func:`real <sigima.proc.image.real>`" msgstr "" -msgid "`test_image_real <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L295>`_" +msgid "" +"`test_image_real <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/operation_unit_test.py#L295>`_" msgstr "" msgid ":py:func:`resampling <sigima.proc.image.resampling>`" @@ -1705,7 +2146,9 @@ msgstr "" msgid "Resample image to new coordinate grid using interpolation" msgstr "" -msgid "`test_image_resampling <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/geometry_unit_test.py#L215>`_" +msgid "" +"`test_image_resampling <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/geometry_unit_test.py#L295>`_" msgstr "" msgid ":py:func:`rescale_intensity <sigima.proc.image.rescale_intensity>`" @@ -1714,7 +2157,9 @@ msgstr "" msgid "Rescale image intensity levels" msgstr "" -msgid "`test_rescale_intensity <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/exposure_unit_test.py#L59>`_" +msgid "" +"`test_rescale_intensity <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/exposure_unit_test.py#L59>`_" msgstr "" msgid ":py:func:`resize <sigima.proc.image.resize>`" @@ -1723,7 +2168,9 @@ msgstr "" msgid "Zooming function" msgstr "Fonction de zoom" -msgid "`test_image_resize <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/geometry_unit_test.py#L399>`_" +msgid "" +"`test_image_resize <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/geometry_unit_test.py#L479>`_" msgstr "" msgid ":py:func:`roberts <sigima.proc.image.roberts>`" @@ -1732,7 +2179,9 @@ msgstr "" msgid "Compute Roberts filter" msgstr "" -msgid "`test_roberts <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/edges_unit_test.py#L58>`_" +msgid "" +"`test_roberts <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/edges_unit_test.py#L58>`_" msgstr "" msgid ":py:func:`rotate <sigima.proc.image.rotate>`" @@ -1741,7 +2190,9 @@ msgstr "" msgid "Rotate data" msgstr "" -msgid "`test_image_rotate <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/geometry_unit_test.py#L162>`_" +msgid "" +"`test_image_rotate <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/geometry_unit_test.py#L242>`_" msgstr "" msgid ":py:func:`rotate270 <sigima.proc.image.rotate270>`" @@ -1750,7 +2201,9 @@ msgstr "" msgid "Rotate data 270°" msgstr "" -msgid "`test_image_rotate270 <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/geometry_unit_test.py#L80>`_" +msgid "" +"`test_image_rotate270 <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/geometry_unit_test.py#L80>`_" msgstr "" msgid ":py:func:`rotate90 <sigima.proc.image.rotate90>`" @@ -1759,7 +2212,9 @@ msgstr "" msgid "Rotate data 90°" msgstr "" -msgid "`test_image_rotate90 <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/geometry_unit_test.py#L74>`_" +msgid "" +"`test_image_rotate90 <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/geometry_unit_test.py#L74>`_" msgstr "" msgid ":py:func:`scharr <sigima.proc.image.scharr>`" @@ -1768,7 +2223,9 @@ msgstr "" msgid "Compute Scharr filter" msgstr "" -msgid "`test_scharr <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/edges_unit_test.py#L100>`_" +msgid "" +"`test_scharr <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/edges_unit_test.py#L100>`_" msgstr "" msgid ":py:func:`scharr_h <sigima.proc.image.scharr_h>`" @@ -1777,7 +2234,9 @@ msgstr "" msgid "Compute horizontal Scharr filter" msgstr "" -msgid "`test_scharr_h <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/edges_unit_test.py#L106>`_" +msgid "" +"`test_scharr_h <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/edges_unit_test.py#L106>`_" msgstr "" msgid ":py:func:`scharr_v <sigima.proc.image.scharr_v>`" @@ -1786,7 +2245,9 @@ msgstr "" msgid "Compute vertical Scharr filter" msgstr "" -msgid "`test_scharr_v <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/edges_unit_test.py#L112>`_" +msgid "" +"`test_scharr_v <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/edges_unit_test.py#L112>`_" msgstr "" msgid ":py:func:`segment_profile <sigima.proc.image.segment_profile>`" @@ -1795,7 +2256,9 @@ msgstr "" msgid "Compute segment profile" msgstr "" -msgid "`test_segment_profile <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/profile_unit_test.py#L48>`_" +msgid "" +"`test_segment_profile <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/profile_unit_test.py#L48>`_" msgstr "" msgid ":py:func:`set_uniform_coords <sigima.proc.image.set_uniform_coords>`" @@ -1804,7 +2267,9 @@ msgstr "" msgid "Convert image to uniform coordinate system" msgstr "" -msgid "`test_set_uniform_coords <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/geometry_unit_test.py#L503>`_" +msgid "" +"`test_set_uniform_coords <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/geometry_unit_test.py#L583>`_" msgstr "" msgid ":py:func:`sobel <sigima.proc.image.sobel>`" @@ -1813,7 +2278,9 @@ msgstr "" msgid "Compute Sobel filter" msgstr "" -msgid "`test_sobel <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/edges_unit_test.py#L82>`_" +msgid "" +"`test_sobel <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/edges_unit_test.py#L82>`_" msgstr "" msgid ":py:func:`sobel_h <sigima.proc.image.sobel_h>`" @@ -1822,7 +2289,9 @@ msgstr "" msgid "Compute horizontal Sobel filter" msgstr "" -msgid "`test_sobel_h <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/edges_unit_test.py#L88>`_" +msgid "" +"`test_sobel_h <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/edges_unit_test.py#L88>`_" msgstr "" msgid ":py:func:`sobel_v <sigima.proc.image.sobel_v>`" @@ -1831,7 +2300,9 @@ msgstr "" msgid "Compute vertical Sobel filter" msgstr "" -msgid "`test_sobel_v <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/edges_unit_test.py#L94>`_" +msgid "" +"`test_sobel_v <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/edges_unit_test.py#L94>`_" msgstr "" msgid ":py:func:`standard_deviation <sigima.proc.image.standard_deviation>`" @@ -1840,7 +2311,9 @@ msgstr "" msgid "Compute the element-wise standard deviation of multiple images" msgstr "" -msgid "`test_image_standard_deviation <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L88>`_" +msgid "" +"`test_image_standard_deviation <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/operation_unit_test.py#L88>`_" msgstr "" msgid ":py:func:`stats <sigima.proc.image.stats>`" @@ -1849,7 +2322,9 @@ msgstr "" msgid "Compute statistics on an image" msgstr "" -msgid "`test_image_stats_unit <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/common/stat_unit_test.py#L102>`_" +msgid "" +"`test_image_stats_unit <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/common/stat_unit_test.py#L102>`_" msgstr "" msgid ":py:func:`threshold <sigima.proc.image.threshold>`" @@ -1858,7 +2333,9 @@ msgstr "" msgid "Compute the threshold, using one of the available algorithms" msgstr "" -msgid "`test_threshold <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/threshold_unit_test.py#L21>`_" +msgid "" +"`test_threshold <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/threshold_unit_test.py#L21>`_" msgstr "" msgid ":py:func:`threshold_isodata <sigima.proc.image.threshold_isodata>`" @@ -1867,7 +2344,9 @@ msgstr "" msgid "Compute the threshold using the Isodata algorithm with default parameters" msgstr "" -msgid "`test_threshold_isodata <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/threshold_unit_test.py#L52>`_" +msgid "" +"`test_threshold_isodata <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/threshold_unit_test.py#L52>`_" msgstr "" msgid ":py:func:`threshold_li <sigima.proc.image.threshold_li>`" @@ -1876,7 +2355,9 @@ msgstr "" msgid "Compute the threshold using the Li algorithm with default parameters" msgstr "" -msgid "`test_threshold_li <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/threshold_unit_test.py#L58>`_" +msgid "" +"`test_threshold_li <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/threshold_unit_test.py#L58>`_" msgstr "" msgid ":py:func:`threshold_mean <sigima.proc.image.threshold_mean>`" @@ -1885,7 +2366,9 @@ msgstr "" msgid "Compute the threshold using the Mean algorithm" msgstr "" -msgid "`test_threshold_mean <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/threshold_unit_test.py#L64>`_" +msgid "" +"`test_threshold_mean <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/threshold_unit_test.py#L64>`_" msgstr "" msgid ":py:func:`threshold_minimum <sigima.proc.image.threshold_minimum>`" @@ -1894,7 +2377,9 @@ msgstr "" msgid "Compute the threshold using the Minimum algorithm with default parameters" msgstr "" -msgid "`test_threshold_minimum <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/threshold_unit_test.py#L70>`_" +msgid "" +"`test_threshold_minimum <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/threshold_unit_test.py#L70>`_" msgstr "" msgid ":py:func:`threshold_otsu <sigima.proc.image.threshold_otsu>`" @@ -1903,7 +2388,9 @@ msgstr "" msgid "Compute the threshold using the Otsu algorithm with default parameters" msgstr "" -msgid "`test_threshold_otsu <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/threshold_unit_test.py#L76>`_" +msgid "" +"`test_threshold_otsu <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/threshold_unit_test.py#L76>`_" msgstr "" msgid ":py:func:`threshold_triangle <sigima.proc.image.threshold_triangle>`" @@ -1912,7 +2399,9 @@ msgstr "" msgid "Compute the threshold using the Triangle algorithm with default parameters" msgstr "" -msgid "`test_threshold_triangle <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/threshold_unit_test.py#L82>`_" +msgid "" +"`test_threshold_triangle <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/threshold_unit_test.py#L82>`_" msgstr "" msgid ":py:func:`threshold_yen <sigima.proc.image.threshold_yen>`" @@ -1921,7 +2410,9 @@ msgstr "" msgid "Compute the threshold using the Yen algorithm with default parameters" msgstr "" -msgid "`test_threshold_yen <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/threshold_unit_test.py#L88>`_" +msgid "" +"`test_threshold_yen <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/threshold_unit_test.py#L88>`_" msgstr "" msgid ":py:func:`translate <sigima.proc.image.translate>`" @@ -1930,7 +2421,9 @@ msgstr "" msgid "Translate data" msgstr "" -msgid "`test_image_translate <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/geometry_unit_test.py#L25>`_" +msgid "" +"`test_image_translate <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/geometry_unit_test.py#L25>`_" msgstr "" msgid ":py:func:`transpose <sigima.proc.image.transpose>`" @@ -1939,16 +2432,22 @@ msgstr "" msgid "Transpose image" msgstr "" -msgid "`test_image_transpose <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/geometry_unit_test.py#L176>`_" +msgid "" +"`test_image_transpose <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/geometry_unit_test.py#L256>`_" msgstr "" msgid ":py:func:`vertical_projection <sigima.proc.image.vertical_projection>`" msgstr "" -msgid "Compute the sum of pixel intensities along each row (projection on the y-axis)" +msgid "" +"Compute the sum of pixel intensities along each row (projection on the " +"y-axis)" msgstr "" -msgid "`test_image_vertical_projection <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/projections_unit_test.py#L68>`_" +msgid "" +"`test_image_vertical_projection <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/projections_unit_test.py#L68>`_" msgstr "" msgid ":py:func:`white_tophat <sigima.proc.image.white_tophat>`" @@ -1957,13 +2456,17 @@ msgstr "" msgid "Compute White Top-Hat" msgstr "" -msgid "`test_white_tophat <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/morphology_unit_test.py#L37>`_" +msgid "" +"`test_white_tophat <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/morphology_unit_test.py#L37>`_" msgstr "" msgid ":py:func:`wiener <sigima.proc.image.wiener>`" msgstr "" -msgid "`test_image_wiener <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/filtering_unit_test.py#L61>`_" +msgid "" +"`test_image_wiener <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/filtering_unit_test.py#L61>`_" msgstr "" msgid ":py:func:`zero_padding <sigima.proc.image.zero_padding>`" @@ -1972,6 +2475,1074 @@ msgstr "" msgid "Zero-padding: add zeros to image borders" msgstr "" -msgid "`test_image_zero_padding <https://github.com/DataLab-Platform/Sigima/blob/v1.1.4/sigima/tests/image/fft2d_unit_test.py#L50>`_" -msgstr "" +msgid "" +"`test_image_zero_padding <https://github.com/DataLab-" +"Platform/Sigima/blob/v1.1.6/sigima/tests/image/fft2d_unit_test.py#L50>`_" +msgstr "" + +#~ msgid "" +#~ "`test_signal_absolute <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L229>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_add_gaussian_noise <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/noise_unit_test.py#L21>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_add_poisson_noise <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/noise_unit_test.py#L54>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_add_uniform_noise <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/noise_unit_test.py#L88>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_addition <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L78>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_addition_constant <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L171>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_allan_deviation <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/stability_unit_test.py#L153>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_allan_variance <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/stability_unit_test.py#L102>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_apply_window <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L564>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_arithmetic <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L398>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_astype <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L355>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_average <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L92>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_bandpass <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/filters_unit_test.py#L290>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_bandstop <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/filters_unit_test.py#L248>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_bandwidth_3db <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/analysis_unit_test.py#L33>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_calibration <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L38>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_cdf_fit <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fitting_unit_test.py#L457>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_clip <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L192>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_complex_from_magnitude_phase <https://github.com" +#~ "/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L320>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_complex_from_real_imag <https://github.com" +#~ "/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L253>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_contrast <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/analysis_unit_test.py#L88>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_convolution <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/convolution_unit_test.py#L106>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_deconvolution <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/convolution_unit_test.py#L267>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_derivative <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L205>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_detrending <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L248>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_difference <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L141>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_difference_constant <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L193>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_division <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L159>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_division_constant <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L203>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_dynamic_parameters <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/analysis_unit_test.py#L62>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_evaluate_fit <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fitting_unit_test.py#L846>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_exp <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L365>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_exponential_fit <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fitting_unit_test.py#L308>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_extract_pulse_features <https://github.com" +#~ "/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/pulse/pulse_unit_test.py#L1729>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_extract_roi <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/roi_advanced_unit_test.py#L198>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_extract_rois <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/roi_advanced_unit_test.py#L169>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_fft <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fft1d_unit_test.py#L138>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_full_width_at_y <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fwhm_unit_test.py#L143>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_fw1e2 <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fwhm_unit_test.py#L133>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_fwhm <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fwhm_unit_test.py#L61>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_gaussian_filter <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L271>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_gaussian_fit <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fitting_unit_test.py#L197>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_hadamard_variance <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/stability_unit_test.py#L301>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_highpass <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/filters_unit_test.py#L209>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_histogram <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L388>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_ifft <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fft1d_unit_test.py#L158>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_imag <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L245>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_integral <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L224>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_interpolate <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L486>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_inverse <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L214>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_linear_fit <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fitting_unit_test.py#L114>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_log10 <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L373>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_lorentzian_fit <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fitting_unit_test.py#L239>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_lowpass <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/filters_unit_test.py#L177>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_magnitude_spectrum <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fft1d_unit_test.py#L203>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_modified_allan_variance <https://github.com" +#~ "/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/stability_unit_test.py#L264>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_moving_average <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L282>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_moving_median <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L307>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_normalize <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L157>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_offset_correction <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/offset_correction_unit_test.py#L20>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_overlapping_allan_variance <https://github.com" +#~ "/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/stability_unit_test.py#L204>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_peak_detection <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/peakdetection_unit_test.py#L23>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_phase <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L273>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_phase_spectrum <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fft1d_unit_test.py#L244>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_piecewiseexponential_fit <https://github.com" +#~ "/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fitting_unit_test.py#L341>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_planckian_fit <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fitting_unit_test.py#L377>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_polynomial_fit <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fitting_unit_test.py#L148>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_power <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L389>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_product <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L127>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_product_constant <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L181>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_psd <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fft1d_unit_test.py#L270>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_quadratic_difference <https://github.com" +#~ "/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L151>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_real <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L237>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_replace_x_by_other_y <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/replace_x_by_other_y_unit_test.py#L28>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_resampling <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L332>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_reverse_x <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L78>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_sampling_rate_period <https://github.com" +#~ "/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/analysis_unit_test.py#L78>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_sigmoid_fit <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fitting_unit_test.py#L494>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_signals_to_image <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L424>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_sinusoidal_fit <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fitting_unit_test.py#L753>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_sqrt <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L381>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_standard_deviation <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/operation_unit_test.py#L107>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_stats_unit <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/common/stat_unit_test.py#L81>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_time_deviation <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/stability_unit_test.py#L376>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_to_cartesian <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L139>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_to_polar <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L123>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_total_variance <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/stability_unit_test.py#L344>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_transpose <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L68>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_twohalfgaussian_fit <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fitting_unit_test.py#L530>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_voigt_fit <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fitting_unit_test.py#L272>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_wiener <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L323>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_x_at_minmax <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/analysis_unit_test.py#L143>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_x_at_y <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/analysis_unit_test.py#L153>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_xy_mode <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/processing_unit_test.py#L360>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_y_at_x <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/analysis_unit_test.py#L166>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_signal_zero_padding <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/signal/fft1d_unit_test.py#L26>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_absolute <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L284>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_add_gaussian_noise <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/noise_unit_test.py#L21>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_add_poisson_noise <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/noise_unit_test.py#L59>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_add_uniform_noise <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/noise_unit_test.py#L97>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_addition <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L47>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_addition_constant <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L184>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_adjust_gamma <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/exposure_unit_test.py#L21>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_adjust_log <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/exposure_unit_test.py#L33>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_adjust_sigmoid <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/exposure_unit_test.py#L45>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_arithmetic <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L234>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_astype <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L438>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_average <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L67>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_average_profile <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/profile_unit_test.py#L70>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_binning <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/binning_unit_test.py#L71>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_black_tophat <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/morphology_unit_test.py#L43>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_blob_dog <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/blob_detection_unit_test.py#L110>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_blob_doh <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/blob_detection_unit_test.py#L187>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_blob_log <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/blob_detection_unit_test.py#L226>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_blob_opencv <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/blob_detection_unit_test.py#L266>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_butterworth <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/filtering_unit_test.py#L70>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_calibration <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/geometry_unit_test.py#L578>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_canny <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/edges_unit_test.py#L21>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_centroid <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/centroid_unit_test.py#L147>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_clip <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/exposure_unit_test.py#L158>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_closing <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/morphology_unit_test.py#L67>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_complex_from_magnitude_phase <https://github.com" +#~ "/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L399>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_complex_from_real_imag <https://github.com" +#~ "/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L317>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_contour_shape <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/contour_unit_test.py#L55>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_convolution <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/convolution_unit_test.py#L107>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_deconvolution <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/convolution_unit_test.py#L139>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_denoise_bilateral <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/restoration_unit_test.py#L41>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_denoise_tophat <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/restoration_unit_test.py#L81>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_denoise_tv <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/restoration_unit_test.py#L22>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_denoise_wavelet <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/restoration_unit_test.py#L58>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_difference <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L103>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_difference_constant <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L197>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_dilation <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/morphology_unit_test.py#L55>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_division <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L147>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_division_constant <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L222>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_enclosing_circle <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/enclosingcircle_unit_test.py#L55>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_equalize_adapthist <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/exposure_unit_test.py#L84>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_equalize_hist <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/exposure_unit_test.py#L72>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_erase <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/restoration_unit_test.py#L93>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_erosion <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/morphology_unit_test.py#L49>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_exp <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L459>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_extract_roi <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/roi_advanced_unit_test.py#L231>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_extract_rois <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/roi_advanced_unit_test.py#L201>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_farid <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/edges_unit_test.py#L118>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_farid_h <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/edges_unit_test.py#L124>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_farid_v <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/edges_unit_test.py#L130>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_fft <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/fft2d_unit_test.py#L118>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_flatfield <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/exposure_unit_test.py#L96>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_fliph <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/geometry_unit_test.py#L48>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_flipv <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/geometry_unit_test.py#L54>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_gaussian_filter <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/filtering_unit_test.py#L26>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_gaussian_freq_filter <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/filtering_unit_test.py#L116>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_histogram <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/exposure_unit_test.py#L171>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_horizontal_projection <https://github.com" +#~ "/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/projections_unit_test.py#L17>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_hough_circle_peaks <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/hough_circle_unit_test.py#L60>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_ifft <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/fft2d_unit_test.py#L134>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_imag <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L306>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_inverse <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L270>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_laplace <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/edges_unit_test.py#L136>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_line_profile <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/profile_unit_test.py#L19>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_log10 <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L471>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_log10_z_plus_n <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L483>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_magnitude_spectrum <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/fft2d_unit_test.py#L143>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_moving_average <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/filtering_unit_test.py#L37>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_moving_median <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/filtering_unit_test.py#L49>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_normalize <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/exposure_unit_test.py#L122>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_offset_correction <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/exposure_unit_test.py#L199>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_opening <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/morphology_unit_test.py#L61>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_peak_detection <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/peak2d_unit_test.py#L84>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_phase <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L334>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_phase_spectrum <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/fft2d_unit_test.py#L158>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_prewitt <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/edges_unit_test.py#L64>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_prewitt_h <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/edges_unit_test.py#L70>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_prewitt_v <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/edges_unit_test.py#L76>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_product <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L127>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_product_constant <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L210>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_psd <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/fft2d_unit_test.py#L170>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_quadratic_difference <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L115>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_radial_profile <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/profile_unit_test.py#L123>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_real <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L295>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_resampling <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/geometry_unit_test.py#L215>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_rescale_intensity <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/exposure_unit_test.py#L59>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_resize <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/geometry_unit_test.py#L399>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_roberts <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/edges_unit_test.py#L58>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_rotate <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/geometry_unit_test.py#L162>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_rotate270 <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/geometry_unit_test.py#L80>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_rotate90 <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/geometry_unit_test.py#L74>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_scharr <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/edges_unit_test.py#L100>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_scharr_h <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/edges_unit_test.py#L106>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_scharr_v <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/edges_unit_test.py#L112>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_segment_profile <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/profile_unit_test.py#L48>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_set_uniform_coords <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/geometry_unit_test.py#L503>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_sobel <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/edges_unit_test.py#L82>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_sobel_h <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/edges_unit_test.py#L88>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_sobel_v <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/edges_unit_test.py#L94>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_standard_deviation <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/operation_unit_test.py#L88>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_stats_unit <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/common/stat_unit_test.py#L102>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_threshold <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/threshold_unit_test.py#L21>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_threshold_isodata <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/threshold_unit_test.py#L52>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_threshold_li <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/threshold_unit_test.py#L58>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_threshold_mean <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/threshold_unit_test.py#L64>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_threshold_minimum <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/threshold_unit_test.py#L70>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_threshold_otsu <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/threshold_unit_test.py#L76>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_threshold_triangle <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/threshold_unit_test.py#L82>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_threshold_yen <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/threshold_unit_test.py#L88>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_translate <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/geometry_unit_test.py#L25>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_transpose <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/geometry_unit_test.py#L176>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_vertical_projection <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/projections_unit_test.py#L68>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_white_tophat <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/morphology_unit_test.py#L37>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_wiener <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/filtering_unit_test.py#L61>`_" +#~ msgstr "" + +#~ msgid "" +#~ "`test_image_zero_padding <https://github.com/DataLab-" +#~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/fft2d_unit_test.py#L50>`_" +#~ msgstr "" diff --git a/doc/locale/fr/LC_MESSAGES/intro/installation.po b/doc/locale/fr/LC_MESSAGES/intro/installation.po index 65787966b..8a4164678 100644 --- a/doc/locale/fr/LC_MESSAGES/intro/installation.po +++ b/doc/locale/fr/LC_MESSAGES/intro/installation.po @@ -6,15 +6,28 @@ #, fuzzy msgid "" msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2026-08-05 10:58+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.18.0\n" -msgid "How to install DataLab, the open-source data analysis and visualization platform" -msgstr "Comment installer DataLab, la plateforme d'analyse et de visualisation de données open-source" +msgid "" +"How to install DataLab, the open-source data analysis and visualization " +"platform" +msgstr "" +"Comment installer DataLab, la plateforme d'analyse et de visualisation de" +" données open-source" msgid "DataLab, installation, install, pip, wheel, source, Windows, Linux, macOS" -msgstr "DataLab, installation, installer, pip, wheel, source, Windows, Linux, macOS" +msgstr "" +"DataLab, installation, installer, pip, wheel, source, Windows, Linux, " +"macOS" msgid "Installation" msgstr "Installation" @@ -29,28 +42,58 @@ msgid "|download_link1|" msgstr "|download_link1|" msgid "**Important notice for users upgrading from DataLab v0.20 or earlier:**" -msgstr "**Note importante pour les utilisateurs effectuant une mise à niveau depuis DataLab v0.20 ou une version antérieure :**" +msgstr "" +"**Note importante pour les utilisateurs effectuant une mise à niveau " +"depuis DataLab v0.20 ou une version antérieure :**" -msgid "DataLab v1.0 introduces **breaking changes** that are **not backward compatible** with v0.20." -msgstr "DataLab v1.0 introduit des **changements majeurs** qui ne sont **pas rétrocompatibles** avec v0.20." +msgid "" +"DataLab v1.0 introduces **breaking changes** that are **not backward " +"compatible** with v0.20." +msgstr "" +"DataLab v1.0 introduit des **changements majeurs** qui ne sont **pas " +"rétrocompatibles** avec v0.20." msgid "**Plugins** developed for v0.20 **must be updated** to work with v1.0" -msgstr "**Les plugins** développés pour v0.20 **doivent être mis à jour** pour fonctionner avec v1.0." +msgstr "" +"**Les plugins** développés pour v0.20 **doivent être mis à jour** pour " +"fonctionner avec v1.0." msgid "**API changes** affect custom code integrations" -msgstr "**Les changements d'API** affectent les intégrations de code personnalisées." +msgstr "" +"**Les changements d'API** affectent les intégrations de code " +"personnalisées." -msgid "For detailed migration information, see the :ref:`migration guide <migration_v020_to_v100>`." -msgstr "Pour des informations détaillées sur la migration, voir le :ref:`guide de migration <migration_v020_to_v100>`." +msgid "" +"For detailed migration information, see the :ref:`migration guide " +"<migration_v020_to_v100>`." +msgstr "" +"Pour des informations détaillées sur la migration, voir le :ref:`guide de" +" migration <migration_v020_to_v100>`." -msgid "This section provides information on how to install DataLab on your system. Once installed, you can start DataLab by running the ``datalab`` command in a terminal, or by clicking on the DataLab shortcut in the Start menu (on Windows)." -msgstr "Cette section fournit des informations sur l'installation de DataLab sur votre système. Une fois installé, vous pouvez démarrer DataLab en exécutant la commande ``datalab`` dans un terminal, ou en cliquant sur le raccourci DataLab dans le menu Démarrer (sous Windows)." +msgid "" +"This section provides information on how to install DataLab on your " +"system. Once installed, you can start DataLab by running the ``datalab`` " +"command in a terminal, or by clicking on the DataLab shortcut in the " +"Start menu (on Windows)." +msgstr "" +"Cette section fournit des informations sur l'installation de DataLab sur " +"votre système. Une fois installé, vous pouvez démarrer DataLab en " +"exécutant la commande ``datalab`` dans un terminal, ou en cliquant sur le" +" raccourci DataLab dans le menu Démarrer (sous Windows)." -msgid "For more details on how to execute DataLab and its command-line options, see :ref:`ref-to-command-line-features`." -msgstr "Pour plus de détails sur l'exécution de DataLab et ses options en ligne de commande, voir :ref:`ref-to-command-line-features`." +msgid "" +"For more details on how to execute DataLab and its command-line options, " +"see :ref:`ref-to-command-line-features`." +msgstr "" +"Pour plus de détails sur l'exécution de DataLab et ses options en ligne " +"de commande, voir :ref:`ref-to-command-line-features`." -msgid "For installation on systems without internet access, see the :ref:`offline installation guide <installation_offline>`." -msgstr "Pour l'installation sur des systèmes sans accès à Internet, voir le :ref:`guide d'installation hors ligne <installation_offline>`." +msgid "" +"For installation on systems without internet access, see the " +":ref:`offline installation guide <installation_offline>`." +msgstr "" +"Pour l'installation sur des systèmes sans accès à Internet, voir le " +":ref:`guide d'installation hors ligne <installation_offline>`." msgid "How to install" msgstr "Modes d'installation" @@ -61,65 +104,150 @@ msgstr "DataLab est disponible sous plusieurs formes :" msgid "As a :ref:`install_conda`." msgstr "En tant que :ref:`install_conda`." -msgid ":bdg-info-line:`GNU/Linux` :bdg-info-line:`macOS` As a :ref:`install_nixos`, for users of the `NixOS <https://nixos.org/>`_ ecosystem." -msgstr ":bdg-info-line:`GNU/Linux` :bdg-info-line:`macOS` En tant que :ref:`install_nixos`, pour les utilisateurs de l'écosystème `NixOS <https://nixos.org/>`_." +msgid "" +":bdg-info-line:`GNU/Linux` :bdg-info-line:`macOS` As a " +":ref:`install_nixos`, for users of the `NixOS <https://nixos.org/>`_ " +"ecosystem." +msgstr "" +":bdg-info-line:`GNU/Linux` :bdg-info-line:`macOS` En tant que " +":ref:`install_nixos`, pour les utilisateurs de l'écosystème `NixOS " +"<https://nixos.org/>`_." msgid "As a Python package, which can be installed using the :ref:`install_pip`." msgstr "Un paquet Python qui peut être installé à l'aide du :ref:`install_pip`." -msgid ":bdg-info-line:`Windows` As a stand-alone application, which does not require any Python distribution to be installed. Just run the :ref:`install_aioinstaller` and you're good to go!" -msgstr ":bdg-info-line:`Windows` En tant qu'application autonome, qui ne nécessite pas d'installation de Python. Il suffit d'exécuter l':ref:`install_aioinstaller` et le tour est joué !" +msgid "" +":bdg-info-line:`Windows` As a stand-alone application, which does not " +"require any Python distribution to be installed. Just run the " +":ref:`install_aioinstaller` and you're good to go!" +msgstr "" +":bdg-info-line:`Windows` En tant qu'application autonome, qui ne " +"nécessite pas d'installation de Python. Il suffit d'exécuter " +"l':ref:`install_aioinstaller` et le tour est joué !" -msgid ":bdg-info-line:`Windows` Within a ready-to-use :ref:`install_winpython`, based on `WinPython <https://winpython.github.io/>`_." -msgstr ":bdg-info-line:`Windows` Dans une distribution prête à l'emploi :ref:`install_winpython`, basée sur `WinPython <https://winpython.github.io/>`_." +msgid "" +":bdg-info-line:`Windows` Within a ready-to-use :ref:`install_winpython`, " +"based on `WinPython <https://winpython.github.io/>`_." +msgstr "" +":bdg-info-line:`Windows` Dans une distribution prête à l'emploi " +":ref:`install_winpython`, basée sur `WinPython " +"<https://winpython.github.io/>`_." -msgid "As a precompiled :ref:`install_wheel`, which can be installed using ``pip``." -msgstr "En tant que :ref:`install_wheel` précompilé, qui peut être installé à l'aide de ``pip``." +msgid "" +"As a precompiled :ref:`install_wheel`, which can be installed using " +"``pip``." +msgstr "" +"En tant que :ref:`install_wheel` précompilé, qui peut être installé à " +"l'aide de ``pip``." -msgid "As a :ref:`install_source`, which can be installed using ``pip`` or manually." -msgstr "En tant que :ref:`install_source`, qui peut être installé à l'aide de ``pip`` ou manuellement." +msgid "" +"As a :ref:`install_source`, which can be installed using ``pip`` or " +"manually." +msgstr "" +"En tant que :ref:`install_source`, qui peut être installé à l'aide de " +"``pip`` ou manuellement." -msgid "Impatient to try the next version of DataLab? You can also install the latest development version of DataLab from the master branch of the Git repository. See :ref:`install_development` for more information." -msgstr "Impatient d'essayer la prochaine version de DataLab ? Vous pouvez également installer la dernière version de développement de DataLab à partir de la branche principale du dépôt Git. Voir :ref:`install_development` pour plus d'informations." +msgid "" +"Impatient to try the next version of DataLab? You can also install the " +"latest development version of DataLab from the master branch of the Git " +"repository. See :ref:`install_development` for more information." +msgstr "" +"Impatient d'essayer la prochaine version de DataLab ? Vous pouvez " +"également installer la dernière version de développement de DataLab à " +"partir de la branche principale du dépôt Git. Voir " +":ref:`install_development` pour plus d'informations." msgid "Conda package" msgstr "Paquet Conda" -msgid ":octicon:`info;1em;sd-text-info` :bdg-info-line:`GNU/Linux` :bdg-info-line:`Windows` :bdg-info-line:`macOS`" +msgid "" +":octicon:`info;1em;sd-text-info` :bdg-info-line:`GNU/Linux` :bdg-info-" +"line:`Windows` :bdg-info-line:`macOS`" msgstr "" -msgid "To install ``datalab`` package from the `conda-forge` channel (https://anaconda.org/conda-forge/datalab), run the following command:" -msgstr "Pour installer le paquet ``datalab`` depuis le canal ``conda-forge`` (https://anaconda.org/conda-forge/datalab), exécutez la commande suivante :" +msgid "" +"To install ``datalab`` package from the `conda-forge` channel " +"(https://anaconda.org/conda-forge/datalab), run the following command:" +msgstr "" +"Pour installer le paquet ``datalab`` depuis le canal ``conda-forge`` " +"(https://anaconda.org/conda-forge/datalab), exécutez la commande suivante" +" :" msgid "NixOS package" msgstr "Paquet NixOS" -msgid ":octicon:`info;1em;sd-text-info` :bdg-info-line:`GNU/Linux` :bdg-info-line:`macOS`" +msgid "" +":octicon:`info;1em;sd-text-info` :bdg-info-line:`GNU/Linux` :bdg-info-" +"line:`macOS`" msgstr "" -msgid "DataLab is packaged for `NixOS <https://nixos.org/>`_ and distributed through the `NGI Forge <https://ngi.nixos.org/app/datalab>`_, the software distribution system for projects funded by the `Next Generation Internet (NGI) <https://www.ngi.eu/>`_ initiative. This packaging was contributed by the `Nix@NGI team <https://nixos.org/community/teams/ngi/>`_, an NLnet partner, as part of DataLab's funding through the NGI0 Commons Fund." -msgstr "DataLab est packagé pour `NixOS <https://nixos.org/>`_ et distribué via la `NGI Forge <https://ngi.nixos.org/app/datalab>`_, le système de distribution logicielle des projets financés par l'initiative `Next Generation Internet (NGI) <https://www.ngi.eu/>`_. Ce packaging a été réalisé par l'`équipe Nix@NGI <https://nixos.org/community/teams/ngi/>`_, partenaire de NLnet, dans le cadre du financement de DataLab par le NGI0 Commons Fund." +msgid "" +"DataLab is packaged for `NixOS <https://nixos.org/>`_ and distributed " +"through the `NGI Forge <https://ngi.nixos.org/app/datalab>`_, the " +"software distribution system for projects funded by the `Next Generation " +"Internet (NGI) <https://www.ngi.eu/>`_ initiative. This packaging was " +"contributed by the `Nix@NGI team " +"<https://nixos.org/community/teams/ngi/>`_, an NLnet partner, as part of " +"DataLab's funding through the NGI0 Commons Fund." +msgstr "" +"DataLab est packagé pour `NixOS <https://nixos.org/>`_ et distribué via " +"la `NGI Forge <https://ngi.nixos.org/app/datalab>`_, le système de " +"distribution logicielle des projets financés par l'initiative `Next " +"Generation Internet (NGI) <https://www.ngi.eu/>`_. Ce packaging a été " +"réalisé par l'`équipe Nix@NGI <https://nixos.org/community/teams/ngi/>`_," +" partenaire de NLnet, dans le cadre du financement de DataLab par le NGI0" +" Commons Fund." -msgid "On any system with `Nix <https://nix.dev/>`_ installed, enter the Nix shell that provides DataLab (the ready-to-copy command is available on the `NGI Forge page <https://ngi.nixos.org/app/datalab>`_), then start the desktop application:" -msgstr "Sur tout système où `Nix <https://nix.dev/>`_ est installé, entrez dans le shell Nix qui fournit DataLab (la commande prête à copier est disponible sur la `page NGI Forge <https://ngi.nixos.org/app/datalab>`_), puis démarrez l'application de bureau :" +msgid "" +"On any system with `Nix <https://nix.dev/>`_ installed, enter the Nix " +"shell that provides DataLab (the ready-to-copy command is available on " +"the `NGI Forge page <https://ngi.nixos.org/app/datalab>`_), then start " +"the desktop application:" +msgstr "" +"Sur tout système où `Nix <https://nix.dev/>`_ est installé, entrez dans " +"le shell Nix qui fournit DataLab (la commande prête à copier est " +"disponible sur la `page NGI Forge <https://ngi.nixos.org/app/datalab>`_)," +" puis démarrez l'application de bureau :" msgid "Or, for an automated demonstration of some of DataLab's features:" -msgstr "Ou, pour une démonstration automatisée de certaines fonctionnalités de DataLab :" +msgstr "" +"Ou, pour une démonstration automatisée de certaines fonctionnalités de " +"DataLab :" msgid "Package manager ``pip``" msgstr "Gestionnaire de paquets ``pip``" -msgid "DataLab's package ``datalab-platform`` is available on the Python Package Index (PyPI) on the following URL: https://pypi.python.org/pypi/datalab-platform." -msgstr "Le paquet ``datalab-platform`` de DataLab est disponible sur le Python Package Index (PyPI) à l'adresse suivante : https://pypi.python.org/pypi/datalab-platform." +msgid "" +"DataLab's package ``datalab-platform`` is available on the Python Package" +" Index (PyPI) on the following URL: https://pypi.python.org/pypi/datalab-" +"platform." +msgstr "" +"Le paquet ``datalab-platform`` de DataLab est disponible sur le Python " +"Package Index (PyPI) à l'adresse suivante : https://pypi.python.org/pypi" +"/datalab-platform." -msgid "Installing DataLab from PyPI with Qt is as simple as running this command (you may need to use ``pip3`` instead of ``pip`` on some systems):" -msgstr "L'installation de DataLab depuis PyPI avec Qt est aussi simple que d'exécuter cette commande (vous devrez peut-être utiliser ``pip3`` au lieu de ``pip`` sur certains systèmes) :" +msgid "" +"Installing DataLab from PyPI with Qt is as simple as running this command" +" (you may need to use ``pip3`` instead of ``pip`` on some systems):" +msgstr "" +"L'installation de DataLab depuis PyPI avec Qt est aussi simple que " +"d'exécuter cette commande (vous devrez peut-être utiliser ``pip3`` au " +"lieu de ``pip`` sur certains systèmes) :" -msgid "Or, if you prefer, you can install DataLab without the Qt library (not recommended):" -msgstr "Ou, si vous préférez, vous pouvez installer DataLab sans la bibliothèque Qt (non recommandé) :" +msgid "" +"Or, if you prefer, you can install DataLab without the Qt library (not " +"recommended):" +msgstr "" +"Ou, si vous préférez, vous pouvez installer DataLab sans la bibliothèque " +"Qt (non recommandé) :" -msgid "If you already have a previous version of DataLab installed, you can upgrade it by running the same command with the ``--upgrade`` option:" -msgstr "Si vous avez déjà une version antérieure de DataLab installée, vous pouvez la mettre à jour en exécutant la même commande avec l'option ``--upgrade`` :" +msgid "" +"If you already have a previous version of DataLab installed, you can " +"upgrade it by running the same command with the ``--upgrade`` option:" +msgstr "" +"Si vous avez déjà une version antérieure de DataLab installée, vous " +"pouvez la mettre à jour en exécutant la même commande avec l'option " +"``--upgrade`` :" msgid "All-in-one installer" msgstr "Installeur tout-en-un" @@ -127,80 +255,199 @@ msgstr "Installeur tout-en-un" msgid ":octicon:`info;1em;sd-text-info` :bdg-info-line:`Windows`" msgstr "" -msgid "DataLab is available as a stand-alone application for Windows, which does not require any Python distribution to be installed. Just run the installer and you're good to go!" -msgstr "DataLab est disponible sous la forme d'une application autonome pour Windows qui ne nécessite pas d'installation de Python. Il suffit d'exécuter l'installeur et vous êtes prêt à partir !" +msgid "" +"DataLab is available as a stand-alone application for Windows, which does" +" not require any Python distribution to be installed. Just run the " +"installer and you're good to go!" +msgstr "" +"DataLab est disponible sous la forme d'une application autonome pour " +"Windows qui ne nécessite pas d'installation de Python. Il suffit " +"d'exécuter l'installeur et vous êtes prêt à partir !" msgid "DataLab all-in-one installer for Windows" msgstr "Installeur tout-en-un de DataLab pour Windows" -msgid "The installer package is available in the `Releases`_ section. It supports automatic uninstall and upgrade feature (no need to uninstall DataLab before runinng the installer of another version of the application)." -msgstr "Le paquet d'installation est disponible dans la section `Releases`_. Il prend en charge la désinstallation et la mise à jour automatiques (pas besoin de désinstaller DataLab avant d'exécuter l'installeur d'une autre version de l'application)." +msgid "" +"The installer package is available in the `Releases`_ section. It " +"supports automatic uninstall and upgrade feature (no need to uninstall " +"DataLab before runinng the installer of another version of the " +"application)." +msgstr "" +"Le paquet d'installation est disponible dans la section `Releases`_. Il " +"prend en charge la désinstallation et la mise à jour automatiques (pas " +"besoin de désinstaller DataLab avant d'exécuter l'installeur d'une autre " +"version de l'application)." msgid "DataLab Windows installer is available for Windows 7 SP1, 8, 10 and 11." -msgstr "L'installeur Windows de DataLab est disponible pour Windows 7 SP1, 8, 10 et 11." +msgstr "" +"L'installeur Windows de DataLab est disponible pour Windows 7 SP1, 8, 10 " +"et 11." -msgid ":octicon:`alert;1em;sd-text-warning` On Windows 7 SP1, before running DataLab (or any other Python 3 application), you must install Microsoft Update `KB2533623` (`Windows6.1-KB2533623-x64.msu`) and also may need to install `Microsoft Visual C++ 2015-2022 Redistribuable package <https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170>`_." -msgstr ":octicon:`alert;1em;sd-text-warning` Sur Windows 7 SP1, avant d'exécuter DataLab (ou toute autre application Python 3), vous devez installer la mise à jour Microsoft `KB2533623` (`Windows6.1-KB2533623-x64.msu`) et vous devrez peut-être également installer le `package redistribuable Microsoft Visual C++ 2015-2022 <https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170>`_." +msgid "" +":octicon:`alert;1em;sd-text-warning` On Windows 7 SP1, before running " +"DataLab (or any other Python 3 application), you must install Microsoft " +"Update `KB2533623` (`Windows6.1-KB2533623-x64.msu`) and also may need to " +"install `Microsoft Visual C++ 2015-2022 Redistribuable package " +"<https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-" +"redist?view=msvc-170>`_." +msgstr "" +":octicon:`alert;1em;sd-text-warning` Sur Windows 7 SP1, avant d'exécuter " +"DataLab (ou toute autre application Python 3), vous devez installer la " +"mise à jour Microsoft `KB2533623` (`Windows6.1-KB2533623-x64.msu`) et " +"vous devrez peut-être également installer le `package redistribuable " +"Microsoft Visual C++ 2015-2022 <https://learn.microsoft.com/en-" +"us/cpp/windows/latest-supported-vc-redist?view=msvc-170>`_." msgid "Python distribution" msgstr "Distribution Python" -msgid "DataLab is also available within a ready-to-use Python distribution, based on `WinPython <https://winpython.github.io/>`_. This distribution is called `DataLab-WinPython <https://github.com/DataLab-Platform/DataLab-WinPython?tab=readme-ov-file#datalab-winpython>`_ and is available in the `DataLab-WinPython Releases <https://github.com/DataLab-Platform/DataLab-WinPython/releases>`_ section." -msgstr "DataLab est également disponible dans une distribution Python prête à l'emploi, basée sur `WinPython <https://winpython.github.io/>`_. Cette distribution s'appelle `DataLab-WinPython <https://github.com/DataLab-Platform/DataLab-WinPython?tab=readme-ov-file#datalab-winpython>`_ et est disponible dans la section `DataLab-WinPython Releases <https://github.com/DataLab-Platform/DataLab-WinPython/releases>`_." +msgid "" +"DataLab is also available within a ready-to-use Python distribution, " +"based on `WinPython <https://winpython.github.io/>`_. This distribution " +"is called `DataLab-WinPython <https://github.com/DataLab-Platform" +"/DataLab-WinPython?tab=readme-ov-file#datalab-winpython>`_ and is " +"available in the `DataLab-WinPython Releases <https://github.com/DataLab-" +"Platform/DataLab-WinPython/releases>`_ section." +msgstr "" +"DataLab est également disponible dans une distribution Python prête à " +"l'emploi, basée sur `WinPython <https://winpython.github.io/>`_. Cette " +"distribution s'appelle `DataLab-WinPython <https://github.com/DataLab-" +"Platform/DataLab-WinPython?tab=readme-ov-file#datalab-winpython>`_ et est" +" disponible dans la section `DataLab-WinPython Releases " +"<https://github.com/DataLab-Platform/DataLab-WinPython/releases>`_." -msgid "DataLab-WinPython is a ready-to-use Python distribution including the DataLab platform." -msgstr "DataLab-WinPython est une distribution Python prête à l'emploi incluant la plateforme DataLab." +msgid "" +"DataLab-WinPython is a ready-to-use Python distribution including the " +"DataLab platform." +msgstr "" +"DataLab-WinPython est une distribution Python prête à l'emploi incluant " +"la plateforme DataLab." -msgid "The main difference with the all-in-one installer is that you can use the Python distribution for other purposes than running DataLab, and you may also extend it with additional packages. On the downside, it is also *much bigger* than the all-in-one installer because it includes a full Python distribution." -msgstr "La principale différence avec l'installeur tout-en-un est que vous pouvez utiliser la distribution Python à d'autres fins que l'exécution de DataLab, et vous pouvez également l'étendre avec des paquets supplémentaires. En revanche, elle est également *beaucoup plus volumineuse* que l'installeur tout-en-un car elle inclut une distribution Python complète." +msgid "" +"The main difference with the all-in-one installer is that you can use the" +" Python distribution for other purposes than running DataLab, and you may" +" also extend it with additional packages. On the downside, it is also " +"*much bigger* than the all-in-one installer because it includes a full " +"Python distribution." +msgstr "" +"La principale différence avec l'installeur tout-en-un est que vous pouvez" +" utiliser la distribution Python à d'autres fins que l'exécution de " +"DataLab, et vous pouvez également l'étendre avec des paquets " +"supplémentaires. En revanche, elle est également *beaucoup plus " +"volumineuse* que l'installeur tout-en-un car elle inclut une distribution" +" Python complète." -msgid "DataLab-WinPython includes `Spyder <https://www.spyder-ide.org/>`_, a powerful IDE for scientific programming in Python, as well as `Jupyter Notebook <https://jupyter.org/>`_ for interactive computing." -msgstr "DataLab-WinPython inclut `Spyder <https://www.spyder-ide.org/>`_, un IDE puissant pour la programmation scientifique en Python, ainsi que `Jupyter Notebook <https://jupyter.org/>`_ pour le calcul interactif." +msgid "" +"DataLab-WinPython includes `Spyder <https://www.spyder-ide.org/>`_, a " +"powerful IDE for scientific programming in Python, as well as `Jupyter " +"Notebook <https://jupyter.org/>`_ for interactive computing." +msgstr "" +"DataLab-WinPython inclut `Spyder <https://www.spyder-ide.org/>`_, un IDE " +"puissant pour la programmation scientifique en Python, ainsi que `Jupyter" +" Notebook <https://jupyter.org/>`_ pour le calcul interactif." msgid "DataLab-WinPython Control Panel" msgstr "Panneau de contrôle DataLab-WinPython" -msgid "Whereas the all-in-one installer provides a monolithic package that guarantees the compatibility of all its components because it cannot be modified by the user, the WinPython distribution is more flexible and thus can be broken by a bad manipulation of the Python distribution by the user. This should be taken into account when choosing the installation method." -msgstr "Alors que l'installeur tout-en-un fournit un paquet monolithique qui garantit la compatibilité de tous ses composants car il ne peut pas être modifié par l'utilisateur, la distribution WinPython est plus flexible et peut donc être endommagée par une mauvaise manipulation de la distribution Python par l'utilisateur. Cela doit être pris en compte lors du choix de la méthode d'installation." +msgid "" +"Whereas the all-in-one installer provides a monolithic package that " +"guarantees the compatibility of all its components because it cannot be " +"modified by the user, the WinPython distribution is more flexible and " +"thus can be broken by a bad manipulation of the Python distribution by " +"the user. This should be taken into account when choosing the " +"installation method." +msgstr "" +"Alors que l'installeur tout-en-un fournit un paquet monolithique qui " +"garantit la compatibilité de tous ses composants car il ne peut pas être " +"modifié par l'utilisateur, la distribution WinPython est plus flexible et" +" peut donc être endommagée par une mauvaise manipulation de la " +"distribution Python par l'utilisateur. Cela doit être pris en compte lors" +" du choix de la méthode d'installation." msgid "Wheel package" msgstr "Paquet Wheel" -msgid "On any operating system, using pip and the Wheel package is the easiest way to install DataLab on an existing Python distribution:" -msgstr "Sur n'importe quel système d'exploitation, l'utilisation de pip et du paquet Wheel est le moyen le plus simple d'installer DataLab sur une distribution Python existante :" +msgid "" +"On any operating system, using pip and the Wheel package is the easiest " +"way to install DataLab on an existing Python distribution:" +msgstr "" +"Sur n'importe quel système d'exploitation, l'utilisation de pip et du " +"paquet Wheel est le moyen le plus simple d'installer DataLab sur une " +"distribution Python existante :" msgid "Source package" msgstr "Paquet source" -msgid "Installing DataLab directly from the source package may be done using ``pip``:" -msgstr "L'installation de DataLab directement depuis le paquet source peut être effectuée à l'aide de ``pip`` :" +msgid "" +"Installing DataLab directly from the source package may be done using " +"``pip``:" +msgstr "" +"L'installation de DataLab directement depuis le paquet source peut être " +"effectuée à l'aide de ``pip`` :" -msgid "Or, if you prefer, you can install it manually by running the following command from the root directory of the source package:" -msgstr "Ou, si vous préférez, vous pouvez l'installer manuellement en exécutant la commande suivante depuis le répertoire racine du paquet source :" +msgid "" +"Or, if you prefer, you can install it manually by running the following " +"command from the root directory of the source package:" +msgstr "" +"Ou, si vous préférez, vous pouvez l'installer manuellement en exécutant " +"la commande suivante depuis le répertoire racine du paquet source :" -msgid "Finally, you can also build your own Wheel package and install it using ``pip``, by running the following command from the root directory of the source package (this requires the ``build`` and ``wheel`` packages to be installed):" -msgstr "Enfin, vous pouvez également créer votre propre paquet Wheel et l'installer à l'aide de ``pip``, en exécutant la commande suivante depuis le répertoire racine du paquet source (cela nécessite que les paquets ``build`` et ``wheel`` soient installés) :" +msgid "" +"Finally, you can also build your own Wheel package and install it using " +"``pip``, by running the following command from the root directory of the " +"source package (this requires the ``build`` and ``wheel`` packages to be " +"installed):" +msgstr "" +"Enfin, vous pouvez également créer votre propre paquet Wheel et " +"l'installer à l'aide de ``pip``, en exécutant la commande suivante depuis" +" le répertoire racine du paquet source (cela nécessite que les paquets " +"``build`` et ``wheel`` soient installés) :" msgid "Development version" msgstr "Version de développement" -msgid "If you want to try the latest development version of DataLab, you can install it directly from the master branch of the Git repository." -msgstr "Si vous souhaitez essayer la dernière version de développement de DataLab, vous pouvez l'installer directement depuis la branche principale du dépôt Git." +msgid "" +"If you want to try the latest development version of DataLab, you can " +"install it directly from the master branch of the Git repository." +msgstr "" +"Si vous souhaitez essayer la dernière version de développement de " +"DataLab, vous pouvez l'installer directement depuis la branche principale" +" du dépôt Git." -msgid "The first time you install DataLab from the Git repository, enter the following command:" -msgstr "La première fois que vous installez DataLab depuis le dépôt Git, entrez la commande suivante :" +msgid "" +"The first time you install DataLab from the Git repository, enter the " +"following command:" +msgstr "" +"La première fois que vous installez DataLab depuis le dépôt Git, entrez " +"la commande suivante :" -msgid "Then, if at some point you want to upgrade to the latest version of DataLab, just run the same command with options to force the reinstall of the package without handling dependencies (because it would reinstall all dependencies):" -msgstr "Ensuite, si vous souhaitez à un moment donné passer à la dernière version de DataLab, exécutez simplement la même commande avec les options pour forcer la réinstallation du paquet sans gérer les dépendances (car cela réinstallerait toutes les dépendances) :" +msgid "" +"Then, if at some point you want to upgrade to the latest version of " +"DataLab, just run the same command with options to force the reinstall of" +" the package without handling dependencies (because it would reinstall " +"all dependencies):" +msgstr "" +"Ensuite, si vous souhaitez à un moment donné passer à la dernière version" +" de DataLab, exécutez simplement la même commande avec les options pour " +"forcer la réinstallation du paquet sans gérer les dépendances (car cela " +"réinstallerait toutes les dépendances) :" -msgid "If dependencies have changed, you may need to execute the same command as above, but without the ``--no-deps`` option." -msgstr "Si les dépendances ont changé, vous devrez peut-être exécuter la même commande que ci-dessus, mais sans l'option ``--no-deps``." +msgid "" +"If dependencies have changed, you may need to execute the same command as" +" above, but without the ``--no-deps`` option." +msgstr "" +"Si les dépendances ont changé, vous devrez peut-être exécuter la même " +"commande que ci-dessus, mais sans l'option ``--no-deps``." msgid "Dependencies" msgstr "Dépendances" -msgid "The DataLab all-in-one installer already include all those required libraries as well as Python itself." -msgstr "L'installeur tout-en-un de DataLab inclut déjà toutes ces dépendances ainsi que Python lui-même." +msgid "" +"The DataLab all-in-one installer already include all those required " +"libraries as well as Python itself." +msgstr "" +"L'installeur tout-en-un de DataLab inclut déjà toutes ces dépendances " +"ainsi que Python lui-même." msgid "The `datalab-platform` package requires the following Python modules:" msgstr "Le paquet `datalab-platform` nécessite les modules Python suivants :" @@ -230,7 +477,9 @@ msgid ">= 3.14.4" msgstr "" msgid "Automatic GUI generation for easy dataset editing and display" -msgstr "Génération automatique d'interfaces graphiques pour l'édition et l'affichage de jeux de données" +msgstr "" +"Génération automatique d'interfaces graphiques pour l'édition et " +"l'affichage de jeux de données" msgid "PlotPy" msgstr "" @@ -244,10 +493,12 @@ msgstr "Outils de tracé de courbes et d'images pour les applications Python/Qt" msgid "Sigima" msgstr "" -msgid ">= 1.1.4" +msgid ">= 1.1.6" msgstr "" -msgid "Scientific computing engine for 1D signals and 2D images, part of the DataLab open-source platform." +msgid "" +"Scientific computing engine for 1D signals and 2D images, part of the " +"DataLab open-source platform." msgstr "" msgid "NumPy" @@ -319,7 +570,9 @@ msgstr "" msgid ">= 0.110.0" msgstr "" -msgid "FastAPI framework, high performance, easy to learn, fast to code, ready for production" +msgid "" +"FastAPI framework, high performance, easy to learn, fast to code, ready " +"for production" msgstr "" msgid "uvicorn[standard]" @@ -413,12 +666,16 @@ msgid "myst_parser" msgstr "" msgid "An extended [CommonMark](https://spec.commonmark.org/) compliant parser," -msgstr "Un parseur étendu compatible avec [CommonMark](https://spec.commonmark.org/)" +msgstr "" +"Un parseur étendu compatible avec " +"[CommonMark](https://spec.commonmark.org/)" msgid "sphinx_design" msgstr "" -msgid "A sphinx extension for designing beautiful, view size responsive web components." +msgid "" +"A sphinx extension for designing beautiful, view size responsive web " +"components." msgstr "Extension sphinx pour la conception de composants web réactifs." msgid "sphinx-copybutton" @@ -459,3 +716,7 @@ msgstr "" msgid "Python 3.11 and PyQt5 are the reference for production release" msgstr "Python 3.11 et PyQt5 sont les références pour la version de production" + +#~ msgid ">= 1.1.4" +#~ msgstr "" + diff --git a/doc/locale/fr/LC_MESSAGES/intro/tutorials/laser_beam.po b/doc/locale/fr/LC_MESSAGES/intro/tutorials/laser_beam.po index 1e59e49e0..8a91331b1 100644 --- a/doc/locale/fr/LC_MESSAGES/intro/tutorials/laser_beam.po +++ b/doc/locale/fr/LC_MESSAGES/intro/tutorials/laser_beam.po @@ -6,23 +6,44 @@ #, fuzzy msgid "" msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2026-08-05 14:07+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language: fr\n" +"Language-Team: fr <LL@li.org>\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.18.0\n" -msgid "Tutorial on how to measure the size of a laser beam using DataLab, the open-source scientific analysis and visualization platform" -msgstr "Tutoriel: mesurer la taille d'un faisceau laser avec DataLab, la plateforme d'analyse et de visualisation scientifique open-source" +msgid "" +"Tutorial on how to measure the size of a laser beam using DataLab, the " +"open-source scientific analysis and visualization platform" +msgstr "" +"Tutoriel: mesurer la taille d'un faisceau laser avec DataLab, la " +"plateforme d'analyse et de visualisation scientifique open-source" -msgid "DataLab, tutorial, laser beam, size, FWHM, Gaussian fit, radial profile, line profile, thresholding, centroid, image statistics, linear calibration, HDF5, workspace" -msgstr "DataLab, tutoriel, faisceau laser, taille, FWHM, ajustement gaussien, profil radial, profil de ligne, seuillage, centre de gravité, statistiques de l'image, étalonnage linéaire, HDF5, espace de travail" +msgid "" +"DataLab, tutorial, laser beam, size, FWHM, Gaussian fit, radial profile, " +"line profile, thresholding, centroid, image statistics, linear " +"calibration, HDF5, workspace" +msgstr "" +"DataLab, tutoriel, faisceau laser, taille, FWHM, ajustement gaussien, " +"profil radial, profil de ligne, seuillage, centre de gravité, " +"statistiques de l'image, étalonnage linéaire, HDF5, espace de travail" msgid ":octicon:`book;1em;sd-text-info` Measuring Laser Beam Size" msgstr ":octicon:`book;1em;sd-text-info` Mesurer la taille d'un faisceau laser" -msgid "This example shows how to measure the size of a laser beam along the propagation axis using DataLab:" -msgstr "Cet exemple montre comment mesurer la taille d'un faisceau laser le long de l'axe de propagation en utilisant DataLab :" +msgid "" +"This example shows how to measure the size of a laser beam along the " +"propagation axis using DataLab:" +msgstr "" +"Cet exemple montre comment mesurer la taille d'un faisceau laser le long " +"de l'axe de propagation en utilisant DataLab :" msgid "Load all the images in a folder" msgstr "Ouvrir toutes les images d'un dossier" @@ -45,26 +66,60 @@ msgstr "Essayer une autre méthode : extraire le profil d'intensité radial" msgid "Compute the FWHM of the radial intensity profile" msgstr "Calculer la FWHM du profil d'intensité radial" -msgid "Perform the same analysis on a stack of images and on the resulting profiles" -msgstr "Effectuer la même analyse sur une pile d'images et sur les profils résultants" +msgid "" +"Perform the same analysis on a stack of images and on the resulting " +"profiles" +msgstr "" +"Effectuer la même analyse sur une pile d'images et sur les profils " +"résultants" -msgid "Plot the beam size as a function of the position along the propagation axis" -msgstr "Tracer la taille du faisceau en fonction de la position le long de l'axe de propagation" +msgid "" +"Plot the beam size as a function of the position along the propagation " +"axis" +msgstr "" +"Tracer la taille du faisceau en fonction de la position le long de l'axe " +"de propagation" msgid "Load the images" msgstr "Charger les images" -msgid "The images used in this tutorial \"TEM00_z_*.jpg\" are available in the tutorial data folder of DataLab's installation directory (``<DataLab installation directory>/data/tutorials/``)." -msgstr "Les images utilisées dans ce tutoriel \"TEM00_z_*.jpg\" sont disponibles dans le dossier de données du tutoriel du répertoire d'installation de DataLab (``<Répertoire d'installation de DataLab>/data/tutorials/``)." +msgid "" +"The images used in this tutorial \"TEM00_z_*.jpg\" are available in the " +"tutorial data folder of DataLab's installation directory (``<DataLab " +"installation directory>/data/tutorials/``)." +msgstr "" +"Les images utilisées dans ce tutoriel \"TEM00_z_*.jpg\" sont disponibles " +"dans le dossier de données du tutoriel du répertoire d'installation de " +"DataLab (``<Répertoire d'installation de DataLab>/data/tutorials/``)." -msgid "Alternatively, you can download them from :download:`here </_download/laser_beam.zip>` and extract to the folder of your choice." -msgstr "Alternativement, vous pouvez les télécharger depuis :download:`ici </_download/laser_beam.zip>` et les extraire dans le dossier de votre choix." +msgid "" +"Alternatively, you can download them from :download:`here " +"</_download/laser_beam.zip>` and extract to the folder of your choice." +msgstr "" +"Alternativement, vous pouvez les télécharger depuis :download:`ici " +"</_download/laser_beam.zip>` et les extraire dans le dossier de votre " +"choix." -msgid "Alternatively, they can be downloaded from the online documentation at https://datalab-platform.com." -msgstr "Alternativement, elles peuvent être téléchargées depuis la documentation en ligne à l'adresse https://datalab-platform.com." +msgid "" +"Alternatively, they can be downloaded from the online documentation at " +"https://datalab-platform.com." +msgstr "" +"Alternativement, elles peuvent être téléchargées depuis la documentation " +"en ligne à l'adresse https://datalab-platform.com." -msgid "First, we open DataLab and load the images. When working with multiple images, the most efficient approach is to use the \"Open from directory...\" option from the \"File\" menu (or click the |fileopen_dir| button in the toolbar). This feature loads all images from a selected directory at once." -msgstr "Tout d'abord, nous ouvrons DataLab et chargeons les images. Lorsque vous travaillez avec plusieurs images, l'approche la plus efficace consiste à utiliser l'option \"Ouvrir depuis un répertoire...\" du menu \"Fichier\" (ou cliquer sur le bouton |fileopen_dir| dans la barre d'outils). Cette fonction charge toutes les images d'un répertoire sélectionné en une seule fois." +msgid "" +"First, we open DataLab and load the images. When working with multiple " +"images, the most efficient approach is to use the \"Open from " +"directory...\" option from the \"File\" menu (or click the |fileopen_dir|" +" button in the toolbar). This feature loads all images from a selected " +"directory at once." +msgstr "" +"Tout d'abord, nous ouvrons DataLab et chargeons les images. Lorsque vous " +"travaillez avec plusieurs images, l'approche la plus efficace consiste à " +"utiliser l'option \"Ouvrir depuis un répertoire...\" du menu \"Fichier\" " +"(ou cliquer sur le bouton |fileopen_dir| dans la barre d'outils). Cette " +"fonction charge toutes les images d'un répertoire sélectionné en une " +"seule fois." msgid "fileopen_dir" msgstr "fileopen_dir" @@ -75,20 +130,46 @@ msgstr "Le menu \"Fichier > Ouvrir une image...\"" msgid "Select the folder containing the images and click \"Choose\"." msgstr "Sélectionnez le dossier contenant les images et cliquez sur \"Choisir\"." -msgid "The images are now loaded in the \"Image panel\". You can zoom in and out by right-clicking and dragging the mouse vertically. To pan the image, use the middle mouse button while dragging." -msgstr "Les images sont maintenant chargées dans le panneau \"Images\". Vous pouvez zoomer en cliquant avec le bouton droit et en faisant glisser la souris verticalement. Pour déplacer l'image, utilisez le bouton du milieu de la souris tout en faisant glisser." +msgid "" +"The images are now loaded in the \"Image panel\". You can zoom in and out" +" by right-clicking and dragging the mouse vertically. To pan the image, " +"use the middle mouse button while dragging." +msgstr "" +"Les images sont maintenant chargées dans le panneau \"Images\". Vous " +"pouvez zoomer en cliquant avec le bouton droit et en faisant glisser la " +"souris verticalement. Pour déplacer l'image, utilisez le bouton du milieu" +" de la souris tout en faisant glisser." -msgid "Zoom in and out with the right mouse button. Pan the image with the middle mouse button." -msgstr "Zoomer avec le bouton droit de la souris. Déplacer l'image avec le bouton du milieu de la souris." +msgid "" +"Zoom in and out with the right mouse button. Pan the image with the " +"middle mouse button." +msgstr "" +"Zoomer avec le bouton droit de la souris. Déplacer l'image avec le bouton" +" du milieu de la souris." -msgid "To view multiple images simultaneously, select the image group and choose \"View images side-by-side\" from the \"View\" menu." -msgstr "Pour voir plusieurs images simultanément, sélectionnez le groupe d'images et choisissez \"Afficher les images côte à côte\" dans le menu \"Affichage\"." +msgid "" +"To view multiple images simultaneously, select the image group and choose" +" \"View images side-by-side\" from the \"View\" menu." +msgstr "" +"Pour voir plusieurs images simultanément, sélectionnez le groupe d'images" +" et choisissez \"Afficher les images côte à côte\" dans le menu " +"\"Affichage\"." msgid "Viewing images side by side." msgstr "Affichage des images côte à côte." -msgid "The \"Processing > Geometry\" menu includes a \"Distribute on a grid\" option |distribute_on_grid|. This feature repositions the images by applying offsets to their X and Y coordinates, arranging them in a grid layout for side-by-side viewing. Note that this operation modifies the image coordinates." -msgstr "Le menu \"Traitement > Géométrie\" inclut une option \"Distribuer sur une grille\" |distribute_on_grid|. Cette fonction repositionne les images en appliquant des décalages à leurs coordonnées X et Y, les organisant dans une disposition en grille pour une visualisation côte à côte. Notez que cette opération modifie les coordonnées de l'image." +msgid "" +"The \"Processing > Geometry\" menu includes a \"Distribute on a grid\" " +"option |distribute_on_grid|. This feature repositions the images by " +"applying offsets to their X and Y coordinates, arranging them in a grid " +"layout for side-by-side viewing. Note that this operation modifies the " +"image coordinates." +msgstr "" +"Le menu \"Traitement > Géométrie\" inclut une option \"Distribuer sur une" +" grille\" |distribute_on_grid|. Cette fonction repositionne les images en" +" appliquant des décalages à leurs coordonnées X et Y, les organisant dans" +" une disposition en grille pour une visualisation côte à côte. Notez que " +"cette opération modifie les coordonnées de l'image." msgid "distribute_on_grid" msgstr "distribute_on_grid" @@ -96,92 +177,258 @@ msgstr "distribute_on_grid" msgid "Images distributed on 4 columns grid." msgstr "Images distribuées sur une grille de 4 colonnes." -msgid "To restore the original image positions, use the \"Reset image positions\" option |reset_positions| from the \"Processing > Geometry\" menu. Note that this operation sets all image origins to match the first image's origin, which means any initial differences in image origins will be lost." -msgstr "Pour restaurer les positions d'image d'origine, utilisez l'option \"Réinitialiser les positions des images\" |reset_positions| du menu \"Traitement > Géométrie\". Notez que cette opération définit toutes les origines d'image pour qu'elles correspondent à l'origine de la première image, ce qui signifie que toutes les différences initiales dans les origines d'image seront perdues." +msgid "" +"To restore the original image positions, use the \"Reset image " +"positions\" option |reset_positions| from the \"Processing > Geometry\" " +"menu. Note that this operation sets all image origins to match the first " +"image's origin, which means any initial differences in image origins will" +" be lost." +msgstr "" +"Pour restaurer les positions d'image d'origine, utilisez l'option " +"\"Réinitialiser les positions des images\" |reset_positions| du menu " +"\"Traitement > Géométrie\". Notez que cette opération définit toutes les " +"origines d'image pour qu'elles correspondent à l'origine de la première " +"image, ce qui signifie que toutes les différences initiales dans les " +"origines d'image seront perdues." msgid "reset_positions" msgstr "reset_positions" +msgid "" +"Both the \"Distribute on a grid\" and \"Reset image positions\" options " +"modify the images in place, without creating new images. For this reason," +" they are not registered in the History Panel, which only lists newly " +"created objects." +msgstr "" + msgid "Remove background noise" msgstr "Supprimer le bruit de fond" -msgid "When we select one of the images, we notice the presence of background noise, making it beneficial to apply a threshold to the images. Several methods are available to estimate the background noise level." -msgstr "Lorsque nous sélectionnons l'une des images, nous remarquons la présence de bruit de fond, ce qui rend utile l'application d'un seuillage aux images. Plusieurs méthodes sont disponibles pour estimer le niveau de bruit de fond." +msgid "" +"When we select one of the images, we notice the presence of background " +"noise, making it beneficial to apply a threshold to the images. Several " +"methods are available to estimate the background noise level." +msgstr "" +"Lorsque nous sélectionnons l'une des images, nous remarquons la présence " +"de bruit de fond, ce qui rend utile l'application d'un seuillage aux " +"images. Plusieurs méthodes sont disponibles pour estimer le niveau de " +"bruit de fond." -msgid "One approach utilizes the \"Cross section\" tool, which is provided by the `PlotPy <https://github.com/PlotPyStack/plotpy>` library that DataLab uses for signal and image visualization. Select an image from the \"Image panel\", choose the corresponding image in the visualization panel, and activate the \"Cross section\" tool |cross_section| from the vertical toolbar on the left side of the visualization panel. This reveals that the background noise level is approximately 30 lsb." -msgstr "Une approche utilise l'outil \"Profil rectiligne\", qui est fourni par la bibliothèque `PlotPy <https://github.com/PlotPyStack/plotpy>` que DataLab utilise pour la visualisation de signaux et d'images. Sélectionnez une image dans le panneau \"Images\", choisissez l'image correspondante dans le panneau de visualisation, et activez l'outil \"Profil rectiligne\" |cross_section| depuis la barre d'outils verticale sur le côté gauche du panneau de visualisation. Cela révèle que le niveau de bruit de fond est d'environ 30 lsb." +#, fuzzy +msgid "" +"One approach utilizes the \"Cross section\" tool, which is provided by " +"the `PlotPy <https://github.com/PlotPyStack/plotpy>`__ library that " +"DataLab uses for signal and image visualization. Select an image from the" +" \"Image panel\", choose the corresponding image in the visualization " +"panel, and activate the \"Cross section\" tool |cross_section| from the " +"vertical toolbar on the left side of the visualization panel. This " +"reveals that the background noise level is approximately 30 lsb." +msgstr "" +"Une approche utilise l'outil \"Profil rectiligne\", qui est fourni par la" +" bibliothèque `PlotPy <https://github.com/PlotPyStack/plotpy>` que " +"DataLab utilise pour la visualisation de signaux et d'images. " +"Sélectionnez une image dans le panneau \"Images\", choisissez l'image " +"correspondante dans le panneau de visualisation, et activez l'outil " +"\"Profil rectiligne\" |cross_section| depuis la barre d'outils verticale " +"sur le côté gauche du panneau de visualisation. Cela révèle que le niveau" +" de bruit de fond est d'environ 30 lsb." msgid "cross_section" msgstr "cross_section" -msgid "An image from the \"Image panel\". To display the curve marker, select the profile curve and right-click to open the context menu, then choose \"Markers > Bound to active item\"." -msgstr "Une image du panneau \"Images\". Pour afficher le marqueur de courbe, sélectionnez la courbe de profil et cliquez avec le bouton droit pour ouvrir le menu contextuel, puis choisissez \"Marqueurs > Lié à l'élément actif\"." +msgid "" +"An image from the \"Image panel\". To display the curve marker, select " +"the profile curve and right-click to open the context menu, then choose " +"\"Markers > Bound to active item\"." +msgstr "" +"Une image du panneau \"Images\". Pour afficher le marqueur de courbe, " +"sélectionnez la courbe de profil et cliquez avec le bouton droit pour " +"ouvrir le menu contextuel, puis choisissez \"Marqueurs > Lié à l'élément " +"actif\"." -msgid "Another method for measuring background noise, also provided by `PlotPy <https://github.com/PlotPyStack/plotpy>`, involves using the \"Image statistics\" tool |imagestats| from the vertical toolbar on the left side of the visualization panel. This tool displays statistical information for a rectangular region that you define by dragging the mouse across the image. This analysis confirms that the background noise level is approximately 30 lsb." -msgstr "Une autre méthode pour mesurer le bruit de fond, également fournie par `PlotPy <https://github.com/PlotPyStack/plotpy>`, consiste à utiliser l'outil \"Statistiques de l'image\" |imagestats| de la barre d'outils verticale sur le côté gauche du panneau de visualisation. Cet outil affiche des informations statistiques pour une région rectangulaire que vous définissez en faisant glisser la souris sur l'image. Cette analyse confirme que le niveau de bruit de fond est d'environ 30 lsb." +#, fuzzy +msgid "" +"Another method for measuring background noise, also provided by `PlotPy " +"<https://github.com/PlotPyStack/plotpy>`__, involves using the \"Image " +"statistics\" tool |imagestats| from the vertical toolbar on the left side" +" of the visualization panel. This tool displays statistical information " +"for a rectangular region that you define by dragging the mouse across the" +" image. This analysis confirms that the background noise level is " +"approximately 30 lsb." +msgstr "" +"Une autre méthode pour mesurer le bruit de fond, également fournie par " +"`PlotPy <https://github.com/PlotPyStack/plotpy>`, consiste à utiliser " +"l'outil \"Statistiques de l'image\" |imagestats| de la barre d'outils " +"verticale sur le côté gauche du panneau de visualisation. Cet outil " +"affiche des informations statistiques pour une région rectangulaire que " +"vous définissez en faisant glisser la souris sur l'image. Cette analyse " +"confirme que le niveau de bruit de fond est d'environ 30 lsb." msgid "imagestats" msgstr "imagestats" msgid "The \"Image statistics\" tool |imagestats| in the vertical toolbar." -msgstr "L'outil \"Statistiques de l'image\" |imagestats| dans la barre d'outils verticale." +msgstr "" +"L'outil \"Statistiques de l'image\" |imagestats| dans la barre d'outils " +"verticale." -msgid "Note that these tools are not persistent: the analysis results disappear when you select another image, they are intended to provide a fast insight on the image data." -msgstr "Notez que ces outils ne sont pas persistants : les résultats d'analyse disparaissent lorsque vous sélectionnez une autre image, ils sont destinés à fournir un aperçu rapide des données d'image." +msgid "" +"Note that these tools are not persistent: the analysis results disappear " +"when you select another image, they are intended to provide a fast " +"insight on the image data." +msgstr "" +"Notez que ces outils ne sont pas persistants : les résultats d'analyse " +"disparaissent lorsque vous sélectionnez une autre image, ils sont " +"destinés à fournir un aperçu rapide des données d'image." -msgid "Now we can clip the image at 35 lsb to remove the background noise using the \"Processing > Level Adjustment > Clipping...\" menu." -msgstr "Nous pouvons maintenant écrêter l'image à 35 lsb pour supprimer le bruit de fond en utilisant le menu \"Traitement > Ajustement de niveau > Écrêtage...\"." +msgid "" +"Now we can clip the image at 35 lsb to remove the background noise using " +"the \"Processing > Level Adjustment > Clipping...\" menu." +msgstr "" +"Nous pouvons maintenant écrêter l'image à 35 lsb pour supprimer le bruit " +"de fond en utilisant le menu \"Traitement > Ajustement de niveau > " +"Écrêtage...\"." -msgid "The two original and the clipped images are displayed side by side in the \"Image view\" (using the \"Distribute on a grid\" feature seen previously)." -msgstr "Les deux images d'origine et l'image écrêtée sont affichées côte à côte dans la \"Vue Image\" (en utilisant la fonction \"Distribuer sur une grille\" vue précédemment)." +msgid "" +"The two original and the clipped images are displayed side by side in the" +" \"Image view\" (using the \"Distribute on a grid\" feature seen " +"previously)." +msgstr "" +"Les deux images d'origine et l'image écrêtée sont affichées côte à côte " +"dans la \"Vue Image\" (en utilisant la fonction \"Distribuer sur une " +"grille\" vue précédemment)." msgid "Beam size measurement" msgstr "Mesure de la taille du faisceau" -msgid "We can now compute the centroid of the beam—that is, the position of its center of mass. To do this, select \"Analysis > Centroid\" from the menu." -msgstr "Nous pouvons maintenant calculer le centroïde du faisceau—c'est-à-dire la position de son centre de masse. Pour ce faire, sélectionnez \"Analyse > Centroïde\" dans le menu." +msgid "" +"We can now compute the centroid of the beam—that is, the position of its " +"center of mass. To do this, select \"Analysis > Centroid\" from the menu." +msgstr "" +"Nous pouvons maintenant calculer le centroïde du faisceau—c'est-à-dire la" +" position de son centre de masse. Pour ce faire, sélectionnez \"Analyse >" +" Centroïde\" dans le menu." msgid "The centroid position is displayed on the image." msgstr "La position du centroïde est affichée sur l'image." -msgid "Next, we can extract a line profile along the horizontal axis using \"Analysis > Intensity profiles > Line profile\". Set the row position to the previously computed centroid position (i.e., 668) using the \"Set Parameters\" button. See :ref:`tutorial_fabry_perot` for more details on intensity profile extraction." -msgstr "Ensuite, nous pouvons extraire un profil de ligne le long de l'axe horizontal en utilisant \"Opérations > Profils d'intensité > Profil rectiligne\". Définissez la position de la ligne sur la position du centroïde calculée précédemment (c'est-à-dire 668) en utilisant le bouton \"Définir les paramètres\". Voir :ref:`tutorial_fabry_perot` pour plus de détails sur l'extraction de profil d'intensité." +msgid "" +"Next, we can extract a line profile along the horizontal axis using " +"\"Analysis > Intensity profiles > Line profile\". Set the row position to" +" the previously computed centroid position (i.e., 668) using the \"Set " +"Parameters\" button. See :ref:`tutorial_fabry_perot` for more details on " +"intensity profile extraction." +msgstr "" +"Ensuite, nous pouvons extraire un profil de ligne le long de l'axe " +"horizontal en utilisant \"Opérations > Profils d'intensité > Profil " +"rectiligne\". Définissez la position de la ligne sur la position du " +"centroïde calculée précédemment (c'est-à-dire 668) en utilisant le bouton" +" \"Définir les paramètres\". Voir :ref:`tutorial_fabry_perot` pour plus " +"de détails sur l'extraction de profil d'intensité." -msgid "The intensity profile will be displayed in the \"Signal panel\". We can then fit the profile to a Gaussian function using \"Processing > Fitting > Gaussian fit\". Here we have selected both signals for comparison." -msgstr "Le profil d'intensité sera affiché dans le panneau \"Signaux\". Nous pouvons ensuite ajuster le profil à une fonction gaussienne en utilisant \"Traitement > Ajustement > Ajustement gaussien\". Ici, nous avons sélectionné les deux signaux pour comparaison." +msgid "" +"The intensity profile will be displayed in the \"Signal panel\". We can " +"then fit the profile to a Gaussian function using \"Processing > Fitting " +"> Gaussian fit\". Here we have selected both signals for comparison." +msgstr "" +"Le profil d'intensité sera affiché dans le panneau \"Signaux\". Nous " +"pouvons ensuite ajuster le profil à une fonction gaussienne en utilisant " +"\"Traitement > Ajustement > Ajustement gaussien\". Ici, nous avons " +"sélectionné les deux signaux pour comparaison." -msgid "The intensity profile fitted to a Gaussian function. Here both signals are selected." -msgstr "Le profil d'intensité ajusté à une fonction gaussienne. Ici, les deux signaux sont sélectionnés." +msgid "" +"The intensity profile fitted to a Gaussian function. Here both signals " +"are selected." +msgstr "" +"Le profil d'intensité ajusté à une fonction gaussienne. Ici, les deux " +"signaux sont sélectionnés." -msgid "Now let's explore another method to compute the FWHM. Returning to the intensity profile signal, we can directly compute the FWHM using \"Analysis > Full width at half maximum\". You can choose the estimation method based on your curve characteristics and optionally specify the interval to consider for this computation. Once complete, the results window will display the FWHM value, which is stored in the metadata and shown on the curve." -msgstr "Explorons maintenant une autre méthode pour calculer la FWHM. En revenant au signal de profil d'intensité, nous pouvons calculer directement la FWHM en utilisant \"Analyse > Largeur à mi-hauteur\". Vous pouvez choisir la méthode d'estimation en fonction des caractéristiques de votre courbe et spécifier éventuellement l'intervalle à considérer pour ce calcul. Une fois terminé, la fenêtre de résultats affichera la valeur FWHM, qui est stockée dans les métadonnées et affichée sur la courbe." +msgid "" +"Now let's explore another method to compute the FWHM. Returning to the " +"intensity profile signal, we can directly compute the FWHM using " +"\"Analysis > Full width at half maximum\". You can choose the estimation " +"method based on your curve characteristics and optionally specify the " +"interval to consider for this computation. Once complete, the results " +"window will display the FWHM value, which is stored in the metadata and " +"shown on the curve." +msgstr "" +"Explorons maintenant une autre méthode pour calculer la FWHM. En revenant" +" au signal de profil d'intensité, nous pouvons calculer directement la " +"FWHM en utilisant \"Analyse > Largeur à mi-hauteur\". Vous pouvez choisir" +" la méthode d'estimation en fonction des caractéristiques de votre courbe" +" et spécifier éventuellement l'intervalle à considérer pour ce calcul. " +"Une fois terminé, la fenêtre de résultats affichera la valeur FWHM, qui " +"est stockée dans les métadonnées et affichée sur la courbe." msgid "The popup that allows to choose the method to estimate the FWHM." -msgstr "La fenêtre contextuelle qui permet de choisir la méthode pour estimer la FWHM." +msgstr "" +"La fenêtre contextuelle qui permet de choisir la méthode pour estimer la " +"FWHM." msgid "The FWHM result shown in the popup and over the curve." -msgstr "Le résultat de la FWHM affiché dans la fenêtre contextuelle et sur la courbe." +msgstr "" +"Le résultat de la FWHM affiché dans la fenêtre contextuelle et sur la " +"courbe." -msgid "Let's also try another method to measure the beam size by returning to the image." -msgstr "Essayons également une autre méthode pour mesurer la taille du faisceau en revenant à l'image." +msgid "" +"Let's also try another method to measure the beam size by returning to " +"the image." +msgstr "" +"Essayons également une autre méthode pour mesurer la taille du faisceau " +"en revenant à l'image." -msgid "From the \"Image panel\", we can extract the radial intensity profile using \"Analysis > Intensity profiles > Radial profile\". The radial intensity profile can be computed around the centroid position, the center of the image, or a user-defined position, depending on your data. For our data, which appears to have radial symmetry with a center not necessarily identical to the image center, the best option is the centroid position." -msgstr "Depuis le panneau \"Images\", nous pouvons extraire le profil d'intensité radial en utilisant \"Opérations > Profils d'intensité > Profil radial\". Le profil d'intensité radial peut être calculé autour de la position du centroïde, du centre de l'image ou d'une position définie par l'utilisateur, selon vos données. Pour nos données, qui semblent avoir une symétrie radiale avec un centre pas nécessairement identique au centre de l'image, la meilleure option est la position du centroïde." +msgid "" +"From the \"Image panel\", we can extract the radial intensity profile " +"using \"Analysis > Intensity profiles > Radial profile\". The radial " +"intensity profile can be computed around the centroid position, the " +"center of the image, or a user-defined position, depending on your data. " +"For our data, which appears to have radial symmetry with a center not " +"necessarily identical to the image center, the best option is the " +"centroid position." +msgstr "" +"Depuis le panneau \"Images\", nous pouvons extraire le profil d'intensité" +" radial en utilisant \"Opérations > Profils d'intensité > Profil " +"radial\". Le profil d'intensité radial peut être calculé autour de la " +"position du centroïde, du centre de l'image ou d'une position définie par" +" l'utilisateur, selon vos données. Pour nos données, qui semblent avoir " +"une symétrie radiale avec un centre pas nécessairement identique au " +"centre de l'image, la meilleure option est la position du centroïde." msgid "The options available for the Radial Profile computation." msgstr "Les options disponibles pour le calcul du profil radial." -msgid "The radial intensity profile displayed in the \"Signal panel\". It is smoother than the line profile, because it is computed from a larger number of pixels, thus averaging the noise." -msgstr "Le profil d'intensité radial affiché dans le panneau \"Signaux\". Il est plus lisse que le profil de ligne, car il est calculé à partir d'un plus grand nombre de pixels, ce qui permet de moyenner le bruit." +msgid "" +"The radial intensity profile displayed in the \"Signal panel\". It is " +"smoother than the line profile, because it is computed from a larger " +"number of pixels, thus averaging the noise." +msgstr "" +"Le profil d'intensité radial affiché dans le panneau \"Signaux\". Il est " +"plus lisse que le profil de ligne, car il est calculé à partir d'un plus " +"grand nombre de pixels, ce qui permet de moyenner le bruit." msgid "Apply these operations to all the images" msgstr "Appliquer ces opérations à toutes les images" -msgid "All the operations and computations performed on a single image can be applied to all images in the \"Image panel\"." -msgstr "Toutes les opérations et calculs effectués sur une seule image peuvent être appliqués à toutes les images du panneau \"Images\"." +msgid "" +"All the operations and computations performed on a single image can be " +"applied to all images in the \"Image panel\"." +msgstr "" +"Toutes les opérations et calculs effectués sur une seule image peuvent " +"être appliqués à toutes les images du panneau \"Images\"." -msgid "To begin, clean the \"Signal panel\" using \"Edit > Delete all\" or the |delete_all| button in the toolbar. Also remove intermediate results from the \"Image panel\" by selecting the images created during prototyping and deleting them individually using \"Edit > Remove\" or the |delete| button." -msgstr "Pour commencer, nettoyez le panneau \"Signaux\" en utilisant \"Édition > Tout supprimer\" ou le bouton |delete_all| dans la barre d'outils. Supprimez également les résultats intermédiaires du panneau \"Images\" en sélectionnant les images créées lors du prototypage et en les supprimant individuellement en utilisant \"Édition > Supprimer\" ou le bouton |delete|." +msgid "" +"To begin, clean the \"Signal panel\" using \"Edit > Delete all\" or the " +"|delete_all| button in the toolbar. Also remove intermediate results from" +" the \"Image panel\" by selecting the images created during prototyping " +"and deleting them individually using \"Edit > Remove\" or the |delete| " +"button." +msgstr "" +"Pour commencer, nettoyez le panneau \"Signaux\" en utilisant \"Édition > " +"Tout supprimer\" ou le bouton |delete_all| dans la barre d'outils. " +"Supprimez également les résultats intermédiaires du panneau \"Images\" en" +" sélectionnant les images créées lors du prototypage et en les supprimant" +" individuellement en utilisant \"Édition > Supprimer\" ou le bouton " +"|delete|." msgid "delete_all" msgstr "delete_all" @@ -189,59 +436,143 @@ msgstr "delete_all" msgid "delete" msgstr "delete" -msgid "Next, select all images in the \"Image panel\" (individually or by selecting the entire group \"g001\")." -msgstr "Ensuite, sélectionnez toutes les images dans le panneau \"Images\" (individuellement ou en sélectionnant l'ensemble du groupe \"g001\")." +msgid "" +"Next, select all images in the \"Image panel\" (individually or by " +"selecting the entire group \"g001\")." +msgstr "" +"Ensuite, sélectionnez toutes les images dans le panneau \"Images\" " +"(individuellement ou en sélectionnant l'ensemble du groupe \"g001\")." -msgid "Apply the clipping operation to all images, then extract the radial intensity profiles for all images (after selecting the entire group \"g002\"—it should be automatically selected if you had \"g001\" selected before applying the threshold)." -msgstr "Appliquez l'opération d'écrêtage à toutes les images, puis extrayez les profils d'intensité radiaux pour toutes les images (après avoir sélectionné l'ensemble du groupe \"g002\"—il devrait être automatiquement sélectionné si vous aviez \"g001\" sélectionné avant d'appliquer le seuil)." +msgid "" +"Apply the clipping operation to all images, then extract the radial " +"intensity profiles for all images (after selecting the entire group " +"\"g002\"—it should be automatically selected if you had \"g001\" selected" +" before applying the threshold)." +msgstr "" +"Appliquez l'opération d'écrêtage à toutes les images, puis extrayez les " +"profils d'intensité radiaux pour toutes les images (après avoir " +"sélectionné l'ensemble du groupe \"g002\"—il devrait être automatiquement" +" sélectionné si vous aviez \"g001\" sélectionné avant d'appliquer le " +"seuil)." msgid "The clipping applies to all images of the group." msgstr "L'écrêtage s'applique à toutes les images du groupe." msgid "The \"Signal panel\" now contains all the radial intensity profiles." -msgstr "Le panneau \"Signaux\" contient maintenant tous les profils d'intensité radiaux." +msgstr "" +"Le panneau \"Signaux\" contient maintenant tous les profils d'intensité " +"radiaux." -msgid "We can now compute the FWHM for all radial intensity profiles. The \"Results\" dialog will display the FWHM values for all profiles." -msgstr "Nous pouvons maintenant calculer la FWHM pour tous les profils d'intensité radiaux. La boîte de dialogue \"Résultats\" affichera les valeurs FWHM pour tous les profils." +msgid "" +"We can now compute the FWHM for all radial intensity profiles. The " +"\"Results\" dialog will display the FWHM values for all profiles." +msgstr "" +"Nous pouvons maintenant calculer la FWHM pour tous les profils " +"d'intensité radiaux. La boîte de dialogue \"Résultats\" affichera les " +"valeurs FWHM pour tous les profils." msgid "The \"Results\" dialog displays the FWHM values for all the profiles." -msgstr "La boîte de dialogue \"Résultats\" affiche les valeurs FWHM pour tous les profils." +msgstr "" +"La boîte de dialogue \"Résultats\" affiche les valeurs FWHM pour tous les" +" profils." -msgid "To display the analysis results again, select \"Show results\" |show_results| from the \"Analysis\" menu, or click the \"Show results\" |show_results| button below the image list:" -msgstr "Pour afficher à nouveau les résultats d'analyse, sélectionnez \"Afficher les résultats\" |show_results| dans le menu \"Analyse\", ou cliquez sur le bouton \"Afficher les résultats\" |show_results| en dessous de la liste des images :" +msgid "" +"To display the analysis results again, select \"Show results\" " +"|show_results| from the \"Analysis\" menu, or click the \"Show results\" " +"|show_results| button below the image list:" +msgstr "" +"Pour afficher à nouveau les résultats d'analyse, sélectionnez \"Afficher " +"les résultats\" |show_results| dans le menu \"Analyse\", ou cliquez sur " +"le bouton \"Afficher les résultats\" |show_results| en dessous de la " +"liste des images :" msgid "show_results" msgstr "show_results" -msgid "Finally, we can plot the beam size as a function of position along the propagation axis using the \"Plot results\" feature |plot_results| from the \"Analysis\" menu. This feature allows you to plot result datasets by selecting the x and y axes from the available result columns. Here, we will plot the FWHM values (`L`) as a function of the image index (`Indices`)." -msgstr "Enfin, nous pouvons tracer la taille du faisceau en fonction de la position le long de l'axe de propagation en utilisant la fonction \"Tracer les résultats\" |plot_results| du menu \"Analyse\". Cette fonction vous permet de tracer des ensembles de données de résultats en sélectionnant les axes x et y parmi les colonnes de résultats disponibles. Ici, nous allons tracer les valeurs FWHM (`L`) en fonction de l'index de l'image (`Indices`)." +msgid "" +"Finally, we can plot the beam size as a function of position along the " +"propagation axis using the \"Plot results\" feature |plot_results| from " +"the \"Analysis\" menu. This feature allows you to plot result datasets by" +" selecting the x and y axes from the available result columns. Here, we " +"will plot the FWHM values (`L`) as a function of the image index " +"(`Indices`)." +msgstr "" +"Enfin, nous pouvons tracer la taille du faisceau en fonction de la " +"position le long de l'axe de propagation en utilisant la fonction " +"\"Tracer les résultats\" |plot_results| du menu \"Analyse\". Cette " +"fonction vous permet de tracer des ensembles de données de résultats en " +"sélectionnant les axes x et y parmi les colonnes de résultats " +"disponibles. Ici, nous allons tracer les valeurs FWHM (`L`) en fonction " +"de l'index de l'image (`Indices`)." msgid "plot_results" msgstr "plot_results" msgid "The \"Plot results\" feature |plot_results| in the \"Analysis\" menu." -msgstr "La fonction \"Tracer les résultats\" |plot_results| dans le menu \"Analyse\"." +msgstr "" +"La fonction \"Tracer les résultats\" |plot_results| dans le menu " +"\"Analyse\"." -msgid "The beam size as a function of position along the propagation axis (the position is in arbitrary units—the image index)." -msgstr "La taille du faisceau en fonction de la position le long de l'axe de propagation (la position est en unités arbitraires—l'index de l'image)." +msgid "" +"The beam size as a function of position along the propagation axis (the " +"position is in arbitrary units—the image index)." +msgstr "" +"La taille du faisceau en fonction de la position le long de l'axe de " +"propagation (la position est en unités arbitraires—l'index de l'image)." -msgid "We can also calibrate the X and Y axes using \"Processing > Linear calibration\". Here we set the X axis to the position in mm (entering the title and unit in the \"Properties\" group box) using the formula: :math:`X[\\textrm{mm}] = 0.5 \\cdot i + 10` where :math:`i` is the image index." -msgstr "Nous pouvons également étalonner les axes X et Y en utilisant \"Traitement > Étalonnage linéaire\". Ici, nous définissons l'axe X sur la position en mm (en entrant le titre et l'unité dans le groupe \"Propriétés\") en utilisant la formule : :math:`X[\\textrm{mm}] = 0.5 \\cdot i + 10` où :math:`i` est l'index de l'image." +#, python-brace-format +msgid "" +"We can also calibrate the X and Y axes using \"Processing > Linear " +"calibration\". Here we set the X axis to the position in mm (entering the" +" title and unit in the \"Properties\" group box) using the formula: " +":math:`X[\\textrm{mm}] = 0.5 \\cdot i + 10` where :math:`i` is the image " +"index." +msgstr "" +"Nous pouvons également étalonner les axes X et Y en utilisant " +"\"Traitement > Étalonnage linéaire\". Ici, nous définissons l'axe X sur " +"la position en mm (en entrant le titre et l'unité dans le groupe " +"\"Propriétés\") en utilisant la formule : :math:`X[\\textrm{mm}] = 0.5 " +"\\cdot i + 10` où :math:`i` est l'index de l'image." -msgid "The calibrated beam size as a function of the position along the propagation axis (the position is now in mm)." -msgstr "La taille du faisceau étalonné en fonction de la position le long de l'axe de propagation (la position est maintenant en mm)." +msgid "" +"The calibrated beam size as a function of the position along the " +"propagation axis (the position is now in mm)." +msgstr "" +"La taille du faisceau étalonné en fonction de la position le long de " +"l'axe de propagation (la position est maintenant en mm)." -msgid "Finally, we can save the workspace to a file |filesave_h5|. The workspace contains all the images and signals that were loaded or processed in DataLab. It also contains the analysis results, the visualization settings (colormaps, contrast, etc.), the metadata, and the annotations." -msgstr "Enfin, nous pouvons enregistrer l'espace de travail dans un fichier |filesave_h5|. L'espace de travail contient toutes les images et signaux qui ont été chargés ou traités dans DataLab. Il contient également les résultats d'analyse, les paramètres de visualisation (cartes de couleurs, contraste, etc.), les métadonnées et les annotations." +msgid "" +"Finally, we can save the workspace to a file |filesave_h5|. The workspace" +" contains all the images and signals that were loaded or processed in " +"DataLab. It also contains the analysis results, the visualization " +"settings (colormaps, contrast, etc.), the metadata, and the annotations." +msgstr "" +"Enfin, nous pouvons enregistrer l'espace de travail dans un fichier " +"|filesave_h5|. L'espace de travail contient toutes les images et signaux " +"qui ont été chargés ou traités dans DataLab. Il contient également les " +"résultats d'analyse, les paramètres de visualisation (cartes de couleurs," +" contraste, etc.), les métadonnées et les annotations." msgid "filesave_h5" msgstr "filesave_h5" -msgid "If you want to load the workspace again, you can use the \"File > Open HDF5 file...\" (or the |fileopen_h5| button in the toolbar) to load the whole workspace, or the \"File > Browse HDF5 file...\" (or the |h5browser| button in the toolbar) to load only a selection of data sets from the workspace." -msgstr "Si vous souhaitez charger à nouveau l'espace de travail, vous pouvez utiliser \"Fichier > Ouvrir un fichier HDF5...\" (ou le bouton |fileopen_h5| dans la barre d'outils) pour charger l'ensemble de l'espace de travail, ou \"Fichier > Parcourir un fichier HDF5...\" (ou le bouton |h5browser| dans la barre d'outils) pour charger uniquement une sélection d'ensembles de données de l'espace de travail." +msgid "" +"If you want to load the workspace again, you can use the \"File > Open " +"HDF5 file...\" (or the |fileopen_h5| button in the toolbar) to load the " +"whole workspace, or the \"File > Browse HDF5 file...\" (or the " +"|h5browser| button in the toolbar) to load only a selection of data sets " +"from the workspace." +msgstr "" +"Si vous souhaitez charger à nouveau l'espace de travail, vous pouvez " +"utiliser \"Fichier > Ouvrir un fichier HDF5...\" (ou le bouton " +"|fileopen_h5| dans la barre d'outils) pour charger l'ensemble de l'espace" +" de travail, ou \"Fichier > Parcourir un fichier HDF5...\" (ou le bouton " +"|h5browser| dans la barre d'outils) pour charger uniquement une sélection" +" d'ensembles de données de l'espace de travail." msgid "fileopen_h5" msgstr "fileopen_h5" msgid "h5browser" msgstr "h5browser" + From ed05172aa6c1443460a3ace100128202edb87f2f Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Thu, 6 Aug 2026 09:40:04 +0200 Subject: [PATCH 074/108] Feat: Track analysis effects and ROI mutations in the History panel 1-to-0 analyses write their results (and sometimes ROIs) into the source object's metadata, but history kept no durable record of which keys they touched: recompute rolled back failures with full-metadata snapshots that clobbered unrelated user edits, actions were matched to their source through a fragile input-UUID heuristic, and detection recomputes re-created ROIs the user had deleted or edited. Separately, in-place ROI modifications (graphical/numerical edit, deletion, paste) were recorded as non-replayable UI entries or not recorded at all, so replaying a pipeline could run downstream computations on ROIs that no longer matched the actual workspace. Analyses now capture a per-source effects manifest (metadata keys added or replaced, ROI touched) persisted with the action, and in-place ROI changes are recorded as first-class mutation actions that replay, cascade and persist like any other history entry. * [NEW] : Analysis effects manifest (datalab.history.effects): capture_effects() context manager diffs metadata (numpy-safe) and ROI around a 1-to-0 run; per-source manifests are stored on the action (schema v1 -> v2), JSON-serialized to HDF5, tolerated when absent on legacy actions, and remapped on copy/duplication * [NEW] : Record ROI mutations (graphical/numerical edit, remove all, remove single, paste) as mutation-kind history actions carrying the post-mutation ROI payload; replay re-applies the recorded state, step-by-step lets the user edit the payload before re-applying and recomputes the downstream closure, cascades re-apply mutations to surviving targets, and mutations are saved with sessions (.dlhist and workspace HDF5) with backward-compatible deserialization * [CHG] : Targeted snapshot/rollback in recompute_1_to_0_in_place: with a manifest, only the listed keys are deep-copied and a failed attempt rolls back exactly those keys (plus any it created), leaving unrelated metadata untouched; legacy actions keep the full-metadata snapshot; freshly captured effects are merged into the manifest on success * [CHG] : find_analysis_action matches through the effects manifest first (exact, durable record), falling back to the input-UUID heuristic for pre-manifest actions * [NEW] : Generic result-adapter registry in adapters_metadata (register_result_adapter/create_adapter, MRO-aware resolution) replacing per-type dispatch, as an extension point for plugin-defined result typologies * [CHG] : Consolidate first-run-only side effects into disable_first_run_side_effects(): recompute paths clear create_rois on a local param copy (callers' parameters are never mutated), so re-running a detection refreshes results without re-creating ROIs, while apply_analysis_parameters keeps the user-intent parameter in history * [CHG] : Include an ROI signature in workspace-state object metadata for compatibility checks; mutation actions exclude their own targets from the comparison (the recorded state is post-mutation) and states recorded before signatures existed skip it * [FIX] : Keep the target's user ROI when a recomputed object carries none (update_obj_in_place, aligned with the 1-to-1 path) and invalidate the ROI cache when a rollback restores or removes the ROI metadata entry * [FIX] : Copying an ROI to the clipboard no longer records a history entry (only the paste mutates objects), and copy/paste safely ignore objects without ROI or an empty clipboard * [CHG] : Add unit tests for the effects manifest, adapter registry, mutation model and ROI mutation workflows; extend history model, workflow and analysis-parameter tests (with unattended-mode fixes for standalone runs) * [DOC] : Document the new "Object mutations" behavior and the analysis effects replay semantics in the History panel documentation; update French translations (UI catalog and documentation) --- datalab/adapters_metadata/__init__.py | 4 + datalab/adapters_metadata/common.py | 51 +++- datalab/gui/historysession_ops.py | 49 ++++ datalab/gui/panel/base.py | 52 ++-- datalab/gui/panel/history/chain.py | 53 +++- datalab/gui/panel/history/facade.py | 20 ++ .../gui/panel/history/interactive_replay.py | 17 +- datalab/gui/panel/history/recompute.py | 184 ++++++++++-- datalab/gui/processor/base.py | 103 +++++-- datalab/history/action.py | 197 ++++++++++++- datalab/history/core.py | 6 +- datalab/history/effects.py | 155 +++++++++++ datalab/history/workspace_state.py | 74 ++++- datalab/locale/fr/LC_MESSAGES/datalab.po | 21 +- .../common/adapters_registry_unit_test.py | 135 +++++++++ .../analysis_parameters_edit_unit_test.py | 1 + .../common/history_effects_unit_test.py | 263 ++++++++++++++++++ .../common/history_model_unit_test.py | 87 +++++- .../history_mutation_model_unit_test.py | 89 ++++++ .../common/history_roi_mutation_test.py | 194 +++++++++++++ .../features/common/history_workflow_test.py | 41 ++- .../image/detection_roi_merge_unit_test.py | 2 + doc/features/common/historypanel.rst | 46 ++- .../features/common/historypanel.po | 119 +++++++- 24 files changed, 1833 insertions(+), 130 deletions(-) create mode 100644 datalab/history/effects.py create mode 100644 datalab/tests/features/common/adapters_registry_unit_test.py create mode 100644 datalab/tests/features/common/history_effects_unit_test.py create mode 100644 datalab/tests/features/common/history_mutation_model_unit_test.py create mode 100644 datalab/tests/features/common/history_roi_mutation_test.py diff --git a/datalab/adapters_metadata/__init__.py b/datalab/adapters_metadata/__init__.py index 37bfe4ea7..0bca1806d 100644 --- a/datalab/adapters_metadata/__init__.py +++ b/datalab/adapters_metadata/__init__.py @@ -9,9 +9,11 @@ from .base_adapter import BaseResultAdapter from .common import ( ResultData, + create_adapter, create_resultdata_dict, have_geometry_results, have_results, + register_result_adapter, resultadapter_to_html, show_resultdata, ) @@ -23,9 +25,11 @@ "GeometryAdapter", "ResultData", "TableAdapter", + "create_adapter", "create_resultdata_dict", "have_geometry_results", "have_results", + "register_result_adapter", "resultadapter_to_html", "show_resultdata", ] diff --git a/datalab/adapters_metadata/common.py b/datalab/adapters_metadata/common.py index e334dff9a..4e9ee8555 100644 --- a/datalab/adapters_metadata/common.py +++ b/datalab/adapters_metadata/common.py @@ -14,7 +14,7 @@ import pandas as pd from guidata.qthelpers import exec_dialog from guidata.widgets.dataframeeditor import DataFrameEditor -from sigima.objects import ImageObj, SignalObj +from sigima.objects import GeometryResult, ImageObj, SignalObj, TableResult from datalab.adapters_metadata.base_adapter import BaseResultAdapter from datalab.adapters_metadata.geometry_adapter import GeometryAdapter @@ -25,6 +25,55 @@ if TYPE_CHECKING: from qtpy.QtWidgets import QWidget +# Registry mapping result typologies to their metadata adapter classes +_ADAPTER_REGISTRY: dict[type, type[BaseResultAdapter]] = { + GeometryResult: GeometryAdapter, + TableResult: TableAdapter, +} + + +def register_result_adapter( + result_class: type, adapter_class: type[BaseResultAdapter] +) -> None: + """Register an adapter class for a result typology (extension point for + new result typologies, e.g. from plugins). + + Args: + result_class: Result typology to associate with the adapter. + adapter_class: Adapter class instantiated for results of that typology. + """ + _ADAPTER_REGISTRY[result_class] = adapter_class + + +def create_adapter(result: GeometryResult | TableResult) -> BaseResultAdapter: + """Create the metadata adapter matching the result's typology. + + Resolution first looks up the exact type in the registry, then walks the + result type's MRO so subclasses of registered typologies are accepted: + the most specific registered base class wins, regardless of registration + order. + + Args: + result: Analysis result to wrap. + + Returns: + Adapter instance wrapping ``result``. + + Raises: + TypeError: If no adapter is registered for the result's type. + """ + adapter_class = _ADAPTER_REGISTRY.get(type(result)) + if adapter_class is None: + for base in type(result).__mro__[1:]: + adapter_class = _ADAPTER_REGISTRY.get(base) + if adapter_class is not None: + break + if adapter_class is None: + raise TypeError( + f"No result adapter registered for type {type(result).__name__!r}" + ) + return adapter_class(result) + def alpha_label(index: int) -> str: """Return an alphabetic label for a 0-based index. diff --git a/datalab/gui/historysession_ops.py b/datalab/gui/historysession_ops.py index b0994bc21..23648c08d 100644 --- a/datalab/gui/historysession_ops.py +++ b/datalab/gui/historysession_ops.py @@ -349,6 +349,55 @@ def add_ui_entry( return action +def add_mutation_entry( + panel: HistoryPanel, + action_title: str, + panel_str: str, + mutation_key: str, + target_uuids: list[str], + payload: Any = None, + save_state: bool = True, +) -> HistoryAction | None: + """Record a *mutation* action in the current history session. + + Mutation actions describe in-place modifications of existing data objects + (no new objects created), e.g. ROI assignment or removal. At replay time, + the payload is re-applied to each target object still present in the data + panel's object model. + + Args: + action_title: Title shown in the history tree. + panel_str: Data panel the mutation operates on ("signal" or "image"). + mutation_key: Mutation identifier (currently only "roi" is supported). + target_uuids: UUIDs of the data objects modified in place. + payload: Mutation payload (e.g. a sigima ROI object). ``None`` means + the attribute is removed at replay time (e.g. ROI deletion). + save_state: If True, capture the workspace state for replay. + + Returns: + The created :class:`HistoryAction`, or ``None`` if recording is + disabled (record mode off or replay in progress). + """ + if not panel.record_mode_enabled or panel.is_replaying(): + return None + state = WorkspaceState() + if save_state: + state.save(panel.mainwindow, panel_str=panel_str) + # Deep-copy the payload to ensure independent ownership (same rationale + # as in add_compute_entry). A None payload is encoded as a missing kwarg. + action = HistoryAction( + title=action_title, + kind=HistoryAction.KIND_MUTATION, + panel_str=panel_str, + mutation_key=mutation_key, + target_uuids=list(target_uuids), + kwargs={"payload": deepcopy(payload)} if payload is not None else {}, + state=state, + ) + panel.add_object(action) + return action + + def add_object(panel: HistoryPanel, obj: HistoryAction) -> None: """Add an action to the single active recording session. diff --git a/datalab/gui/panel/base.py b/datalab/gui/panel/base.py index 578afb92c..add3fff83 100644 --- a/datalab/gui/panel/base.py +++ b/datalab/gui/panel/base.py @@ -1062,13 +1062,6 @@ def apply_analysis_parameters( param = editor.dataset if editor is not None else proc_params.param recompute_param = copy.deepcopy(param) - # Disable ROI creation during re-analysis: detection functions store - # create_rois=True in their parameters, but re-running should only - # update analysis results, not recreate ROIs (which would make them - # impossible to delete or modify). - if hasattr(recompute_param, "create_rois"): - recompute_param.create_rois = False - # Re-run the analysis in place (no history entry: runs under replaying) processor = self.__get_processor_associated_to(obj) try: @@ -2324,45 +2317,50 @@ def copy_roi(self, roi_data=None) -> None: """Copy regions of interest Args: - roi_data: ROI snapshot for replay. When ``None`` (interactive use), - the ROI is read from the currently selected object. + roi_data: ROI snapshot kept for legacy session replay compatibility. + When ``None`` (interactive use), the ROI is read from the + currently selected object. """ + # Copying to the clipboard mutates nothing: no history entry is + # recorded (the paste operation records the resulting ROI mutation). if roi_data is None: obj = self.objview.get_sel_objects()[0] + if obj.roi is None: + return roi_data = obj.roi.copy() self.__roi_clipboard = roi_data.copy() - self.mainwindow.historypanel.add_ui_entry( - _("Copy regions of interest from selected %s") - % (_("signal") if self.PANEL_STR_ID == "signal" else _("image")), - target=self.PANEL_STR_ID + "panel", - method_name="copy_roi", - save_state=True, - roi_data=roi_data, - ) def paste_roi(self, roi_data=None) -> None: """Paste regions of interest Args: - roi_data: ROI snapshot for replay. When ``None`` (interactive use), - the clipboard populated by :meth:`copy_roi` is used. + roi_data: ROI snapshot kept for legacy session replay compatibility. + When ``None`` (interactive use), the clipboard populated by + :meth:`copy_roi` is used. """ if roi_data is None: roi_data = self.__roi_clipboard - self.mainwindow.historypanel.add_ui_entry( - _("Paste regions of interest into selected %s") - % (_("signal") if self.PANEL_STR_ID == "signal" else _("image")), - target=self.PANEL_STR_ID + "panel", - method_name="paste_roi", - save_state=True, - roi_data=roi_data, - ) + if roi_data is None: + return sel_objects = self.objview.get_sel_objects(include_groups=True) + title = _("Paste regions of interest into selected %s") % ( + _("signal") if self.PANEL_STR_ID == "signal" else _("image") + ) for obj in sel_objects: if obj.roi is None: obj.roi = roi_data.copy() else: obj.roi = obj.roi.combine_with(roi_data) + # Pasting combines with any existing ROI, whereas mutation replay + # replaces the target's ROI: record one entry per object with the + # post-combination ROI so replay is deterministic. + self.mainwindow.historypanel.add_mutation_entry( + title, + panel_str=self.PANEL_STR_ID, + mutation_key="roi", + target_uuids=[get_uuid(obj)], + payload=obj.roi, + ) self.selection_changed(update_items=True) self.refresh_plot( "selected", update_items=True, only_visible=False, only_existing=True diff --git a/datalab/gui/panel/history/chain.py b/datalab/gui/panel/history/chain.py index 88c1385e5..7ebbf7fa9 100644 --- a/datalab/gui/panel/history/chain.py +++ b/datalab/gui/panel/history/chain.py @@ -179,8 +179,13 @@ def find_analysis_action( """Find the 1-to-0 analysis action for ``obj_uuid`` with ``func_name``. Analysis operations (1-to-0) do not produce a new output object: they - write their result to the input object's metadata. The matching action is - therefore identified by its input UUID and function name. + write their result to the input object's metadata. Matching is two-pass: + + 1. Effects manifest: an action whose ``effects`` manifest contains + ``obj_uuid`` is a durable, exact record that it wrote to that object. + The most recent such action wins. + 2. Legacy heuristic: for actions recorded before the manifest existed, + fall back to matching ``obj_uuid`` against the action's input UUIDs. Args: panel: The history panel providing the sessions. @@ -190,14 +195,18 @@ def find_analysis_action( Returns: The matching :class:`HistoryAction`, or ``None`` if not found. """ - for session in reversed(panel.history_sessions): - for action in reversed(session.actions): - if action.kind != HistoryAction.KIND_COMPUTE: - continue - if action.func_name != func_name: - continue - if obj_uuid in action_input_uuids(action): - return action + candidates = [ + action + for session in reversed(panel.history_sessions) + for action in reversed(session.actions) + if action.kind == HistoryAction.KIND_COMPUTE and action.func_name == func_name + ] + for action in candidates: + if action.effects is not None and obj_uuid in action.effects: + return action + for action in candidates: + if obj_uuid in action_input_uuids(action): + return action return None @@ -237,6 +246,13 @@ def action_consumes_any(action: HistoryAction, uuids: set[str]) -> bool: return bool(action_input_uuids(action) & uuids) +def action_mutates_any(action: HistoryAction, uuids: set[str]) -> bool: + """Return True if ``action``'s mutation targets intersect ``uuids``.""" + if action.kind != HistoryAction.KIND_MUTATION: + return False + return bool(set(action.target_uuids or []) & uuids) + + def get_downstream_actions( panel: HistoryPanel, action: HistoryAction ) -> list[HistoryAction]: @@ -246,13 +262,24 @@ def get_downstream_actions( current = get_session_of(panel, action) if current is None: return [] - root_outputs = recorded_action_output_uuids(panel, action) + if action.kind == HistoryAction.KIND_MUTATION: + # Mutations produce no outputs: seed the closure with the mutated + # objects so downstream computes consuming them are included. + root_outputs = list(action.target_uuids or []) + else: + root_outputs = recorded_action_output_uuids(panel, action) if not root_outputs: return [] closure: set[str] = set(root_outputs) downstream: list[HistoryAction] = [] idx = current.actions.index(action) for candidate in current.actions[idx + 1 :]: + if candidate.kind == HistoryAction.KIND_MUTATION: + # Mutations produce no outputs: they are downstream when they + # modify an object already in the closure. + if action_mutates_any(candidate, closure): + downstream.append(candidate) + continue if candidate.kind != HistoryAction.KIND_COMPUTE: continue if not action_consumes_any(candidate, closure): @@ -300,6 +327,10 @@ def rewrite_action_source( action.kwargs["obj2_uuids"] = new_uuid elif obj2: action.kwargs["obj2_uuids"] = [new_uuid if u == old_uuid else u for u in obj2] + if action.target_uuids and action.effective_panel_str() == pstr: + action.target_uuids = [ + new_uuid if u == old_uuid else u for u in action.target_uuids + ] def remove_single_action(panel: HistoryPanel, action: HistoryAction) -> None: diff --git a/datalab/gui/panel/history/facade.py b/datalab/gui/panel/history/facade.py index 0b137a4f4..17b282fe5 100644 --- a/datalab/gui/panel/history/facade.py +++ b/datalab/gui/panel/history/facade.py @@ -258,6 +258,26 @@ def add_ui_entry( self, action_title, target, method_name, save_state, **kwargs ) + def add_mutation_entry( + self, + action_title: str, + panel_str: str, + mutation_key: str, + target_uuids: list[str], + payload: Any = None, + save_state: bool = True, + ) -> HistoryAction | None: + """Add a mutation entry to history.""" + return hsess.add_mutation_entry( + self, + action_title, + panel_str, + mutation_key, + target_uuids, + payload, + save_state, + ) + class HistoryPersistenceFacadeMixin: """Expose standalone and workspace HDF5 persistence operations.""" diff --git a/datalab/gui/panel/history/interactive_replay.py b/datalab/gui/panel/history/interactive_replay.py index 37edf70a2..6804df32e 100644 --- a/datalab/gui/panel/history/interactive_replay.py +++ b/datalab/gui/panel/history/interactive_replay.py @@ -215,10 +215,25 @@ def replay_actions( try: for action in execution_plan: if action in deferred_actions: + if hchain.action_mutates_any(action, blocked_outputs): + # Mutation targeting an object whose recompute failed + # upstream: skip it like a blocked compute. + continue + payload_before = action.kwargs.get("payload") with panel.replaying(), panel.output_suppressed(): action.replay( panel.mainwindow, restore_selection=True, edit=prompt ) + if ( + prompt + and action.kind == HistoryAction.KIND_MUTATION + and action.kwargs.get("payload") is not payload_before + ): + # The mutation payload was edited in the dialog: + # recompute the downstream closure (seeded from the + # mutation targets, see ``get_downstream_actions``). + panel.tree.refresh_action_item(action) + hrec.recompute_cascade(panel, action) continue if hchain.action_consumes_any(action, blocked_outputs): blocked_outputs.update( @@ -271,7 +286,7 @@ def restore_action_params( actions = [ a for a in item.actions - if a.kind == HistoryAction.KIND_COMPUTE + if a.kind in (HistoryAction.KIND_COMPUTE, HistoryAction.KIND_MUTATION) or ( a.kind == HistoryAction.KIND_UI and a.method_name in HistoryAction.UI_CREATION_METHODS diff --git a/datalab/gui/panel/history/recompute.py b/datalab/gui/panel/history/recompute.py index 8683aaf8b..a5d0afb3c 100644 --- a/datalab/gui/panel/history/recompute.py +++ b/datalab/gui/panel/history/recompute.py @@ -6,10 +6,11 @@ import copy import logging -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Any from qtpy import QtWidgets as QW from sigima.objects import ImageObj, SignalObj +from sigima.objects.base import ROI_KEY from datalab.config import _ from datalab.env import execenv @@ -28,6 +29,7 @@ insert_processing_parameters, ) from datalab.history import HistoryAction +from datalab.history.effects import AnalysisEffects, capture_effects, merge_effects from datalab.objectmodel import get_uuid if TYPE_CHECKING: @@ -65,12 +67,17 @@ def update_obj_in_place( try: saved_uuid = target_obj.metadata.get("__uuid") saved_number = target_obj.metadata.get("__number") + # Align with the 1_to_1 path: keep the target's user ROI when the + # freshly computed object does not carry one. + saved_roi = target_obj.metadata.get(ROI_KEY) target_obj.metadata.clear() target_obj.metadata.update(new_obj.metadata) if saved_uuid is not None: target_obj.metadata["__uuid"] = saved_uuid if saved_number is not None: target_obj.metadata["__number"] = saved_number + if saved_roi is not None and ROI_KEY not in target_obj.metadata: + target_obj.metadata[ROI_KEY] = saved_roi except AttributeError: pass @@ -171,6 +178,54 @@ def apply_output_in_place_or_recreate( insert_processing_parameters(target_obj, pparams) +def recompute_mutation_in_place(panel: HistoryPanel, action: HistoryAction) -> bool: + """Re-apply a mutation action to its target object(s) during a cascade. + + The recorded payload is re-applied through + :meth:`HistoryAction.replay_mutation`; targets that were deleted are + skipped with a cascade warning. + + Args: + panel: History panel instance. + action: Mutation-kind history action to re-apply. + + Returns: + True when at least one target object was mutated. + """ + name = action.title or action.uuid + panel_data = hchain.resolve_panel_for_action(panel, action) + if panel_data is None: + panel.runtime.execution.cascade_warnings.append( + _("Action %s: target panel not found — skipping.") % name + ) + return False + targets = action.target_uuids or [] + if not targets: + panel.runtime.execution.cascade_warnings.append( + _("Action %s: no recorded mutation target — skipping.") % name + ) + return False + missing = [uuid for uuid in targets if not panel_data.objmodel.has_uuid(uuid)] + if len(missing) == len(targets): + panel.runtime.execution.cascade_warnings.append( + _("Action %s: target object(s) no longer exist — skipping.") % name + ) + return False + if missing: + panel.runtime.execution.cascade_warnings.append( + _("Action %s: %d target object(s) were deleted — applying to the rest.") + % (name, len(missing)) + ) + # ``replaying()`` is reentrant: suppress history capture while the + # payload is re-applied to the data panel objects. ``refresh=False`` + # because each mutated target is refreshed individually below. + with panel.replaying(): + mutated = action.replay_mutation(panel.mainwindow, refresh=False) + for uuid in mutated: + refresh_target(panel_data, uuid) + return bool(mutated) + + def recompute_action_in_place(panel: HistoryPanel, action: HistoryAction) -> bool: """Re-run ``action`` on the existing output object(s) (same UUIDs).""" if ( @@ -178,6 +233,8 @@ def recompute_action_in_place(panel: HistoryPanel, action: HistoryAction) -> boo and action.method_name in HistoryAction.UI_CREATION_METHODS ): return recompute_creation_in_place(panel, action) + if action.kind == HistoryAction.KIND_MUTATION: + return recompute_mutation_in_place(panel, action) if action.kind != HistoryAction.KIND_COMPUTE: return False method = { @@ -212,7 +269,7 @@ def recompute_action_in_place(panel: HistoryPanel, action: HistoryAction) -> boo return success except FeatureNotFoundError as exc: handle_missing_feature(panel, action, exc) - except (RuntimeError, ValueError, AttributeError, KeyError, TypeError) as exc: + except Exception as exc: # pylint: disable=broad-exception-caught action.is_stale = True panel.runtime.execution.broken_actions.add(action.uuid) _logger.exception( @@ -670,8 +727,84 @@ def recompute_2_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> boo return True +def _snapshot_analysis_source( + obj: SignalObj | ImageObj, effects_dict: dict | None +) -> tuple[dict[str, Any], list[str] | None]: + """Snapshot the metadata of one analysis source before a recompute. + + When an effects manifest is available, only the keys it lists are deep + copied (targeted snapshot) and the manifest keys currently absent are + recorded so a failed attempt that recreates them can be rolled back by + deletion. Without a manifest (legacy action), the whole metadata + dictionary is deep copied. + + Args: + obj: Source object about to be recomputed. + effects_dict: Serialized :class:`AnalysisEffects` manifest, or None. + + Returns: + Tuple ``(saved, absent)`` where ``saved`` maps keys to deep-copied + values and ``absent`` lists manifest keys missing before the + recompute. ``absent`` is None for the legacy full-metadata snapshot. + """ + if effects_dict is None: + return copy.deepcopy(obj.metadata), None + manifest = AnalysisEffects.from_dict(effects_dict) + keys = manifest.metadata_added + manifest.metadata_replaced + saved = { + key: copy.deepcopy(obj.metadata[key]) for key in keys if key in obj.metadata + } + absent = [key for key in keys if key not in obj.metadata] + return saved, absent + + +def _restore_analysis_source( + obj: SignalObj | ImageObj, + saved: dict[str, Any], + absent: list[str] | None, + attempt_effects: AnalysisEffects | None, +) -> None: + """Restore a source's metadata from its snapshot after a failed recompute. + + Args: + obj: Source object to restore. + saved: Snapshotted metadata values (full metadata for legacy actions). + absent: Manifest keys absent before the recompute (delete them if the + failed attempt recreated them), or None for a legacy full restore. + attempt_effects: Effects captured during the failed attempt, used to + delete keys it created outside the manifest (targeted mode only). + """ + if absent is None: + obj.metadata.clear() + obj.metadata.update(saved) + # Drop any ROI created during the failed recompute so the cache stays + # consistent with the restored metadata + obj.invalidate_roi_cache() + return + touched = set(saved) | set(absent) + if attempt_effects is not None: + for key in attempt_effects.metadata_added: + obj.metadata.pop(key, None) + touched.update(attempt_effects.metadata_added) + obj.metadata.update(saved) + for key in absent: + obj.metadata.pop(key, None) + if ROI_KEY in touched and hasattr(obj, "invalidate_roi_cache"): + # Align with the legacy full-restore path: a restored/removed ROI + # entry must not leave a stale cached ROI object behind. + obj.invalidate_roi_cache() + + def recompute_1_to_0_in_place(panel: HistoryPanel, action: HistoryAction) -> bool: - """Recompute a 1-to-0 analysis on each source object in place.""" + """Recompute a 1-to-0 analysis on each source object in place. + + Sources are snapshotted before the recompute. When the action carries an + effects manifest, the snapshot is targeted: only manifest keys are deep + copied and a failed attempt rolls back exactly those keys (plus any key + the attempt created), leaving unrelated metadata untouched. Legacy + actions without a manifest fall back to a full-metadata snapshot. + On success, the freshly captured effects are merged into the manifest. + """ panel_data = hchain.resolve_panel_for_action(panel, action) if panel_data is None: return False @@ -679,8 +812,6 @@ def recompute_1_to_0_in_place(panel: HistoryPanel, action: HistoryAction) -> boo if not sources: return False param = copy.deepcopy(action.kwargs.get("param")) - if hasattr(param, "create_rois"): - param.create_rois = False missing = [uuid for uuid in sources if not panel_data.objmodel.has_uuid(uuid)] if missing: panel.runtime.execution.cascade_warnings.append( @@ -689,29 +820,44 @@ def recompute_1_to_0_in_place(panel: HistoryPanel, action: HistoryAction) -> boo ) return False source_objs = [panel_data.objmodel[uuid] for uuid in sources] - metadata_snapshots = [copy.deepcopy(obj.metadata) for obj in source_objs] + snapshots = [ + _snapshot_analysis_source(obj, (action.effects or {}).get(uuid)) + for uuid, obj in zip(sources, source_objs) + ] + captured: dict[str, AnalysisEffects] = {} + + def rollback() -> None: + for uuid, obj, (saved, absent) in zip(sources, source_objs, snapshots): + _restore_analysis_source(obj, saved, absent, captured.get(uuid)) + try: - for src_obj in source_objs: + for uuid, src_obj in zip(sources, source_objs): analysis_parameters = extract_analysis_parameters(src_obj) plugin_origin = action.plugin_origin or ( analysis_parameters.plugin_origin if analysis_parameters else None ) - success = panel_data.processor.recompute_1_to_0( - action.func_name, - src_obj, - param, - plugin_origin=plugin_origin, - ) + with capture_effects(src_obj) as effects: + # Register the (mutable) effects before running so rollback + # sees them even when the recompute raises + captured[uuid] = effects + success = panel_data.processor.recompute_1_to_0( + action.func_name, + src_obj, + param, + plugin_origin=plugin_origin, + ) if not success: - for obj, metadata in zip(source_objs, metadata_snapshots): - obj.metadata.clear() - obj.metadata.update(metadata) + rollback() return False except Exception: - for obj, metadata in zip(source_objs, metadata_snapshots): - obj.metadata.clear() - obj.metadata.update(metadata) + rollback() raise + if action.effects is None: + action.effects = {} + for uuid in sources: + prev_dict = action.effects.get(uuid) + previous = AnalysisEffects.from_dict(prev_dict) if prev_dict else None + action.effects[uuid] = merge_effects(previous, captured[uuid]).to_dict() for uuid in sources: refresh_target(panel_data, uuid) return True diff --git a/datalab/gui/processor/base.py b/datalab/gui/processor/base.py index be9fb1296..69dfcfc4a 100644 --- a/datalab/gui/processor/base.py +++ b/datalab/gui/processor/base.py @@ -44,11 +44,13 @@ GeometryAdapter, ResultData, TableAdapter, + create_adapter, show_resultdata, ) from datalab.adapters_plotpy import coordutils from datalab.config import Conf, _ from datalab.gui.processor.catcher import CompOut, wng_err_func +from datalab.history.effects import capture_effects from datalab.objectmodel import get_short_id, get_uuid, patch_title_with_ids from datalab.utils.qthelpers import create_progress_bar, qt_try_except from datalab.widgets.warningerror import show_warning_error @@ -273,6 +275,29 @@ def clear_analysis_parameters(obj: SignalObj | ImageObj) -> None: del obj.metadata[key] +# Param fields triggering side effects that must only run on first execution +FIRST_RUN_ONLY_PARAM_FIELDS = ("create_rois",) + + +def disable_first_run_side_effects(param: Any) -> None: + """Disable parameter fields whose side effects must only run once. + + Recomputing an analysis must refresh its results, not replay first-run + side effects: for instance, detection functions store ``create_rois=True`` + in their parameters, but re-running should not recreate ROIs (which would + overwrite ROIs deleted or edited by the user). Each field listed in + :data:`FIRST_RUN_ONLY_PARAM_FIELDS` is set to False when present on + ``param``. This is a generic extension point for future side-effect + parameters. + + Args: + param: Parameter dataset to sanitize in place (None is a no-op). + """ + for field_name in FIRST_RUN_ONLY_PARAM_FIELDS: + if hasattr(param, field_name): + setattr(param, field_name, False) + + def run_with_env(func: Callable, args: tuple, env_json: str) -> CompOut: """Wrapper to apply environment config before calling func @@ -1257,22 +1282,13 @@ def recompute_analysis( if proc_params is None or proc_params.pattern != "1-to-0": return False - # Get the parameter from processing parameters - param = copy.deepcopy(proc_params.param) - - # Disable ROI creation during recompute: detection functions store - # create_rois=True in their parameters, but recompute should only - # update analysis results, not recreate ROIs (which would make them - # impossible to delete or modify). - if hasattr(param, "create_rois"): - param.create_rois = False - # Recompute the analysis operation silently, only for this specific object # (not all selected objects, to avoid O(n²) behavior when called in a loop). + # No deepcopy needed here: recompute_1_to_0 deepcopies its param internally. success = self.recompute_1_to_0( proc_params.func_name, obj, - param, + param=proc_params.param, plugin_origin=proc_params.plugin_origin, ) if not success: @@ -1773,6 +1789,10 @@ def recompute_1_to_0( Returns: True if the analysis result was refreshed successfully. """ + # Work on a local copy so callers' kwargs are never mutated, and + # disable side effects that must only run on first execution + param = copy.deepcopy(param) + disable_first_run_side_effects(param) paramclass_name = type(param).__name__ if param is not None else None feature = self.get_feature( func_name, @@ -2163,13 +2183,7 @@ def compute_1_to_0( short_id_count = len(rdata.short_ids) def persist_result(result=result, obj=obj) -> bool: - if isinstance(result, GeometryResult): - adapter = GeometryAdapter(result) - elif isinstance(result, TableResult): - adapter = TableAdapter(result) - else: - raise TypeError("Unsupported result type") - + adapter = create_adapter(result) adapter.add_to(obj, param) pp = ProcessingParameters( func_name=func.__name__, @@ -2183,18 +2197,27 @@ def persist_result(result=result, obj=obj) -> bool: rdata.append(adapter, obj) return result_modified - persistence_output = wng_err_func(persist_result, ()) - result_modified = self.handle_output( - persistence_output, _("Computing: %s") % title, progress - ) + with capture_effects(obj) as effects: + persistence_output = wng_err_func(persist_result, ()) + result_modified = self.handle_output( + persistence_output, _("Computing: %s") % title, progress + ) if result_modified is None: + # Rollback: discard the captured effects for this object obj.metadata = metadata_snapshot + # Drop any ROI created during the failed computation so the + # cache stays consistent with the restored metadata + obj.invalidate_roi_cache() del rdata.results[result_count:] del rdata.ylabels[ylabel_count:] del rdata.short_ids[short_id_count:] rdata.execution_success = False continue refresh_needed |= result_modified + if action is not None: + if action.effects is None: + action.effects = {} + action.effects[get_uuid(obj)] = effects.to_dict() if obj is current_obj: # Mark object as having fresh analysis results to show Analysis tab @@ -3202,6 +3225,22 @@ def _extract_multiple_roi_in_single_object( # ------Analysis------------------------------------------------------------------- + def _record_roi_mutation( + self, title: str, objs: list[TypeObj], roi: TypeROI | None + ) -> None: + """Record a ROI mutation history entry for ``objs`` (payload may be None).""" + # Some tests build processors without a history panel: stay defensive. + hpanel = getattr(self.mainwindow, "historypanel", None) + if hpanel is None: + return + hpanel.add_mutation_entry( + title, + panel_str=self.panel.PANEL_STR_ID, + mutation_key="roi", + target_uuids=[get_uuid(obj) for obj in objs], + payload=roi, + ) + def edit_roi_graphically( self, mode: Literal["apply", "extract", "define"] = "apply" ) -> TypeROI | None: @@ -3245,12 +3284,22 @@ def edit_roi_graphically( # object yet) for obj_i in objs: obj_i.roi = None + # Objects are actually mutated in both "apply" and "extract" + # modes here (mode != "define" is guaranteed above). + self._record_roi_mutation( + _("Edit regions of interest graphically"), objs, None + ) else: edited_roi = edited_roi.__class__.from_params(obj, params) if mode == "apply": # Apply ROI to all selected objects for obj_i in objs: obj_i.roi = edited_roi + self._record_roi_mutation( + _("Edit regions of interest graphically"), + objs, + edited_roi, + ) self.SIG_ADD_SHAPE.emit(get_uuid(obj)) self.panel.selection_changed(update_items=True) self.panel.refresh_plot( @@ -3283,6 +3332,9 @@ def edit_roi_numerically(self) -> TypeROI: if group.edit(parent=self.mainwindow): edited_roi = obj.roi.__class__.from_params(obj, params) obj.roi = edited_roi + self._record_roi_mutation( + _("Edit regions of interest numerically"), [obj], edited_roi + ) self.SIG_ADD_SHAPE.emit(get_uuid(obj)) self.panel.refresh_plot( "selected", @@ -3304,10 +3356,14 @@ def delete_regions_of_interest(self) -> None: ) == QW.QMessageBox.Yes ): + removed_objs: list[TypeObj] = [] for obj in self.panel.objview.get_sel_objects(): if obj.roi is not None: obj.roi = None + removed_objs.append(obj) self.panel.selection_changed(update_items=True) + if removed_objs: + self._record_roi_mutation(_("Remove all ROIs"), removed_objs, None) def delete_single_roi(self, roi_index: int) -> None: """Delete a single ROI by index @@ -3332,4 +3388,7 @@ def delete_single_roi(self, roi_index: int) -> None: if len(obj.roi.single_rois) == 0: obj.roi = None obj.mark_roi_as_changed() + self._record_roi_mutation( + _("Remove ROI '%s'") % roi_title, [obj], obj.roi + ) self.panel.selection_changed(update_items=True) diff --git a/datalab/history/action.py b/datalab/history/action.py index 42a33c4bf..c87a10f96 100644 --- a/datalab/history/action.py +++ b/datalab/history/action.py @@ -18,6 +18,7 @@ Dict, Generator, Generic, + List, Optional, TypeVar, overload, @@ -26,12 +27,13 @@ import sigima.proc.image import sigima.proc.signal -from guidata.dataset.datatypes import DataSet +from guidata.dataset.datatypes import DataSet, DataSetGroup +from datalab.config import _ +from datalab.env import execenv from datalab.gui import ObjItf from datalab.history.core import ( HISTORY_ACTION_SCHEMA_VERSION, - HISTORY_SCHEMA_VERSION, copy_history_value, decode_kwargs, encode_kwargs, @@ -90,6 +92,11 @@ class HistoryAction(ObjItf): KIND_COMPUTE = "compute" KIND_UI = "ui" + # Mutation actions describe in-place modifications of existing data objects + # (no new objects created), e.g. ROI assignment/removal. + KIND_MUTATION = "mutation" + # Mutation keys currently supported by ``replay_mutation``. + SUPPORTED_MUTATION_KEYS: frozenset[str] = frozenset({"roi"}) FUNC_EDIT_MODE = "edit" # Name of the function parameter to enable edit mode # Object-creation actions skipped during non-persistent (output-suppressed) @@ -112,6 +119,9 @@ class Descriptors: target: str | None = None method_name: str | None = None plugin_origin: dict[str, Any] | None = None + # Mutation-only descriptors (``kind == KIND_MUTATION``): + mutation_key: str | None = None + target_uuids: list[str] | None = None kind = DescriptorField[str]("kind") panel_str = DescriptorField[Optional[str]]("panel_str") @@ -120,6 +130,8 @@ class Descriptors: target = DescriptorField[Optional[str]]("target") method_name = DescriptorField[Optional[str]]("method_name") plugin_origin = DescriptorField[Optional[Dict[str, Any]]]("plugin_origin") + mutation_key = DescriptorField[Optional[str]]("mutation_key") + target_uuids = DescriptorField[Optional[List[str]]]("target_uuids") def __init__( self, @@ -132,6 +144,9 @@ def __init__( # --- ui-only ------------------------------------------------------- target: str | None = None, method_name: str | None = None, + # --- mutation-only --------------------------------------------------- + mutation_key: str | None = None, + target_uuids: list[str] | None = None, # --- common -------------------------------------------------------- kwargs: dict[str, Any] | None = None, state: WorkspaceState | None = None, @@ -145,6 +160,8 @@ def __init__( pattern=pattern, target=target, method_name=method_name, + mutation_key=mutation_key, + target_uuids=target_uuids, ) # Common: self.kwargs: dict[str, Any] = ( @@ -167,6 +184,11 @@ def __init__( # ``add_compute_entry_from_pp``. See # :func:`datalab.gui.processor.base._detect_plugin_origin` for shape. # Persisted as a JSON string in HDF5. + + # Analysis effects manifest, keyed by source object UUID, values are + # ``AnalysisEffects.to_dict()`` payloads. Persisted as a JSON string. + # Only populated for 1_to_0 compute actions, None otherwise. + self.effects: dict[str, dict] | None = None # Transient flag (NOT serialized): set during a cascade recompute to # display a "stale" visual marker in the tree. Cleared once the # action has been recomputed. @@ -219,6 +241,8 @@ def copy(self, title_suffix: str | None = None) -> HistoryAction: pattern=self.pattern, target=self.target, method_name=self.method_name, + mutation_key=self.mutation_key, + target_uuids=list(self.target_uuids) if self.target_uuids else None, kwargs={ key: copy_history_value(value) for key, value in self.kwargs.items() }, @@ -226,6 +250,7 @@ def copy(self, title_suffix: str | None = None) -> HistoryAction: ) new_action.plugin_origin = copy_history_value(self.plugin_origin) new_action.output_uuids = list(self.output_uuids) + new_action.effects = copy_history_value(self.effects) # Note: saved_kwargs is intentionally NOT propagated to the copy. # Copying an action acts as an implicit commit (no pending edits). return new_action @@ -290,6 +315,18 @@ def copy_with_uuid_remap( pstr = new_action.effective_panel_str() pmap = uuid_remap.get(pstr, {}) new_action.output_uuids = [pmap.get(u, u) for u in new_action.output_uuids] + # Rewrite target_uuids — mutated objects live in the target panel. + if new_action.target_uuids: + pstr = new_action.effective_panel_str() + pmap = uuid_remap.get(pstr, {}) + new_action.target_uuids = [pmap.get(u, u) for u in new_action.target_uuids] + # Rewrite effects keys — they reference source objects in the target panel. + if new_action.effects: + pstr = new_action.effective_panel_str() + pmap = uuid_remap.get(pstr, {}) + new_action.effects = { + pmap.get(u, u): payload for u, payload in new_action.effects.items() + } return new_action @property @@ -408,15 +445,31 @@ def description_html(self) -> str: # Workspace-state delegation # ------------------------------------------------------------------ + def __roi_exclusions(self) -> set[str] | None: + """Return the target UUIDs to exclude from ROI comparison, or None. + + Mutation states are captured after the mutation was applied, so the + targets' ROI signatures cannot be expected to match at replay time. + """ + if self.kind == self.KIND_MUTATION: + return set(self.target_uuids or []) + return None + def is_current_state_compatible( self, mainwindow: DLMainWindow, restore_selection: bool ) -> bool: - """Check if the current workspace state is compatible with the saved state.""" - return self.state.is_current_state_compatible(mainwindow, restore_selection) + """Check if the current workspace state is compatible with the saved state. + + Mutation actions exclude their own targets from the ROI signature + comparison (the recorded state contains the post-mutation ROI). + """ + return self.state.is_current_state_compatible( + mainwindow, restore_selection, ignore_roi_uuids=self.__roi_exclusions() + ) def restore(self, mainwindow: DLMainWindow) -> None: """Restore the associated workspace state.""" - self.state.restore(mainwindow) + self.state.restore(mainwindow, ignore_roi_uuids=self.__roi_exclusions()) # ------------------------------------------------------------------ # Replay @@ -448,7 +501,7 @@ def replay( restore_selection: bool, edit: bool, ) -> None: - """Replay a UI-kind action. + """Replay a UI-kind or mutation-kind action. Compute-kind actions are recomputed in place by the History panel engine (see :mod:`datalab.gui.panel.history.recompute`) and must never @@ -479,8 +532,80 @@ def replay( ctx = nullcontext() with ctx: if restore_selection: - self.state.restore(mainwindow) - self.replay_ui(mainwindow, edit) + self.restore(mainwindow) + if self.kind == self.KIND_MUTATION: + self.replay_mutation(mainwindow, edit=edit) + else: + self.replay_ui(mainwindow, edit) + + def replay_mutation( + self, mainwindow: DLMainWindow, edit: bool = False, refresh: bool = True + ) -> list[str]: + """Replay a mutation-kind action: re-apply the in-place modification. + + Only ``mutation_key == "roi"`` is supported: the ROI payload (or None + for a deletion) is re-applied to each target object still present in + the data panel's object model. + + Args: + mainwindow: DataLab's main window + edit: If True (and not in unattended mode), open the ROI parameter + dialog before applying so the recorded payload can be modified. + Deletion payloads (None) have nothing to edit and are applied + directly. If the dialog is cancelled, the recorded payload is + applied as-is. + refresh: If True (default), refresh the panel selection and plot + after applying the mutation. The cascade engine passes False as + it refreshes each target itself. + + Returns: + UUIDs of the target objects that were mutated (empty list when + the mutation could not be applied to any object). + """ + if self.mutation_key not in self.SUPPORTED_MUTATION_KEYS: + _logger.warning( + "Skipping mutation replay: unsupported mutation key %r", + self.mutation_key, + ) + return [] + panel_str = self.effective_panel_str() + if panel_str == "signal": + panel_data = mainwindow.signalpanel + elif panel_str == "image": + panel_data = mainwindow.imagepanel + else: + _logger.warning("Skipping mutation replay: unknown panel %r", panel_str) + return [] + # A missing "payload" kwarg means None (ROI deletion): encode_kwargs + # skips None values, so deletion payloads are simply not persisted. + payload = self.kwargs.get("payload") + targets = [ + uuid + for uuid in self.target_uuids or [] + if panel_data.objmodel.has_uuid(uuid) + ] + if not targets: + return [] + if edit and payload is not None and not execenv.unattended: + # Edit mode: let the user adjust the ROI payload before applying. + obj = panel_data.objmodel[targets[0]] + params = payload.to_params(obj) + group = DataSetGroup(params, title=_("Regions of Interest")) + if group.edit(parent=mainwindow): + payload = payload.__class__.from_params(obj, params) + self.snapshot_kwargs() + self.kwargs["payload"] = payload + for uuid in targets: + obj = panel_data.objmodel[uuid] + obj.roi = payload.copy() if payload is not None else None + if hasattr(obj, "mark_roi_as_changed"): + obj.mark_roi_as_changed() + if refresh: + panel_data.selection_changed(update_items=True) + panel_data.refresh_plot( + "selected", update_items=True, only_visible=False, only_existing=True + ) + return targets def replay_ui( self, @@ -565,6 +690,13 @@ def serialize(self, writer: NativeH5Writer) -> None: if self.method_name is not None: with writer.group("method_name"): writer.write(self.method_name) + if self.mutation_key is not None: + with writer.group("mutation_key"): + writer.write(self.mutation_key) + # Like ``output_uuids``: only emit when non-empty. + if self.target_uuids: + with writer.group("target_uuids"): + writer.write(list(self.target_uuids)) encoded = encode_kwargs(self.kwargs) if encoded: with writer.group("kwargs"): @@ -588,6 +720,11 @@ def serialize(self, writer: NativeH5Writer) -> None: if self.plugin_origin is not None: with writer.group("plugin_origin"): writer.write(json.dumps(self.plugin_origin)) + # ``effects``: analysis effects manifest (1_to_0 compute actions only), + # stored as a JSON string. Skipped when None. + if self.effects is not None: + with writer.group("effects"): + writer.write(json.dumps(self.effects)) with writer.group("state"): self.state.serialize(writer) with writer.group("dtstr"): @@ -595,9 +732,8 @@ def serialize(self, writer: NativeH5Writer) -> None: def deserialize(self, reader: NativeH5Reader) -> None: """Deserialize this action.""" - self.schema_version = reader.read( - "schema_version", default=HISTORY_SCHEMA_VERSION - ) + # Legacy files predate per-action schema versions: default to 1 + self.schema_version = reader.read("schema_version", default=1) with reader.group("kind"): self.kind = reader.read_any() with reader.group("title"): @@ -628,12 +764,29 @@ def deserialize_descriptors( loaded_uuid = reader.read_any() if loaded_uuid: action.uuid = str(loaded_uuid) - for attr in ("panel_str", "func_name", "pattern", "target", "method_name"): + for attr in ( + "panel_str", + "func_name", + "pattern", + "target", + "method_name", + "mutation_key", + ): if attr in current.attrs or attr in current: with reader.group(attr): setattr(action, attr, reader.read_any()) else: setattr(action, attr, None) + # ``target_uuids`` is serialized only when non-empty (mutation actions); + # legacy files and non-mutation actions leave it as ``None``. + if "target_uuids" in current.attrs or "target_uuids" in current: + with reader.group("target_uuids"): + raw_targets = reader.read_any() + action.target_uuids = ( + [str(u) for u in raw_targets] if raw_targets is not None else None + ) + else: + action.target_uuids = None def deserialize_kwargs_snapshot( @@ -659,7 +812,7 @@ def deserialize_kwargs_snapshot( def deserialize_outputs_plugin_origin( action: HistoryAction, reader: NativeH5Reader, current: Any ) -> None: - """Deserialize optional outputs and plugin provenance.""" + """Deserialize optional outputs, plugin provenance and effects manifest.""" # ``output_uuids`` is serialized only when non-empty. Outputless actions and # legacy files without this field leave it empty, so consumers fall back to # the heuristic matcher. @@ -692,3 +845,21 @@ def deserialize_outputs_plugin_origin( action.plugin_origin = None else: action.plugin_origin = None + # ``effects`` is present only for 1_to_0 compute actions written with + # action schema v2+; legacy files leave it as ``None``. + if "effects" in current.attrs or "effects" in current: + with reader.group("effects"): + raw_effects = reader.read_any() + if raw_effects in (None, ""): + action.effects = None + else: + try: + action.effects = json.loads(raw_effects) + except (TypeError, ValueError): + _logger.warning( + "Failed to decode effects for action %s; falling back to None.", + action.uuid, + ) + action.effects = None + else: + action.effects = None diff --git a/datalab/history/core.py b/datalab/history/core.py index 3737f1a4a..5fe370dc1 100644 --- a/datalab/history/core.py +++ b/datalab/history/core.py @@ -24,11 +24,13 @@ _logger = logging.getLogger(__name__) _TRUSTED_ROI_MODULE_PREFIX = "sigima." -# Schema versions for persisted history sessions/actions. Both start at 1. +# Schema versions for persisted history sessions/actions. # Bump the relevant constant (and add the corresponding optional field # handling in serialize/deserialize) when the on-disk layout evolves. +# Action schema v2: optional ``effects`` manifest for 1_to_0 compute actions, +# and optional mutation descriptors (``mutation_key``/``target_uuids``). HISTORY_SCHEMA_VERSION = 1 -HISTORY_ACTION_SCHEMA_VERSION = 1 +HISTORY_ACTION_SCHEMA_VERSION = 2 # Keys used in the kwargs dict to mark DataSet payloads, so that the # serialization layer can round-trip them as JSON strings instead of pickling # arbitrary Python objects. diff --git a/datalab/history/effects.py b/datalab/history/effects.py new file mode 100644 index 000000000..3cdec6890 --- /dev/null +++ b/datalab/history/effects.py @@ -0,0 +1,155 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +"""Analysis effects manifest: capture metadata/ROI mutations of 1-to-0 analyses.""" + +from __future__ import annotations + +from contextlib import contextmanager +from dataclasses import dataclass, field +from typing import Any, Generator + +import numpy as np +from sigima.objects.base import ROI_KEY + +# Private bookkeeping keys excluded from the metadata diff (ROI changes are +# tracked separately through ``roi_modified``, not the metadata diff) +EXCLUDED_METADATA_KEYS = frozenset({"__uuid", "__number", ROI_KEY}) + + +@dataclass +class AnalysisEffects: + """Manifest of the side effects produced by a 1-to-0 analysis on one object. + + Attributes: + metadata_added: Metadata keys created by the analysis. + metadata_replaced: Pre-existing metadata keys whose value changed. + roi_modified: True when the analysis created or changed the object's ROI. + """ + + metadata_added: list[str] = field(default_factory=list) + metadata_replaced: list[str] = field(default_factory=list) + roi_modified: bool = False + + def to_dict(self) -> dict[str, Any]: + """Return a JSON-safe dictionary representation. + + Returns: + Dictionary suitable for ``json.dumps`` round-trip. + """ + return { + "metadata_added": list(self.metadata_added), + "metadata_replaced": list(self.metadata_replaced), + "roi_modified": bool(self.roi_modified), + } + + @classmethod + def from_dict(cls, data: dict[str, Any]) -> AnalysisEffects: + """Build an instance from a dictionary produced by :meth:`to_dict`. + + Args: + data: Dictionary payload (missing fields fall back to defaults). + + Returns: + New :class:`AnalysisEffects` instance. + """ + return cls( + metadata_added=list(data.get("metadata_added", [])), + metadata_replaced=list(data.get("metadata_replaced", [])), + roi_modified=bool(data.get("roi_modified", False)), + ) + + +def safe_equal(value1: Any, value2: Any) -> bool: + """Return True if both values compare equal, tolerating numpy arrays. + + Numpy arrays are compared with :func:`numpy.array_equal`. Any comparison + failure is treated as "changed" (returns False). + + Args: + value1: First value. + value2: Second value. + + Returns: + True if values are considered equal. + """ + if isinstance(value1, np.ndarray) or isinstance(value2, np.ndarray): + try: + return bool(np.array_equal(value1, value2)) + except (TypeError, ValueError): + return False + try: + return bool(value1 == value2) + except Exception: # pylint: disable=broad-except + return False + + +def merge_effects( + previous: AnalysisEffects | None, new: AnalysisEffects +) -> AnalysisEffects: + """Merge a freshly captured manifest into the previous one. + + Keys produced on the first run stay in ``metadata_added`` even though a + recompute observes them as replaced (the analysis owns them for their + whole lifetime). ``roi_modified`` is sticky: once an execution touched + the ROI, the merged manifest keeps the flag. Output lists are sorted for + deterministic ordering. + + Args: + previous: Manifest from earlier executions, or None on first merge. + new: Manifest captured during the latest execution. + + Returns: + Merged :class:`AnalysisEffects` instance. + """ + if previous is None: + return AnalysisEffects( + metadata_added=sorted(new.metadata_added), + metadata_replaced=sorted(new.metadata_replaced), + roi_modified=new.roi_modified, + ) + added = set(previous.metadata_added) | set(new.metadata_added) + replaced = (set(previous.metadata_replaced) | set(new.metadata_replaced)) - added + return AnalysisEffects( + metadata_added=sorted(added), + metadata_replaced=sorted(replaced), + roi_modified=previous.roi_modified or new.roi_modified, + ) + + +@contextmanager +def capture_effects(obj: Any) -> Generator[AnalysisEffects, None, None]: + """Capture metadata and ROI mutations applied to an object. + + Snapshots the object's metadata keys/values and ROI before yielding, then + fills the yielded :class:`AnalysisEffects` instance on exit. Private + bookkeeping keys (``__uuid``, ``__number``) and the ROI metadata key are + excluded from the diff. + + Args: + obj: Signal or image object whose ``metadata`` and ``roi`` are watched. + + Yields: + Mutable :class:`AnalysisEffects` instance, filled on exit. + """ + before = { + key: value + for key, value in obj.metadata.items() + if key not in EXCLUDED_METADATA_KEYS + } + roi_before = obj.roi.copy() if obj.roi is not None else None + effects = AnalysisEffects() + try: + yield effects + finally: + after = { + key: value + for key, value in obj.metadata.items() + if key not in EXCLUDED_METADATA_KEYS + } + effects.metadata_added = sorted(set(after) - set(before)) + effects.metadata_replaced = sorted( + key + for key in set(before) & set(after) + if not safe_equal(before[key], after[key]) + ) + effects.roi_modified = not safe_equal(roi_before, obj.roi) diff --git a/datalab/history/workspace_state.py b/datalab/history/workspace_state.py index f99391b1d..7cd798aa0 100644 --- a/datalab/history/workspace_state.py +++ b/datalab/history/workspace_state.py @@ -4,9 +4,12 @@ from __future__ import annotations +import hashlib +import json from copy import deepcopy from typing import TYPE_CHECKING, Any +from datalab.history.core import numpy_to_json_safe from datalab.objectmodel import get_uuid if TYPE_CHECKING: @@ -110,6 +113,29 @@ def get_current_selection(self, mainwindow: DLMainWindow) -> dict[str, list[str] ] return selection + @staticmethod + def get_roi_signature(obj: Any) -> str | None: + """Return a short stable hash of the object's ROI, or None. + + Args: + obj: Signal or image object (any object exposing a ``roi`` + attribute with a ``to_dict()`` method). + + Returns: + 16-character hex digest of the JSON-encoded ROI, or ``None`` + when the object has no ROI or its encoding fails. + """ + roi = getattr(obj, "roi", None) + if roi is None: + return None + try: + payload = numpy_to_json_safe(roi.to_dict()) + serialized = json.dumps(payload, sort_keys=True) + except (AttributeError, TypeError, ValueError): + # Defensive: ROI classes evolve; omit signature on failure. + return None + return hashlib.sha1(serialized.encode()).hexdigest()[:16] + @staticmethod def get_object_metadata(obj: Any) -> dict[str, Any]: """Return a stable data signature for an object.""" @@ -119,7 +145,11 @@ def get_object_metadata(obj: Any) -> dict[str, Any]: return {} shape = [int(size) for size in shape] ndim = getattr(data, "ndim", len(shape)) - return {"shape": shape, "ndim": int(ndim)} + metadata: dict[str, Any] = {"shape": shape, "ndim": int(ndim)} + roi_signature = WorkspaceState.get_roi_signature(obj) + if roi_signature is not None: + metadata["roi"] = roi_signature + return metadata @staticmethod def normalize_object_metadata(metadata: dict[str, Any]) -> dict[str, Any]: @@ -129,7 +159,11 @@ def normalize_object_metadata(metadata: dict[str, Any]) -> dict[str, Any]: return {} shape = [int(size) for size in shape] ndim = metadata.get("ndim", len(shape)) - return {"shape": shape, "ndim": int(ndim)} + normalized: dict[str, Any] = {"shape": shape, "ndim": int(ndim)} + roi = metadata.get("roi") + if roi is not None: + normalized["roi"] = str(roi) + return normalized # Mapping from legacy translated panel keys to stable identifiers. # Covers the English translations; other locales are handled by the @@ -205,21 +239,30 @@ def save(self, mainwindow: DLMainWindow, panel_str: str | None = None) -> None: } def is_current_state_compatible( # pylint: disable=unused-argument - self, mainwindow: DLMainWindow, restore_selection: bool + self, + mainwindow: DLMainWindow, + restore_selection: bool, + ignore_roi_uuids: set[str] | None = None, ) -> bool: """Check if the current workspace state is compatible with the saved state. Compatibility means that **every** UUID recorded in the saved selection still exists in the corresponding panel. When structured object metadata - is available (current schema), each selected object's data shape and - dimensions must also match the saved signature. Histories without this - metadata fall back to legacy UUID-existence validation. + is available (current schema), each selected object's data shape, + dimensions and ROI signature (when recorded) must also match the saved + signature. Histories without this metadata fall back to legacy + UUID-existence validation; metadata recorded before ROI signatures + existed skips the ROI comparison. Args: mainwindow: DataLab's main window restore_selection: Unused (kept for API symmetry). With UUID-based identity, the compatibility check no longer depends on the current selection -- it only depends on object existence. + ignore_roi_uuids: UUIDs whose ROI signature must be excluded from + the comparison (both saved and current sides). Used by mutation + actions whose state was captured after the mutation was applied: + the target's ROI legitimately differs at replay time. Returns: True if every saved UUID still exists in its panel and saved @@ -238,15 +281,28 @@ def is_current_state_compatible( # pylint: disable=unused-argument current = self.get_object_metadata(panel.objmodel[uuid]) current = self.normalize_object_metadata(current) saved = self.normalize_object_metadata(saved_metadata[uuid]) + if ignore_roi_uuids and uuid in ignore_roi_uuids: + # Mutation target: the ROI is precisely what the + # action changes, exclude it from both sides. + current.pop("roi", None) + saved.pop("roi", None) + elif "roi" not in saved: + # Legacy tolerance: states recorded before the ROI + # signature existed must not flag incompatibility. + current.pop("roi", None) if saved and current != saved: return False return True - def restore(self, mainwindow: DLMainWindow) -> None: + def restore( + self, mainwindow: DLMainWindow, ignore_roi_uuids: set[str] | None = None + ) -> None: """Restore the workspace state by selecting the recorded UUIDs. Args: mainwindow: DataLab's main window + ignore_roi_uuids: UUIDs whose ROI signature is excluded from the + compatibility check (see :meth:`is_current_state_compatible`). Raises: ValueError: If a saved UUID no longer exists in its panel or its @@ -254,7 +310,9 @@ def restore(self, mainwindow: DLMainWindow) -> None: """ if not self.selection: return - if not self.is_current_state_compatible(mainwindow, False): + if not self.is_current_state_compatible( + mainwindow, False, ignore_roi_uuids=ignore_roi_uuids + ): raise ValueError( "Current workspace state is not compatible with saved state" ) diff --git a/datalab/locale/fr/LC_MESSAGES/datalab.po b/datalab/locale/fr/LC_MESSAGES/datalab.po index fbfa2f9e6..844d1d3fd 100644 --- a/datalab/locale/fr/LC_MESSAGES/datalab.po +++ b/datalab/locale/fr/LC_MESSAGES/datalab.po @@ -4256,6 +4256,22 @@ msgstr "Fichiers d'historique" msgid "Action %s has been edited but its target output object(s) no longer exist — skipping." msgstr "L'action %s a été modifiée mais son ou ses objets de sortie cibles n'existent plus — ignorée." +#, python-format +msgid "Action %s: target panel not found — skipping." +msgstr "Action %s : panneau cible introuvable — ignorée." + +#, python-format +msgid "Action %s: no recorded mutation target — skipping." +msgstr "Action %s : aucune cible de mutation enregistrée — ignorée." + +#, python-format +msgid "Action %s: target object(s) no longer exist — skipping." +msgstr "Action %s : le ou les objets cibles n'existent plus — ignorée." + +#, python-format +msgid "Action %s: %d target object(s) were deleted — applying to the rest." +msgstr "Action %s : %d objet(s) cible(s) ont été supprimés — appliquée aux autres." + #, python-format msgid "Action %s uses pattern %r which is not recomputable yet." msgstr "L'action %s utilise le motif %r qui n'est pas encore recalculable." @@ -4361,6 +4377,10 @@ msgstr "Nouvelle image" msgid "New signal" msgstr "Nouveau signal" +#, python-format +msgid "Remove ROI '%s'" +msgstr "Supprimer la ROI '%s'" + msgid "History sessions" msgstr "Sessions d'historique" @@ -4443,4 +4463,3 @@ msgstr "Image" msgid "Dimensions" msgstr "Dimensions" - diff --git a/datalab/tests/features/common/adapters_registry_unit_test.py b/datalab/tests/features/common/adapters_registry_unit_test.py new file mode 100644 index 000000000..8fb90a446 --- /dev/null +++ b/datalab/tests/features/common/adapters_registry_unit_test.py @@ -0,0 +1,135 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +""" +Adapters registry unit test +--------------------------- + +Test the generic result-adapter resolver of :mod:`datalab.adapters_metadata`: +resolution of registered result typologies, subclass tolerance, error on +unsupported types and the public registration hook +(:func:`datalab.adapters_metadata.register_result_adapter`). +""" + +# pylint: disable=invalid-name # Allows short reference names like x, y, ... + +from __future__ import annotations + +import numpy as np +import pytest +from sigima.objects.scalar import GeometryResult, KindShape, TableResult + +from datalab.adapters_metadata import ( + GeometryAdapter, + TableAdapter, + create_adapter, + register_result_adapter, +) +from datalab.adapters_metadata.common import _ADAPTER_REGISTRY +from datalab.env import execenv + + +def make_geometry_result(cls: type[GeometryResult] = GeometryResult) -> GeometryResult: + """Build a minimal segment geometry result. + + Args: + cls: Result class to instantiate (allows building subclasses). + + Returns: + Geometry result instance. + """ + return cls( + title="fwhm", + func_name="fwhm", + kind=KindShape.SEGMENT, + coords=np.array([[3.5, 0.6, 6.5, 0.6]]), + roi_indices=None, + attrs={}, + ) + + +def make_table_result() -> TableResult: + """Build a minimal statistics table result.""" + return TableResult( + title="stats", + func_name="stats", + headers=["Mean", "Std"], + data=[[5.0, 1.5]], + roi_indices=None, + attrs={}, + ) + + +def test_create_adapter_resolves_registered_typologies() -> None: + """Resolve GeometryResult and TableResult to their respective adapters.""" + geometry_adapter = create_adapter(make_geometry_result()) + assert type(geometry_adapter) is GeometryAdapter + table_adapter = create_adapter(make_table_result()) + assert type(table_adapter) is TableAdapter + execenv.print("test_create_adapter_resolves_registered_typologies: ✓") + + +def test_create_adapter_rejects_unsupported_type() -> None: + """Raise TypeError naming the unsupported result type.""" + with pytest.raises(TypeError, match="dict"): + create_adapter({"not": "a result"}) + execenv.print("test_create_adapter_rejects_unsupported_type: ✓") + + +def test_create_adapter_falls_back_to_isinstance() -> None: + """Resolve an unregistered subclass through the isinstance fallback.""" + + class CustomGeometryResult(GeometryResult): + """Subclass without a dedicated adapter registration.""" + + adapter = create_adapter(make_geometry_result(CustomGeometryResult)) + assert type(adapter) is GeometryAdapter + execenv.print("test_create_adapter_falls_back_to_isinstance: ✓") + + +def test_register_result_adapter_custom_typology() -> None: + """Register a custom adapter and resolve the custom typology exactly.""" + + class CustomGeometryResult(GeometryResult): + """Custom result typology (e.g. contributed by a plugin).""" + + class CustomAdapter(GeometryAdapter): + """Adapter dedicated to the custom typology.""" + + register_result_adapter(CustomGeometryResult, CustomAdapter) + try: + adapter = create_adapter(make_geometry_result(CustomGeometryResult)) + assert type(adapter) is CustomAdapter + # Base typology resolution is unaffected by the extra registration + assert type(create_adapter(make_geometry_result())) is GeometryAdapter + finally: + _ADAPTER_REGISTRY.pop(CustomGeometryResult, None) + execenv.print("test_register_result_adapter_custom_typology: ✓") + + +def test_create_adapter_fallback_prefers_most_specific_base() -> None: + """Resolve an unregistered sub-subclass to the most specific adapter.""" + + class CustomGeometryResult(GeometryResult): + """Custom result typology with its own registered adapter.""" + + class CustomAdapter(GeometryAdapter): + """Adapter dedicated to the custom typology.""" + + class UnregisteredSubResult(CustomGeometryResult): + """Sub-subclass without a dedicated adapter registration.""" + + register_result_adapter(CustomGeometryResult, CustomAdapter) + try: + adapter = create_adapter(make_geometry_result(UnregisteredSubResult)) + assert type(adapter) is CustomAdapter + finally: + _ADAPTER_REGISTRY.pop(CustomGeometryResult, None) + execenv.print("test_create_adapter_fallback_prefers_most_specific_base: ✓") + + +if __name__ == "__main__": + test_create_adapter_resolves_registered_typologies() + test_create_adapter_rejects_unsupported_type() + test_create_adapter_falls_back_to_isinstance() + test_register_result_adapter_custom_typology() + test_create_adapter_fallback_prefers_most_specific_base() diff --git a/datalab/tests/features/common/analysis_parameters_edit_unit_test.py b/datalab/tests/features/common/analysis_parameters_edit_unit_test.py index caad812f5..bf93547de 100644 --- a/datalab/tests/features/common/analysis_parameters_edit_unit_test.py +++ b/datalab/tests/features/common/analysis_parameters_edit_unit_test.py @@ -80,4 +80,5 @@ def test_analysis_parameters_edit_image(): if __name__ == "__main__": + execenv.unattended = True # Auto-close dialogs and event loops (standalone run) test_analysis_parameters_edit_image() diff --git a/datalab/tests/features/common/history_effects_unit_test.py b/datalab/tests/features/common/history_effects_unit_test.py new file mode 100644 index 000000000..758cbe743 --- /dev/null +++ b/datalab/tests/features/common/history_effects_unit_test.py @@ -0,0 +1,263 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +""" +History effects unit test +------------------------- + +Test the analysis effects manifest (:mod:`datalab.history.effects`): +capture of metadata/ROI mutations during 1-to-0 analyses, persistence on +:class:`HistoryAction` and HDF5 round-trip (action schema v2). +""" + +# pylint: disable=invalid-name # Allows short reference names like x, y, ... +# guitest: show + +from __future__ import annotations + +import copy +import os +import tempfile +from unittest.mock import patch + +import numpy as np +import sigima.params as sigima_param +from sigima.objects import Gauss2DParam, create_image_from_param, create_image_roi +from sigima.tests.data import create_peak_image + +from datalab.config import Conf +from datalab.env import execenv +from datalab.gui.panel.history import recompute as hrec +from datalab.h5.native import NativeH5Writer +from datalab.history.effects import AnalysisEffects, capture_effects, merge_effects +from datalab.history.session import HistorySession +from datalab.objectmodel import get_uuid +from datalab.tests import datalab_test_app_context +from datalab.tests.features.common.history_test_helpers import ( + build_history_action, + delete_hdf5_items_by_name, + read_history_sessions, +) + + +def test_capture_effects_metadata_diff() -> None: + """Capture added/replaced metadata keys, excluding bookkeeping keys.""" + obj = create_image_from_param(Gauss2DParam.create(height=16, width=16)) + obj.metadata["untouched"] = 1 + obj.metadata["changed_scalar"] = 5 + obj.metadata["changed_array"] = np.arange(3) + with capture_effects(obj) as effects: + obj.metadata["new_key"] = "hello" + obj.metadata["changed_scalar"] = 6 + obj.metadata["changed_array"] = np.arange(4) + obj.metadata["__uuid"] = "synthetic-uuid" + obj.metadata["__number"] = 42 + assert effects.metadata_added == ["new_key"] + assert effects.metadata_replaced == ["changed_array", "changed_scalar"] + assert "untouched" not in effects.metadata_added + assert "untouched" not in effects.metadata_replaced + assert "__uuid" not in effects.metadata_added + assert "__number" not in effects.metadata_added + assert effects.roi_modified is False + execenv.print("test_capture_effects_metadata_diff: ✓") + + +def test_capture_effects_roi_modified() -> None: + """Detect ROI creation inside the capture window.""" + obj = create_image_from_param(Gauss2DParam.create(height=16, width=16)) + with capture_effects(obj) as effects: + pass + assert effects.roi_modified is False + with capture_effects(obj) as effects: + obj.roi = create_image_roi("rectangle", [2, 2, 5, 5]) + assert effects.roi_modified is True + execenv.print("test_capture_effects_roi_modified: ✓") + + +def test_analysis_effects_dict_round_trip() -> None: + """Round-trip AnalysisEffects through to_dict/from_dict.""" + effects = AnalysisEffects( + metadata_added=["Geometry_peak_detection_dict"], + metadata_replaced=["analysis_parameters"], + roi_modified=True, + ) + payload = effects.to_dict() + assert payload == { + "metadata_added": ["Geometry_peak_detection_dict"], + "metadata_replaced": ["analysis_parameters"], + "roi_modified": True, + } + assert AnalysisEffects.from_dict(payload) == effects + assert AnalysisEffects.from_dict({}) == AnalysisEffects() + execenv.print("test_analysis_effects_dict_round_trip: ✓") + + +def test_analysis_effects_populated_by_1_to_0_compute() -> None: + """Populate the action effects manifest through a real 1-to-0 analysis.""" + with datalab_test_app_context(console=False, history=True) as win: + execenv.print("History effects integration test (image peak detection):") + history = win.historypanel + history.toggle_record_mode(True) + panel = win.imagepanel + img = create_peak_image() + panel.add_object(img) + + det_param = sigima_param.Peak2DDetectionParam.create( + create_rois=True, threshold=0.5 + ) + with Conf.proc.show_result_dialog.temp(False): + panel.processor.run_feature("peak_detection", det_param) + + action = history[len(history)] + assert action.effects is not None, "1-to-0 action must carry effects" + src_uuid = get_uuid(img) + assert src_uuid in action.effects + manifest = AnalysisEffects.from_dict(action.effects[src_uuid]) + assert any( + key.startswith("Geometry_") and key.endswith("_dict") + for key in manifest.metadata_added + ), f"Expected a Geometry_*_dict key, got {manifest.metadata_added}" + assert manifest.roi_modified is True, "Detection ROIs must flag roi_modified" + execenv.print(" ✓ Effects manifest populated with source uuid and keys") + + +def test_merge_effects() -> None: + """Merge manifests: added-stays-added, sticky roi_modified, sorted output.""" + new = AnalysisEffects( + metadata_added=["b", "a"], metadata_replaced=["c"], roi_modified=False + ) + merged = merge_effects(None, new) + assert merged == AnalysisEffects(["a", "b"], ["c"], False) + # Keys created on the first run stay "added" even though a recompute + # observes them as replaced + previous = AnalysisEffects(metadata_added=["result"], roi_modified=True) + recomputed = AnalysisEffects(metadata_replaced=["result", "params"]) + merged = merge_effects(previous, recomputed) + assert merged.metadata_added == ["result"] + assert merged.metadata_replaced == ["params"] + # roi_modified is sticky: True on first run stays True after a recompute + assert merged.roi_modified is True + execenv.print("test_merge_effects: ✓") + + +def test_recompute_updates_effects_manifest() -> None: + """Keep first-run keys under metadata_added after a history recompute.""" + with datalab_test_app_context(console=False, history=True) as win: + execenv.print("History effects recompute integration test:") + history = win.historypanel + history.toggle_record_mode(True) + panel = win.imagepanel + img = create_peak_image() + panel.add_object(img) + det_param = sigima_param.Peak2DDetectionParam.create( + create_rois=True, threshold=0.5 + ) + with Conf.proc.show_result_dialog.temp(False): + panel.processor.run_feature("peak_detection", det_param) + action = history[len(history)] + src_uuid = get_uuid(img) + added_before = AnalysisEffects.from_dict( + action.effects[src_uuid] + ).metadata_added + assert added_before, "First run must have recorded added keys" + + success = hrec.recompute_1_to_0_in_place(history, action) + + assert success is True + manifest = AnalysisEffects.from_dict(action.effects[src_uuid]) + assert set(added_before) <= set(manifest.metadata_added), ( + "First-run keys must stay under metadata_added after recompute" + ) + assert not set(added_before) & set(manifest.metadata_replaced) + execenv.print(" ✓ Manifest keys stayed 'added' after recompute") + + +def test_targeted_rollback_preserves_unrelated_metadata() -> None: + """Roll back only manifest keys when a manifest-driven recompute fails.""" + with datalab_test_app_context(console=False, history=True) as win: + execenv.print("History effects targeted rollback test:") + history = win.historypanel + history.toggle_record_mode(True) + panel = win.imagepanel + img = create_peak_image() + panel.add_object(img) + det_param = sigima_param.Peak2DDetectionParam.create( + create_rois=False, threshold=0.5 + ) + with Conf.proc.show_result_dialog.temp(False): + panel.processor.run_feature("peak_detection", det_param) + action = history[len(history)] + src_uuid = get_uuid(img) + manifest = AnalysisEffects.from_dict(action.effects[src_uuid]) + manifest_keys = manifest.metadata_added + manifest.metadata_replaced + geometry_key = next(key for key in manifest_keys if key.startswith("Geometry_")) + # Simulate a user having deleted one analysis result key beforehand + del img.metadata[geometry_key] + present_key = next(key for key in manifest_keys if key in img.metadata) + value_before = copy.deepcopy(img.metadata[present_key]) + img.metadata["user_marker"] = 123 + effects_before = copy.deepcopy(action.effects) + + def failing_recompute(_func_name, obj, _param, plugin_origin=None): + del plugin_origin + obj.metadata[geometry_key] = "recreated-by-failed-attempt" + obj.metadata[present_key] = "corrupted" + raise RuntimeError("forced recompute failure") + + with patch.object( + panel.processor, "recompute_1_to_0", side_effect=failing_recompute + ): + try: + hrec.recompute_1_to_0_in_place(history, action) + except RuntimeError: + pass + else: + raise AssertionError("RuntimeError should have propagated") + + assert img.metadata["user_marker"] == 123, "Unrelated key must be untouched" + assert geometry_key not in img.metadata, ( + "Manifest key absent before the recompute must be deleted on rollback" + ) + assert img.metadata[present_key] == value_before, ( + "Manifest key must be restored to its pre-recompute value" + ) + assert action.effects == effects_before, "Manifest must be unchanged" + execenv.print(" ✓ Targeted rollback restored only manifest keys") + + +def test_action_effects_hdf5_round_trip_and_legacy() -> None: + """Round-trip effects through HDF5 and tolerate legacy files without it.""" + action = build_history_action() + action.effects = { + "source-uuid": AnalysisEffects( + metadata_added=["Geometry_peak_detection_dict"], + metadata_replaced=["analysis_parameters"], + roi_modified=True, + ).to_dict() + } + session = HistorySession(number=1) + session.add_action(action) + with tempfile.TemporaryDirectory() as tmpdir: + path = os.path.join(tmpdir, "history.dlhist") + with NativeH5Writer(path) as writer: + writer.write_object_list([session], "history_session") + loaded = read_history_sessions(path)[0].actions[0] + assert loaded.effects == action.effects + # Legacy tolerance: files without the effects group deserialize to None + with NativeH5Writer(path) as writer: + writer.write_object_list([session], "history_session") + delete_hdf5_items_by_name(writer.h5, "effects") + legacy = read_history_sessions(path)[0].actions[0] + assert legacy.effects is None + execenv.print("test_action_effects_hdf5_round_trip_and_legacy: ✓") + + +if __name__ == "__main__": + execenv.unattended = True # Auto-close dialogs and event loops (standalone run) + test_capture_effects_metadata_diff() + test_capture_effects_roi_modified() + test_analysis_effects_dict_round_trip() + test_merge_effects() + test_analysis_effects_populated_by_1_to_0_compute() + test_recompute_updates_effects_manifest() + test_targeted_rollback_preserves_unrelated_metadata() + test_action_effects_hdf5_round_trip_and_legacy() diff --git a/datalab/tests/features/common/history_model_unit_test.py b/datalab/tests/features/common/history_model_unit_test.py index 18061917b..3cafa5be1 100644 --- a/datalab/tests/features/common/history_model_unit_test.py +++ b/datalab/tests/features/common/history_model_unit_test.py @@ -13,7 +13,8 @@ import numpy as np import pytest -from sigima.objects import Gauss2DParam, ImageObj +from sigima.objects import Gauss2DParam, ImageObj, create_signal_roi +from sigima.tests.data import create_paracetamol_signal from datalab.gui import historysession_ops as hsess from datalab.gui import historytools_ops as hops @@ -36,11 +37,13 @@ from datalab.h5.native import NativeH5Reader, NativeH5Writer from datalab.history.action import HistoryAction from datalab.history.core import HISTORY_ACTION_SCHEMA_VERSION, HISTORY_SCHEMA_VERSION +from datalab.history.effects import AnalysisEffects from datalab.history.session import HistorySession from datalab.history.workspace_state import WorkspaceState from datalab.objectmodel import get_uuid, set_uuid from datalab.tests.features.common.history_test_helpers import ( build_history_action, + build_workspace_state, delete_hdf5_items_by_name, read_history_sessions, ) @@ -812,6 +815,88 @@ def test_action_copy_remaps_all_uuid_references() -> None: assert action.plugin_origin["metadata"]["entry_points"] == ["difference"] +def _make_analysis_action(obj_uuid: str) -> HistoryAction: + """Build a 1-to-0 compute action analysing ``obj_uuid``.""" + return HistoryAction( + title="FWHM", + kind=HistoryAction.KIND_COMPUTE, + panel_str="signal", + func_name="fwhm", + pattern="1_to_0", + state=build_workspace_state([obj_uuid]), + ) + + +def test_find_analysis_action_two_pass_matching() -> None: + """Prefer the effects manifest, then fall back to the input-uuid heuristic.""" + obj_uuid = "analysed-uuid" + older = _make_analysis_action(obj_uuid) + newer = _make_analysis_action(obj_uuid) + session = HistorySession(number=1) + session.add_action(older) + session.add_action(newer) + panel = SimpleNamespace(history_sessions=[session]) + manifest = {obj_uuid: AnalysisEffects(metadata_added=["fwhm"]).to_dict()} + # Manifest pass: only the older action recorded effects for the object, + # so it wins over the more recent heuristic-only match + older.effects = manifest + assert hchain.find_analysis_action(panel, obj_uuid, "fwhm") is older + # Both actions carry a manifest: the most recent one wins + newer.effects = dict(manifest) + assert hchain.find_analysis_action(panel, obj_uuid, "fwhm") is newer + # Legacy pass: without any manifest, the input-uuid heuristic matches the + # most recent action + older.effects = None + newer.effects = None + assert hchain.find_analysis_action(panel, obj_uuid, "fwhm") is newer + # No match for another function name or another object + assert hchain.find_analysis_action(panel, obj_uuid, "fw1e2") is None + assert hchain.find_analysis_action(panel, "other-uuid", "fwhm") is None + + +def test_object_metadata_roi_signature_presence_and_stability() -> None: + """Expose a stable ROI signature and omit it for ROI-less objects.""" + obj = create_paracetamol_signal() + assert "roi" not in WorkspaceState.get_object_metadata(obj) + obj.roi = create_signal_roi([[10, 20]], indices=True) + signature = WorkspaceState.get_object_metadata(obj)["roi"] + obj.roi = create_signal_roi([[10, 20]], indices=True) + assert WorkspaceState.get_object_metadata(obj)["roi"] == signature + obj.roi = create_signal_roi([[15, 30]], indices=True) + assert WorkspaceState.get_object_metadata(obj)["roi"] != signature + + +def test_state_compatibility_handles_roi_signature_and_legacy_metadata() -> None: + """Tolerate legacy metadata without ROI key and flag ROI drift otherwise.""" + obj = create_paracetamol_signal() + obj.roi = create_signal_roi([[10, 20]], indices=True) + uuid = get_uuid(obj) + mainwindow = cast( + DLMainWindow, + SimpleNamespace( + signalpanel=SimpleNamespace( + PANEL_STR_ID="signal", objmodel=CascadeObjectModel([obj]) + ), + imagepanel=SimpleNamespace( + PANEL_STR_ID="image", objmodel=CascadeObjectModel([]) + ), + ), + ) + state = WorkspaceState() + state.selection = {"signal": [uuid]} + recorded = WorkspaceState.get_object_metadata(obj) + state.object_metadata = {"signal": {uuid: recorded}} + assert state.is_current_state_compatible(mainwindow, False) + # Legacy tolerance: metadata recorded without "roi" vs current object with ROI + legacy = dict(recorded) + del legacy["roi"] + state.object_metadata = {"signal": {uuid: legacy}} + assert state.is_current_state_compatible(mainwindow, False) + # ROI drift against a recorded signature flags incompatibility + state.object_metadata = {"signal": {uuid: dict(recorded, roi="0" * 16)}} + assert not state.is_current_state_compatible(mainwindow, False) + + def test_edited_image_creation_recomputes_downstream_in_place() -> None: """Regenerate an edited image before recomputing its existing descendant.""" initial_param = Gauss2DParam.create( diff --git a/datalab/tests/features/common/history_mutation_model_unit_test.py b/datalab/tests/features/common/history_mutation_model_unit_test.py new file mode 100644 index 000000000..fe582e260 --- /dev/null +++ b/datalab/tests/features/common/history_mutation_model_unit_test.py @@ -0,0 +1,89 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +"""Pure unit contracts for mutation-kind history actions.""" + +from __future__ import annotations + +import os +import tempfile + +from sigima.objects import SignalROI, create_signal_roi + +from datalab.h5.native import NativeH5Writer +from datalab.history.action import HistoryAction +from datalab.history.core import numpy_to_json_safe +from datalab.history.session import HistorySession +from datalab.tests.features.common.history_test_helpers import read_history_sessions + + +def roi_as_dict(roi: SignalROI) -> dict: + """Return a plain-Python (comparable) dict representation of a ROI.""" + return numpy_to_json_safe(roi.to_dict()) + + +def build_mutation_action(payload: SignalROI | None) -> HistoryAction: + """Build a ROI mutation action targeting two signal objects.""" + return HistoryAction( + title="Edit regions of interest", + kind=HistoryAction.KIND_MUTATION, + panel_str="signal", + mutation_key="roi", + target_uuids=["first-uuid", "second-uuid"], + kwargs={"payload": payload}, + ) + + +def roundtrip_action(action: HistoryAction) -> HistoryAction: + """Serialize an action to HDF5 and return its deserialized counterpart.""" + session = HistorySession(number=1) + session.add_action(action) + with tempfile.TemporaryDirectory() as tmpdir: + path = os.path.join(tmpdir, "history.dlhist") + with NativeH5Writer(path) as writer: + writer.write_object_list([session], "history_session") + return read_history_sessions(path)[0].actions[0] + + +def test_mutation_action_hdf5_roundtrip() -> None: + """Round-trip a ROI mutation action with its payload and identity fields.""" + payload = create_signal_roi([[26, 41], [125, 146]], indices=True) + action = build_mutation_action(payload) + loaded = roundtrip_action(action) + assert loaded.kind == HistoryAction.KIND_MUTATION + assert loaded.mutation_key == "roi" + assert loaded.target_uuids == ["first-uuid", "second-uuid"] + assert loaded.panel_str == "signal" + loaded_payload = loaded.kwargs.get("payload") + assert isinstance(loaded_payload, SignalROI) + assert type(loaded_payload) is type(payload) + assert roi_as_dict(loaded_payload) == roi_as_dict(payload) + + +def test_mutation_action_deletion_payload_roundtrip() -> None: + """Decode a missing payload kwarg as None (ROI deletion).""" + action = build_mutation_action(None) + # None kwargs are dropped at construction/encoding time: a deletion + # mutation simply has no "payload" kwarg on disk. + assert "payload" not in action.kwargs + loaded = roundtrip_action(action) + assert loaded.kind == HistoryAction.KIND_MUTATION + assert loaded.mutation_key == "roi" + assert loaded.target_uuids == ["first-uuid", "second-uuid"] + assert loaded.kwargs.get("payload") is None + + +def test_mutation_action_copy_and_uuid_remap() -> None: + """Copy a mutation action independently and remap its target UUIDs.""" + payload = create_signal_roi([[26, 41]], indices=True) + action = build_mutation_action(payload) + copied = action.copy() + assert copied is not action and copied.uuid != action.uuid + assert copied.mutation_key == "roi" + assert copied.target_uuids == action.target_uuids + assert copied.target_uuids is not action.target_uuids + assert roi_as_dict(copied.kwargs["payload"]) == roi_as_dict(payload) + remapped = action.copy_with_uuid_remap( + {"signal": {"first-uuid": "new-first", "second-uuid": "new-second"}} + ) + assert remapped.target_uuids == ["new-first", "new-second"] + assert action.target_uuids == ["first-uuid", "second-uuid"] diff --git a/datalab/tests/features/common/history_roi_mutation_test.py b/datalab/tests/features/common/history_roi_mutation_test.py new file mode 100644 index 000000000..9cee5d12b --- /dev/null +++ b/datalab/tests/features/common/history_roi_mutation_test.py @@ -0,0 +1,194 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +"""Unified ROI mutation recording and replay in the History panel.""" + +# guitest: show + +from __future__ import annotations + +import sigima.proc.signal as sips +from sigima.objects import create_signal_roi +from sigima.tests.data import create_paracetamol_signal + +from datalab.gui.panel.history import chain as hchain +from datalab.gui.panel.history import recompute as hrec +from datalab.history.action import HistoryAction +from datalab.history.core import numpy_to_json_safe +from datalab.objectmodel import get_uuid +from datalab.tests import datalab_test_app_context + +SIZE = 200 +SROI1 = [26, 41] +SROI2 = [125, 146] + + +def test_paste_roi_records_mutation_entry() -> None: + """Pasting a ROI records a per-object mutation entry with the final ROI.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + sig1 = create_paracetamol_signal(SIZE) + sig1.roi = create_signal_roi([SROI1, SROI2], indices=True) + panel.add_object(sig1) + sig2 = create_paracetamol_signal(SIZE) + panel.add_object(sig2) + sig2 = panel.objmodel[get_uuid(sig2)] + # Seed the clipboard from the first signal, then paste on the second + panel.objview.select_objects([1]) + panel.copy_roi() + panel.objview.select_objects([2]) + panel.paste_roi() + action = history.history_sessions[-1].actions[-1] + assert action.kind == HistoryAction.KIND_MUTATION + assert action.mutation_key == "roi" + assert action.target_uuids == [get_uuid(sig2)] + payload = action.kwargs.get("payload") + assert payload is not None + # Payload is the object's post-combination ROI (round-trip check) + assert numpy_to_json_safe(payload.to_dict()) == numpy_to_json_safe( + sig2.roi.to_dict() + ) + + +def test_delete_rois_records_mutation_and_replays() -> None: + """Deleting ROIs records an empty-payload mutation; session replay works.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + sig1 = create_paracetamol_signal(SIZE) + sig1.roi = create_signal_roi([SROI1], indices=True) + panel.add_object(sig1) + sig2 = create_paracetamol_signal(SIZE) + panel.add_object(sig2) + sig2 = panel.objmodel[get_uuid(sig2)] + # Apply ROI to sig2 (records mutation #1 with payload) + panel.objview.select_objects([1]) + panel.copy_roi() + panel.objview.select_objects([2]) + panel.paste_roi() + assert sig2.roi is not None + # Remove all ROIs from sig2 (records mutation #2 without payload) + panel.processor.delete_regions_of_interest() + assert sig2.roi is None + actions = history.history_sessions[-1].actions + apply_action, delete_action = actions[-2], actions[-1] + assert delete_action.kind == HistoryAction.KIND_MUTATION + assert delete_action.mutation_key == "roi" + assert delete_action.target_uuids == [get_uuid(sig2)] + assert delete_action.kwargs.get("payload") is None + # Replaying the session in order restores the ROI, then removes it + apply_action.replay(win, restore_selection=True, edit=False) + assert sig2.roi is not None + delete_action.replay(win, restore_selection=True, edit=False) + assert sig2.roi is None + + +def test_mutation_replay_applies_roi_to_targets() -> None: + """Direct mutation replay re-applies the ROI payload to target objects.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + sig1 = create_paracetamol_signal(SIZE) + sig1.roi = create_signal_roi([SROI1, SROI2], indices=True) + panel.add_object(sig1) + sig2 = create_paracetamol_signal(SIZE) + panel.add_object(sig2) + sig2 = panel.objmodel[get_uuid(sig2)] + panel.objview.select_objects([1]) + panel.copy_roi() + panel.objview.select_objects([2]) + panel.paste_roi() + action = history.history_sessions[-1].actions[-1] + assert action.kind == HistoryAction.KIND_MUTATION + # Clear the ROI, then replay the mutation directly + sig2.roi = None + action.replay(win, restore_selection=True, edit=False) + assert sig2.roi is not None + assert numpy_to_json_safe(sig2.roi.to_dict()) == numpy_to_json_safe( + action.kwargs["payload"].to_dict() + ) + + +def test_cascade_reapplies_roi_mutation() -> None: + """Cascade recompute re-applies a downstream ROI mutation on the output.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + sig1 = create_paracetamol_signal(SIZE) + sig1.roi = create_signal_roi([SROI1, SROI2], indices=True) + panel.add_object(sig1) + src = create_paracetamol_signal(SIZE) + panel.add_object(src) + # Record a compute action producing the output object + panel.objview.select_objects([2]) + panel.processor.run_feature(sips.derivative) + compute_action = history[len(history)] + output = panel.objmodel[compute_action.output_uuids[0]] + # Paste a ROI onto the compute output (records a mutation action) + panel.objview.select_objects([1]) + panel.copy_roi() + panel.objview.select_objects([get_uuid(output)]) + panel.paste_roi() + mutation_action = history.history_sessions[-1].actions[-1] + assert mutation_action.kind == HistoryAction.KIND_MUTATION + # The mutation belongs to the compute action's downstream closure + downstream = hchain.get_downstream_actions(history, compute_action) + assert mutation_action in downstream + # Wipe the ROI, then recompute the cascade from the compute action + output.roi = None + history.recompute_cascade(compute_action) + assert output.roi is not None + assert numpy_to_json_safe(output.roi.to_dict()) == numpy_to_json_safe( + mutation_action.kwargs["payload"].to_dict() + ) + assert mutation_action.is_stale is False + + +def test_update_obj_in_place_preserves_roi() -> None: + """In-place recompute keeps the target's ROI when the new object has none.""" + with datalab_test_app_context(history=True) as win: + panel = win.signalpanel + target = create_paracetamol_signal(SIZE) + target.roi = create_signal_roi([SROI1], indices=True) + panel.add_object(target) + target = panel.objmodel[get_uuid(target)] + saved_roi_dict = numpy_to_json_safe(target.roi.to_dict()) + new_obj = create_paracetamol_signal(SIZE) + assert new_obj.roi is None + hrec.update_obj_in_place(target, new_obj) + assert target.roi is not None + assert numpy_to_json_safe(target.roi.to_dict()) == saved_roi_dict + + +def test_mutation_root_has_downstream_computes() -> None: + """A mutation root seeds its targets: consuming computes are downstream.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + sig1 = create_paracetamol_signal(SIZE) + sig1.roi = create_signal_roi([SROI1], indices=True) + panel.add_object(sig1) + sig2 = create_paracetamol_signal(SIZE) + panel.add_object(sig2) + panel.objview.select_objects([1]) + panel.copy_roi() + panel.objview.select_objects([2]) + panel.paste_roi() + mutation_action = history.history_sessions[-1].actions[-1] + assert mutation_action.kind == HistoryAction.KIND_MUTATION + # Compute consuming the mutated object is downstream of the mutation + panel.objview.select_objects([2]) + panel.processor.run_feature(sips.derivative) + compute_action = history.history_sessions[-1].actions[-1] + assert compute_action.kind == HistoryAction.KIND_COMPUTE + downstream = hchain.get_downstream_actions(history, mutation_action) + assert compute_action in downstream + + +if __name__ == "__main__": + test_paste_roi_records_mutation_entry() + test_delete_rois_records_mutation_and_replays() + test_mutation_replay_applies_roi_to_targets() + test_cascade_reapplies_roi_mutation() + test_update_obj_in_place_preserves_roi() + test_mutation_root_has_downstream_computes() diff --git a/datalab/tests/features/common/history_workflow_test.py b/datalab/tests/features/common/history_workflow_test.py index c449b5855..f6fc223f3 100644 --- a/datalab/tests/features/common/history_workflow_test.py +++ b/datalab/tests/features/common/history_workflow_test.py @@ -976,17 +976,21 @@ def test_1_to_0_cascade_uses_roi_safe_parameter_copy() -> None: action.pattern = "1_to_0" action.target = "signalpanel" action.panel_str = "signal" - action.func_name = "analysis" + action.func_name = "stats" action.kwargs = {"param": param} action.state.selection = {panel.PANEL_STR_ID: [source_uuid]} + # The guard now lives inside recompute_1_to_0: spy on compute_1_to_0 + # to observe the parameter actually passed to the executed analysis with patch.object( - panel.processor, "recompute_1_to_0", return_value=True - ) as recompute: + panel.processor, + "compute_1_to_0", + return_value=SimpleNamespace(execution_success=True), + ) as compute: success = hrec.recompute_action_in_place(history, action) assert success is True - passed_param = recompute.call_args.args[2] + passed_param = compute.call_args.args[1] assert passed_param is not param assert passed_param.create_rois is False assert action.kwargs["param"].create_rois is True @@ -1089,3 +1093,32 @@ def test_deletion_reconnects_and_splices_chain() -> None: output_uuid not in history.runtime.objects.output_to_action for output_uuid in removed_output_uuids ) + + +def test_replay_survives_unexpected_recompute_exception() -> None: + """Contain unexpected exception types raised during an in-place recompute.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + history.toggle_edit_mode(True) + acts = list(build_signal_chain(panel, history).actions) + original = hrec.recompute_1_to_1_in_place + + def flaky(panel_, action_): + if action_ is acts[1]: + raise IndexError("boom") + return original(panel_, action_) + + with ( + patch.object(hireplay, "prompt_edit_action_params", return_value=True), + patch.object(hrec, "recompute_1_to_1_in_place", flaky), + patch.object(hrec, "flush_cascade_warnings") as flush, + ): + hireplay.replay_actions(history, acts, prompt=True) + + assert acts[0].is_stale is False + assert acts[1].is_stale is True # failed action stays flagged + assert acts[2].is_stale is True # downstream blocked by the failure + flush.assert_called() + warnings = history.runtime.execution.cascade_warnings + assert any("boom" in w for w in warnings) diff --git a/datalab/tests/features/image/detection_roi_merge_unit_test.py b/datalab/tests/features/image/detection_roi_merge_unit_test.py index 1565d0751..b33e83330 100644 --- a/datalab/tests/features/image/detection_roi_merge_unit_test.py +++ b/datalab/tests/features/image/detection_roi_merge_unit_test.py @@ -22,6 +22,7 @@ from sigima.objects import NewImageParam, create_image_roi from sigima.tests.data import create_multigaussian_image, create_peak_image +from datalab.env import execenv from datalab.tests import datalab_test_app_context from datalab.tests.features.image.roi_app_test import IROI1, IROI2 @@ -221,6 +222,7 @@ def test_no_infinite_roi_recreation_loop(): if __name__ == "__main__": + execenv.unattended = True # Auto-close dialogs and event loops (standalone run) test_create_rois_no_existing_roi() test_create_rois_appends_to_existing_roi() test_create_rois_false_preserves_existing_roi() diff --git a/doc/features/common/historypanel.rst b/doc/features/common/historypanel.rst index 50c1b3904..ffca2c063 100644 --- a/doc/features/common/historypanel.rst +++ b/doc/features/common/historypanel.rst @@ -15,9 +15,11 @@ signals and images, organized into **sessions**. Each session is a chronological list of either: - **UI actions** (creating a new signal, removing selected objects, saving the - workspace to HDF5, ...), or + workspace to HDF5, ...), - **computations** (FFT, average, Gaussian fit, ...) dispatched by the DataLab - processors to Sigima. + processors to Sigima, or +- **mutations** (in-place modifications of existing objects, such as editing + regions of interest). See :ref:`history-object-mutations`. A recorded session can be: @@ -44,6 +46,33 @@ A recorded session can be: Gaussian signal, compute the average, add Gaussian noise to the result and run a Gaussian fit. +.. _history-object-mutations: + +Object mutations +---------------- + +Besides UI actions and computations, the panel records **mutations**: +in-place modifications of existing objects that do not create new ones. +Mutations currently cover regions of interest (ROI): defining or editing +ROIs graphically or numerically, deleting one or all ROIs, and pasting ROIs +each record a single generic mutation entry holding the affected objects +and the resulting ROI state. + +Replaying a mutation re-applies the recorded ROI state to its target +objects (an empty state removes the ROIs). In step-by-step mode, the ROI +parameters can be reviewed and edited in a dialog before being re-applied; +editing them triggers a recompute of the downstream dependent computations. + +When a recomputed action re-creates or updates an object, the mutations +recorded on that object are re-applied in order, and analyses depending on +the mutated object are recomputed. User ROIs present on an output object +are preserved by in-place recomputes, unless the recompute itself produces +a ROI. + +Mutation entries are saved with sessions (standalone ``.dlhist`` files and +HDF5 workspaces) like any other action; history files created with earlier +versions of DataLab load unchanged. + Recording and session lifecycle ------------------------------- @@ -152,10 +181,15 @@ The toolbar at the top of the panel exposes the following actions: changed (in step-by-step mode or from the **Processing** tab) are marked as outdated; replaying recomputes them and, when parameters were edited, their downstream dependent actions as well. Analysis actions replay by - recomputing their results on the source objects. UI actions are replayed by - invoking their recorded method and may reproduce side effects, including - creating, importing, or duplicating objects; destructive actions are - skipped when their captured targets no longer resolve. + recomputing their results on the source objects: each analysis records + which results it stored on the object (its *effects*), so replaying + updates exactly those results — previous values are replaced, and if the + recompute fails the previous results are restored. Analyses recorded with + earlier versions of DataLab replay using their saved state. UI actions + are replayed by invoking their recorded method and may reproduce side + effects, including creating, importing, or duplicating objects; + destructive actions are skipped when their captured targets no longer + resolve. - |step_by_step| **Step-by-step**: replay the same selection one step at a time, opening the parameter dialog for each supported action (object creation, computation, ROI extraction) before recomputing it. Accepted diff --git a/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po b/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po index 68f1f9280..768230058 100644 --- a/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po +++ b/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2026-08-05 19:29+0200\n" +"POT-Creation-Date: 2026-08-06 09:11+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language: fr\n" @@ -50,7 +50,7 @@ msgstr "" msgid "" "**UI actions** (creating a new signal, removing selected objects, saving " -"the workspace to HDF5, ...), or" +"the workspace to HDF5, ...)," msgstr "" "d'**actions de l'interface** (création d'un nouveau signal, suppression " "des objets sélectionnés, enregistrement de l'espace de travail au format " @@ -58,10 +58,17 @@ msgstr "" msgid "" "**computations** (FFT, average, Gaussian fit, ...) dispatched by the " -"DataLab processors to Sigima." +"DataLab processors to Sigima, or" msgstr "" "de **calculs** (FFT, moyenne, ajustement gaussien, ...) dont l'exécution " -"est confiée à Sigima par les processeurs de DataLab." +"est confiée à Sigima par les processeurs de DataLab, soit" + +msgid "" +"**mutations** (in-place modifications of existing objects, such as " +"editing regions of interest). See :ref:`history-object-mutations`." +msgstr "" +"de **mutations** (modifications en place d'objets existants, telles que " +"l'édition de régions d'intérêt). Voir :ref:`history-object-mutations`." msgid "A recorded session can be:" msgstr "Une session enregistrée peut être :" @@ -116,6 +123,61 @@ msgstr "" "calcul de la moyenne, ajout d'un bruit gaussien au résultat et ajustement" " par une gaussienne." +msgid "Object mutations" +msgstr "Mutations d'objets" + +msgid "" +"Besides UI actions and computations, the panel records **mutations**: in-" +"place modifications of existing objects that do not create new ones. " +"Mutations currently cover regions of interest (ROI): defining or editing " +"ROIs graphically or numerically, deleting one or all ROIs, and pasting " +"ROIs each record a single generic mutation entry holding the affected " +"objects and the resulting ROI state." +msgstr "" +"Outre les actions de l'interface et les calculs, le panneau enregistre " +"des **mutations** : des modifications en place d'objets existants qui ne " +"créent pas de nouveaux objets. Les mutations couvrent actuellement les " +"régions d'intérêt (ROI) : la définition ou l'édition de ROI de manière " +"graphique ou numérique, la suppression d'une ou de toutes les ROI et le " +"collage de ROI enregistrent chacun une entrée de mutation générique " +"unique contenant les objets concernés et l'état de ROI résultant." + +msgid "" +"Replaying a mutation re-applies the recorded ROI state to its target " +"objects (an empty state removes the ROIs). In step-by-step mode, the ROI " +"parameters can be reviewed and edited in a dialog before being re-" +"applied; editing them triggers a recompute of the downstream dependent " +"computations." +msgstr "" +"Le rejeu d'une mutation réapplique l'état de ROI enregistré à ses objets " +"cibles (un état vide supprime les ROI). En mode pas à pas, les paramètres" +" des ROI peuvent être examinés et modifiés dans une boîte de dialogue " +"avant d'être réappliqués ; leur modification déclenche un recalcul des " +"calculs dépendants en aval." + +msgid "" +"When a recomputed action re-creates or updates an object, the mutations " +"recorded on that object are re-applied in order, and analyses depending " +"on the mutated object are recomputed. User ROIs present on an output " +"object are preserved by in-place recomputes, unless the recompute itself " +"produces a ROI." +msgstr "" +"Lorsqu'une action recalculée recrée ou met à jour un objet, les mutations" +" enregistrées sur cet objet sont réappliquées dans l'ordre, et les " +"analyses dépendant de l'objet muté sont recalculées. Les ROI définies par" +" l'utilisateur sur un objet de sortie sont préservées par les recalculs " +"en place, sauf si le recalcul produit lui-même une ROI." + +msgid "" +"Mutation entries are saved with sessions (standalone ``.dlhist`` files " +"and HDF5 workspaces) like any other action; history files created with " +"earlier versions of DataLab load unchanged." +msgstr "" +"Les entrées de mutation sont sauvegardées avec les sessions (fichiers " +"``.dlhist`` autonomes et espaces de travail HDF5) comme toute autre " +"action ; les fichiers d'historique créés avec des versions antérieures de" +" DataLab se chargent sans modification." + msgid "Recording and session lifecycle" msgstr "Enregistrement et cycle de vie des sessions" @@ -249,10 +311,14 @@ msgid "" "**Processing** tab) are marked as outdated; replaying recomputes them " "and, when parameters were edited, their downstream dependent actions as " "well. Analysis actions replay by recomputing their results on the source " -"objects. UI actions are replayed by invoking their recorded method and " -"may reproduce side effects, including creating, importing, or duplicating" -" objects; destructive actions are skipped when their captured targets no " -"longer resolve." +"objects: each analysis records which results it stored on the object (its" +" *effects*), so replaying updates exactly those results — previous values" +" are replaced, and if the recompute fails the previous results are " +"restored. Analyses recorded with earlier versions of DataLab replay using" +" their saved state. UI actions are replayed by invoking their recorded " +"method and may reproduce side effects, including creating, importing, or " +"duplicating objects; destructive actions are skipped when their captured " +"targets no longer resolve." msgstr "" "|replay| **Rejouer** : recalcule la sélection en place, silencieusement " "(sans boîtes de dialogue de paramètres). Sélectionner une action rejoue " @@ -271,8 +337,14 @@ msgstr "" "marquées comme obsolètes ; le rejeu les recalcule et, lorsque les " "paramètres ont été modifiés, recalcule également leurs actions " "dépendantes en aval. Les actions d'analyse sont rejouées en recalculant " -"leurs résultats sur les objets source. Les actions de l'interface sont " -"rejouées en invoquant leur méthode enregistrée et peuvent reproduire des " +"leurs résultats sur les objets source : chaque analyse enregistre les " +"résultats qu'elle a stockés sur l'objet (ses *effets*), de sorte que le " +"rejeu met à jour exactement ces résultats — les valeurs précédentes sont " +"remplacées et, si le recalcul échoue, les résultats précédents sont " +"restaurés. Les analyses enregistrées avec des versions antérieures de " +"DataLab sont rejouées à partir de leur état sauvegardé. Les actions de " +"l'interface sont rejouées en invoquant leur méthode enregistrée et " +"peuvent reproduire des " "effets, notamment créer, importer ou dupliquer des objets ; les actions " "destructives sont ignorées lorsque leurs cibles capturées ne peuvent plus" " être résolues." @@ -289,10 +361,10 @@ msgid "" "edits made during that run, and silently recomputes any actions left " "outdated so the chain stays up to date." msgstr "" -"|step_by_step| **Pas à pas** : rejoue la même sélection étape par " -"étape, en ouvrant la boîte de dialogue des paramètres pour chaque action " -"prise en charge (création d'objet, calcul, extraction de ROI) avant de la" -" recalculer. Les modifications acceptées se propagent aux actions " +"|step_by_step| **Pas à pas** : rejoue la même sélection étape par étape, " +"en ouvrant la boîte de dialogue des paramètres pour chaque action prise " +"en charge (création d'objet, calcul, extraction de ROI) avant de la " +"recalculer. Les modifications acceptées se propagent aux actions " "dépendantes en aval, qui sont également recalculées. L'annulation d'une " "boîte de dialogue interrompt le rejeu, restaure les modifications de " "paramètres effectuées durant cette exécution et recalcule silencieusement" @@ -670,3 +742,22 @@ msgstr "" #~ "mises à jour ou recalculées sur " #~ "place." +#~ msgid "" +#~ "**UI actions** (creating a new signal," +#~ " removing selected objects, saving the " +#~ "workspace to HDF5, ...), or" +#~ msgstr "" +#~ "d'**actions de l'interface** (création d'un" +#~ " nouveau signal, suppression des objets " +#~ "sélectionnés, enregistrement de l'espace de" +#~ " travail au format HDF5, ...), soit" + +#~ msgid "" +#~ "**computations** (FFT, average, Gaussian fit," +#~ " ...) dispatched by the DataLab " +#~ "processors to Sigima." +#~ msgstr "" +#~ "de **calculs** (FFT, moyenne, ajustement " +#~ "gaussien, ...) dont l'exécution est " +#~ "confiée à Sigima par les processeurs " +#~ "de DataLab." From 03e1ff729afc4d4f0e3f31d27a44c15464ee9f7d Mon Sep 17 00:00:00 2001 From: Stefano Pierini <s.pierini@codra.fr> Date: Wed, 5 Aug 2026 16:14:16 +0200 Subject: [PATCH 075/108] Doc: Add note on history session behavior and include new image --- doc/images/tutorials/laser_beam/07.png | Bin 0 -> 51371 bytes doc/intro/tutorials/laser_beam.rst | 14 ++++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 doc/images/tutorials/laser_beam/07.png diff --git a/doc/images/tutorials/laser_beam/07.png b/doc/images/tutorials/laser_beam/07.png new file mode 100644 index 0000000000000000000000000000000000000000..6107178a8e317bab1646ce75f4bd6dc2f8a7109d GIT binary patch literal 51371 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%0DxH{wBXR~AD#gTS-=!(8(3S_Tv?beMvGhSQ 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 bg1o*7Bkn|ISbi;f1N+EGDoRv|83p|xiS}cN literal 0 HcmV?d00001 diff --git a/doc/intro/tutorials/laser_beam.rst b/doc/intro/tutorials/laser_beam.rst index 42e39e913..8d0cf8212 100644 --- a/doc/intro/tutorials/laser_beam.rst +++ b/doc/intro/tutorials/laser_beam.rst @@ -172,6 +172,20 @@ The intensity profile will be displayed in the "Signal panel". We can then fit t to a Gaussian function using "Processing > Fitting > Gaussian fit". Here we have selected both signals for comparison. +.. note:: + + If history recording is enabled, creating a new signal starts a new history + session, separate from the session containing the image operations. Since + extracting the intensity profile is an operation performed on an image, the + new session starts with the Gaussian fit applied to the resulting signal. + + .. figure:: ../../images/tutorials/laser_beam/07.png + + The image-processing actions are recorded in the first session, while + the Gaussian fit starts a separate session for the resulting signal. + + + .. figure:: ../../images/tutorials/laser_beam/08.png The intensity profile fitted to a Gaussian function. Here both signals are From cfa57ad7623f6cca2cf3d0e23ce58ee9de049d8b Mon Sep 17 00:00:00 2001 From: Stefano Pierini <s.pierini@codra.fr> Date: Wed, 5 Aug 2026 16:14:57 +0200 Subject: [PATCH 076/108] Fix: Update laser beam tutorial image --- doc/images/tutorials/laser_beam/09.png | Bin 9411 -> 33543 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/doc/images/tutorials/laser_beam/09.png b/doc/images/tutorials/laser_beam/09.png index d63b6d4b0580e011c3b3b5c0b195d0062fa17b41..23e65baed0bb5a69dc5766fb66db678d8670180e 100644 GIT binary patch literal 33543 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 literal 9411 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 From 1b822ddfd151bf242328144135b7d6d831b03d84 Mon Sep 17 00:00:00 2001 From: Stefano Pierini <s.pierini@codra.fr> Date: Wed, 5 Aug 2026 16:33:43 +0200 Subject: [PATCH 077/108] Doc: Update French tutorial translation with history panel behavior and image processing details --- .../LC_MESSAGES/intro/tutorials/laser_beam.po | 79 ++++--------------- 1 file changed, 16 insertions(+), 63 deletions(-) diff --git a/doc/locale/fr/LC_MESSAGES/intro/tutorials/laser_beam.po b/doc/locale/fr/LC_MESSAGES/intro/tutorials/laser_beam.po index 8a91331b1..b0ebb076a 100644 --- a/doc/locale/fr/LC_MESSAGES/intro/tutorials/laser_beam.po +++ b/doc/locale/fr/LC_MESSAGES/intro/tutorials/laser_beam.po @@ -194,12 +194,8 @@ msgstr "" msgid "reset_positions" msgstr "reset_positions" -msgid "" -"Both the \"Distribute on a grid\" and \"Reset image positions\" options " -"modify the images in place, without creating new images. For this reason," -" they are not registered in the History Panel, which only lists newly " -"created objects." -msgstr "" +msgid "Both the \"Distribute on a grid\" and \"Reset image positions\" options modify the images in place, without creating new images. For this reason, they are not registered in the History Panel, which only lists newly created objects." +msgstr "Les options \"Distribuer sur une grille\" et \"Réinitialiser les positions des images\" modifient les images sur place, sans créer de nouvelles images. Pour cette raison, elles ne sont pas enregistrées dans le panneau Historique, qui ne répertorie que les objets nouvellement créés." msgid "Remove background noise" msgstr "Supprimer le bruit de fond" @@ -214,24 +210,8 @@ msgstr "" "images. Plusieurs méthodes sont disponibles pour estimer le niveau de " "bruit de fond." -#, fuzzy -msgid "" -"One approach utilizes the \"Cross section\" tool, which is provided by " -"the `PlotPy <https://github.com/PlotPyStack/plotpy>`__ library that " -"DataLab uses for signal and image visualization. Select an image from the" -" \"Image panel\", choose the corresponding image in the visualization " -"panel, and activate the \"Cross section\" tool |cross_section| from the " -"vertical toolbar on the left side of the visualization panel. This " -"reveals that the background noise level is approximately 30 lsb." -msgstr "" -"Une approche utilise l'outil \"Profil rectiligne\", qui est fourni par la" -" bibliothèque `PlotPy <https://github.com/PlotPyStack/plotpy>` que " -"DataLab utilise pour la visualisation de signaux et d'images. " -"Sélectionnez une image dans le panneau \"Images\", choisissez l'image " -"correspondante dans le panneau de visualisation, et activez l'outil " -"\"Profil rectiligne\" |cross_section| depuis la barre d'outils verticale " -"sur le côté gauche du panneau de visualisation. Cela révèle que le niveau" -" de bruit de fond est d'environ 30 lsb." +msgid "One approach utilizes the \"Cross section\" tool, which is provided by the `PlotPy <https://github.com/PlotPyStack/plotpy>`__ library that DataLab uses for signal and image visualization. Select an image from the \"Image panel\", choose the corresponding image in the visualization panel, and activate the \"Cross section\" tool |cross_section| from the vertical toolbar on the left side of the visualization panel. This reveals that the background noise level is approximately 30 lsb." +msgstr "Une approche utilise l'outil \"Profil rectiligne\", qui est fourni par la bibliothèque `PlotPy <https://github.com/PlotPyStack/plotpy>`__ que DataLab utilise pour la visualisation de signaux et d'images. Sélectionnez une image dans le panneau \"Images\", choisissez l'image correspondante dans le panneau de visualisation, et activez l'outil \"Profil rectiligne\" |cross_section| depuis la barre d'outils verticale sur le côté gauche du panneau de visualisation. Cela révèle que le niveau de bruit de fond est d'environ 30 lsb." msgid "cross_section" msgstr "cross_section" @@ -246,23 +226,8 @@ msgstr "" "ouvrir le menu contextuel, puis choisissez \"Marqueurs > Lié à l'élément " "actif\"." -#, fuzzy -msgid "" -"Another method for measuring background noise, also provided by `PlotPy " -"<https://github.com/PlotPyStack/plotpy>`__, involves using the \"Image " -"statistics\" tool |imagestats| from the vertical toolbar on the left side" -" of the visualization panel. This tool displays statistical information " -"for a rectangular region that you define by dragging the mouse across the" -" image. This analysis confirms that the background noise level is " -"approximately 30 lsb." -msgstr "" -"Une autre méthode pour mesurer le bruit de fond, également fournie par " -"`PlotPy <https://github.com/PlotPyStack/plotpy>`, consiste à utiliser " -"l'outil \"Statistiques de l'image\" |imagestats| de la barre d'outils " -"verticale sur le côté gauche du panneau de visualisation. Cet outil " -"affiche des informations statistiques pour une région rectangulaire que " -"vous définissez en faisant glisser la souris sur l'image. Cette analyse " -"confirme que le niveau de bruit de fond est d'environ 30 lsb." +msgid "Another method for measuring background noise, also provided by `PlotPy <https://github.com/PlotPyStack/plotpy>`__, involves using the \"Image statistics\" tool |imagestats| from the vertical toolbar on the left side of the visualization panel. This tool displays statistical information for a rectangular region that you define by dragging the mouse across the image. This analysis confirms that the background noise level is approximately 30 lsb." +msgstr "Une autre méthode pour mesurer le bruit de fond, également fournie par `PlotPy <https://github.com/PlotPyStack/plotpy>`__, consiste à utiliser l'outil \"Statistiques de l'image\" |imagestats| de la barre d'outils verticale sur le côté gauche du panneau de visualisation. Cet outil affiche des informations statistiques pour une région rectangulaire que vous définissez en faisant glisser la souris sur l'image. Cette analyse confirme que le niveau de bruit de fond est d'environ 30 lsb." msgid "imagestats" msgstr "imagestats" @@ -326,15 +291,14 @@ msgstr "" " \"Définir les paramètres\". Voir :ref:`tutorial_fabry_perot` pour plus " "de détails sur l'extraction de profil d'intensité." -msgid "" -"The intensity profile will be displayed in the \"Signal panel\". We can " -"then fit the profile to a Gaussian function using \"Processing > Fitting " -"> Gaussian fit\". Here we have selected both signals for comparison." -msgstr "" -"Le profil d'intensité sera affiché dans le panneau \"Signaux\". Nous " -"pouvons ensuite ajuster le profil à une fonction gaussienne en utilisant " -"\"Traitement > Ajustement > Ajustement gaussien\". Ici, nous avons " -"sélectionné les deux signaux pour comparaison." +msgid "The intensity profile will be displayed in the \"Signal panel\". We can then fit the profile to a Gaussian function using \"Processing > Fitting > Gaussian fit\". Here we have selected both signals for comparison." +msgstr "Le profil d'intensité sera affiché dans le panneau \"Signaux\". Nous pouvons ensuite ajuster le profil à une fonction gaussienne en utilisant \"Traitement > Ajustement > Ajustement gaussien\". Ici, nous avons sélectionné les deux signaux pour comparaison." + +msgid "If history recording is enabled, creating a new signal starts a new history session, separate from the session containing the image operations. Since extracting the intensity profile is an operation performed on an image, the new session starts with the Gaussian fit applied to the resulting signal." +msgstr "Si l'enregistrement de l'historique est activé, la création d'un nouveau signal démarre une nouvelle session d'historique, distincte de celle contenant les opérations sur les images. Comme l'extraction du profil d'intensité est une opération effectuée sur une image, la nouvelle session commence avec l'ajustement gaussien appliqué au signal obtenu." + +msgid "The image-processing actions are recorded in the first session, while the Gaussian fit starts a separate session for the resulting signal." +msgstr "Les actions de traitement d'image sont enregistrées dans la première session, tandis que l'ajustement gaussien démarre une session distincte pour le signal obtenu." msgid "" "The intensity profile fitted to a Gaussian function. Here both signals " @@ -521,18 +485,8 @@ msgstr "" "propagation (la position est en unités arbitraires—l'index de l'image)." #, python-brace-format -msgid "" -"We can also calibrate the X and Y axes using \"Processing > Linear " -"calibration\". Here we set the X axis to the position in mm (entering the" -" title and unit in the \"Properties\" group box) using the formula: " -":math:`X[\\textrm{mm}] = 0.5 \\cdot i + 10` where :math:`i` is the image " -"index." -msgstr "" -"Nous pouvons également étalonner les axes X et Y en utilisant " -"\"Traitement > Étalonnage linéaire\". Ici, nous définissons l'axe X sur " -"la position en mm (en entrant le titre et l'unité dans le groupe " -"\"Propriétés\") en utilisant la formule : :math:`X[\\textrm{mm}] = 0.5 " -"\\cdot i + 10` où :math:`i` est l'index de l'image." +msgid "We can also calibrate the X and Y axes using \"Processing > Linear calibration\". Here we set the X axis to the position in mm (entering the title and unit in the \"Properties\" group box) using the formula: :math:`X[\\textrm{mm}] = 0.5 \\cdot i + 10` where :math:`i` is the image index." +msgstr "Nous pouvons également étalonner les axes X et Y en utilisant \"Traitement > Étalonnage linéaire\". Ici, nous définissons l'axe X sur la position en mm (en entrant le titre et l'unité dans le groupe \"Propriétés\") en utilisant la formule : :math:`X[\\textrm{mm}] = 0.5 \\cdot i + 10` où :math:`i` est l'index de l'image." msgid "" "The calibrated beam size as a function of the position along the " @@ -575,4 +529,3 @@ msgstr "fileopen_h5" msgid "h5browser" msgstr "h5browser" - From acaf1c43581a59544a20ea1bcbddac53a7285881 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Thu, 6 Aug 2026 13:21:49 +0200 Subject: [PATCH 078/108] Refactor: Clean up History panel internals after feature review A full functional and clean-code review of the History panel feature. The replay engine went through several iterations (silent replay, then unified in-place recompute), leaving behind dead helpers, obsolete parameters and duplicated declarations that no longer had any caller or effect. The review also surfaced two robustness gaps (a partially-wiped metadata risk during in-place updates, and an incomplete panel reset) and a test-isolation leak that broke unrelated tests in full-suite runs. The history test suite is consolidated at the same time: three files whose scope had been absorbed by the model, workflow and panel test files are merged into them, with coverage raised on the weakest history modules and no regression elsewhere. * [CHG] : Remove dead code identified during review: resolve_target_outputs, reconnect_single_removed, build_processing_chains, HistoryNavigation.current_panel_str, HistorySession.remove_action (obsolete truncating semantics), write-only HistoryExecutionState.broken_actions, prune_output_mapping module wrapper, action_output_uuid facade re-export, duplicated get_session_of, redundant SIG_OBJECT_MODIFIED redeclaration, unused module loggers, and unreachable branches in recompute_cascade and HistoryAction.description * [CHG] : Remove the unused restore_selection parameter from the whole is_current_state_compatible chain (workspace state, action, session and call sites) * [FIX] : update_obj_in_place no longer risks leaving half-wiped metadata when restoring attributes fails with AttributeError * [FIX] : HistoryPanel.remove_all_objects now fully resets the panel state (sessions list, navigation active session and counters, tree, action buttons) * [CHG] : Update docstrings to the unified in-place recompute vocabulary (scientific processing-lineage context) and add missing type annotations in historytools_ops.py * [CHG] : Consolidate history tests from 9 files down to 6: merge history_effects_unit_test, history_mutation_model_unit_test and history_roi_mutation_test into the model, workflow and panel test files (88 -> 83 tests); raise coverage on chain.py (72 -> 89%), recompute.py (73 -> 80%), historytools_ops.py (73 -> 84%) and interactive_replay.py (73 -> 84%) * [FIX] : Drain stale unattended Qt auto-close timers via an autouse fixture in worker_unit_test.py: leaked timers were closing dialogs in later tests during full-suite runs (pluginconfig_dialog_test and a history stub test) * [CHG] : Purge generic placeholder header lines (Report-Msgid-Bugs-To, Last-Translator, Language, Language-Team, Generated-By) from the documentation translation catalogs; no translation entries touched --- datalab/gui/historytools_ops.py | 15 +- datalab/gui/panel/history/chain.py | 50 +- datalab/gui/panel/history/chainmodel.py | 21 +- datalab/gui/panel/history/facade.py | 4 - .../gui/panel/history/interactive_replay.py | 29 +- datalab/gui/panel/history/navigation.py | 5 - datalab/gui/panel/history/panel.py | 7 +- datalab/gui/panel/history/recompute.py | 196 ++++- datalab/gui/panel/history/runtime.py | 2 - datalab/history/action.py | 13 +- datalab/history/core.py | 2 - datalab/history/session.py | 31 +- datalab/history/workspace_state.py | 8 +- .../common/history_effects_unit_test.py | 263 ------ .../common/history_model_unit_test.py | 763 +++++++++++------- .../history_mutation_model_unit_test.py | 89 -- .../features/common/history_panel_test.py | 83 ++ .../common/history_roi_mutation_test.py | 194 ----- .../features/common/history_test_helpers.py | 24 + .../features/common/history_workflow_test.py | 520 +++++++++++- .../tests/features/common/worker_unit_test.py | 16 + datalab/widgets/historytree.py | 4 +- .../LC_MESSAGES/contributing/dependencies.po | 1 - .../LC_MESSAGES/contributing/environment.po | 1 - .../LC_MESSAGES/contributing/gitworkflow.po | 1 - .../fr/LC_MESSAGES/features/advanced/api.po | 1 - .../features/advanced/api/index.po | 1 - .../LC_MESSAGES/features/advanced/macros.po | 1 - .../advanced/migration_v020_to_v100.po | 1 - .../fr/LC_MESSAGES/features/advanced/model.po | 1 - .../fr/LC_MESSAGES/features/advanced/proxy.po | 6 - .../LC_MESSAGES/features/advanced/webapi.po | 1 - .../LC_MESSAGES/features/common/h5browser.po | 1 - .../features/common/historypanel.po | 5 - .../LC_MESSAGES/features/common/overview.po | 4 - .../LC_MESSAGES/features/common/settings.po | 5 - .../features/image/menu_analysis.po | 1 - .../LC_MESSAGES/features/image/menu_create.po | 1 - .../LC_MESSAGES/features/image/menu_edit.po | 1 - .../LC_MESSAGES/features/image/menu_file.po | 1 - .../features/image/menu_operations.po | 1 - .../features/image/menu_processing.po | 1 - .../fr/LC_MESSAGES/features/image/menu_roi.po | 1 - .../LC_MESSAGES/features/image/menu_view.po | 1 - doc/locale/fr/LC_MESSAGES/features/index.po | 1 - .../features/signal/menu_analysis.po | 1 - .../features/signal/menu_create.po | 1 - .../LC_MESSAGES/features/signal/menu_edit.po | 1 - .../LC_MESSAGES/features/signal/menu_file.po | 1 - .../features/signal/menu_operations.po | 1 - .../features/signal/menu_processing.po | 1 - .../LC_MESSAGES/features/signal/menu_roi.po | 1 - .../LC_MESSAGES/features/signal/menu_view.po | 1 - .../features/validation/functional.po | 1 - .../LC_MESSAGES/features/validation/status.po | 6 - .../features/validation/technical.po | 1 - doc/locale/fr/LC_MESSAGES/intro/ecosystem.po | 1 - .../fr/LC_MESSAGES/intro/installation.po | 5 - .../LC_MESSAGES/intro/installation_offline.po | 1 - .../fr/LC_MESSAGES/intro/introduction.po | 1 - .../fr/LC_MESSAGES/intro/tutorials/blobs.po | 1 - .../intro/tutorials/custom_func.po | 1 - .../intro/tutorials/fabry_perot.po | 1 - .../fr/LC_MESSAGES/intro/tutorials/index.po | 1 - .../LC_MESSAGES/intro/tutorials/laser_beam.po | 6 - .../LC_MESSAGES/intro/tutorials/spectrum.po | 1 - .../intro/tutorials/videos/p1_quick_demo.po | 1 - .../tutorials/videos/p2_extensibility.po | 1 - .../intro/tutorials/work_with_spyder.po | 1 - .../fr/LC_MESSAGES/outreach/euroscipy2026.po | 1 - doc/locale/fr/LC_MESSAGES/outreach/index.po | 1 - .../fr/LC_MESSAGES/outreach/osxp2024.po | 1 - .../fr/LC_MESSAGES/outreach/osxp2025.po | 1 - .../fr/LC_MESSAGES/outreach/pydata2024.po | 1 - .../fr/LC_MESSAGES/outreach/scipy2024.po | 1 - .../fr/LC_MESSAGES/release_notes/index.po | 1 - .../LC_MESSAGES/release_notes/release_0.09.po | 1 - .../LC_MESSAGES/release_notes/release_0.10.po | 1 - .../LC_MESSAGES/release_notes/release_0.11.po | 1 - .../LC_MESSAGES/release_notes/release_0.12.po | 1 - .../LC_MESSAGES/release_notes/release_0.14.po | 1 - .../LC_MESSAGES/release_notes/release_0.15.po | 1 - .../LC_MESSAGES/release_notes/release_0.16.po | 1 - .../LC_MESSAGES/release_notes/release_0.17.po | 1 - .../LC_MESSAGES/release_notes/release_0.18.po | 1 - .../LC_MESSAGES/release_notes/release_0.19.po | 1 - .../LC_MESSAGES/release_notes/release_0.20.po | 1 - .../LC_MESSAGES/release_notes/release_1.00.po | 1 - .../LC_MESSAGES/release_notes/release_1.01.po | 1 - .../LC_MESSAGES/release_notes/release_1.02.po | 1 - .../LC_MESSAGES/release_notes/release_1.03.po | 1 - doc/locale/fr/LC_MESSAGES/requirements.po | 6 - 92 files changed, 1285 insertions(+), 1159 deletions(-) delete mode 100644 datalab/tests/features/common/history_effects_unit_test.py delete mode 100644 datalab/tests/features/common/history_mutation_model_unit_test.py delete mode 100644 datalab/tests/features/common/history_roi_mutation_test.py diff --git a/datalab/gui/historytools_ops.py b/datalab/gui/historytools_ops.py index c97c82b6c..6acc39d4b 100644 --- a/datalab/gui/historytools_ops.py +++ b/datalab/gui/historytools_ops.py @@ -35,6 +35,8 @@ from datalab.objectmodel import get_uuid if TYPE_CHECKING: + from sigima.objects import ImageObj, SignalObj + from datalab.gui.panel.base import BaseDataPanel from datalab.gui.panel.history import HistoryPanel @@ -336,7 +338,7 @@ def data_panel_for(panel: HistoryPanel, panel_str: str) -> BaseDataPanel | None: return None -def strip_source_links(obj) -> None: +def strip_source_links(obj: SignalObj | ImageObj) -> None: """Turn ``obj`` into a parentless creation root (drop source references).""" pp = extract_processing_parameters(obj) if pp is None: @@ -347,7 +349,9 @@ def strip_source_links(obj) -> None: ) -def remap_object_source(obj, old_uuid: str, new_uuid: str) -> None: +def remap_object_source( + obj: SignalObj | ImageObj, old_uuid: str, new_uuid: str +) -> None: """Replace ``old_uuid`` with ``new_uuid`` in ``obj``'s source references.""" pp = extract_processing_parameters(obj) if pp is None: @@ -412,7 +416,8 @@ def split_chain_on_action_delete( orphan_uuid = next((u for u in output_uuids if u in first_inputs), None) if orphan_uuid is None or not data_panel.objmodel.has_uuid(orphan_uuid): return first_alive_output(panel, panel_str, output_uuids) - # §8.2 — autonomy via COPY: clone the orphan as a parentless creation root. + # Deep-copying the orphan and stripping its source links makes the copy + # autonomous: it no longer references the deleted upstream chain. orphan_obj = data_panel.objmodel[orphan_uuid] clone = deepcopy(orphan_obj) new_uuid = str(uuid4()) @@ -618,9 +623,7 @@ def remove_incompatible_actions(panel: HistoryPanel) -> None: incompatible: list[tuple[HistorySession, HistoryAction]] = [] for session in panel.history_sessions: for action in session.actions: - if not action.is_current_state_compatible( - panel.mainwindow, restore_selection=True - ): + if not action.is_current_state_compatible(panel.mainwindow): incompatible.append((session, action)) if not incompatible: if not execenv.unattended: diff --git a/datalab/gui/panel/history/chain.py b/datalab/gui/panel/history/chain.py index 7ebbf7fa9..d13e09b05 100644 --- a/datalab/gui/panel/history/chain.py +++ b/datalab/gui/panel/history/chain.py @@ -4,7 +4,6 @@ from __future__ import annotations -import logging from typing import TYPE_CHECKING from qtpy import QtWidgets as QW @@ -28,8 +27,6 @@ from datalab.gui.panel.base import BaseDataPanel from datalab.gui.panel.history.panel import HistoryPanel -_logger = logging.getLogger(__name__) - def find_parent_session( panel: HistoryPanel, action: HistoryAction @@ -69,9 +66,12 @@ def find_output_object_uuid( """ registered = panel.runtime.objects.action_output_uuids.get(action.uuid) if registered: - existing_ids = set(panel_data.objmodel.get_object_ids()) + # Outputs of cross-panel features (e.g. image line profile producing + # a signal) live in the other panel: check both object models. for out_uuid in registered: - if out_uuid in existing_ids: + if panel.mainwindow.signalpanel.objmodel.has_uuid( + out_uuid + ) or panel.mainwindow.imagepanel.objmodel.has_uuid(out_uuid): return out_uuid if action.func_name is None: return None @@ -210,14 +210,6 @@ def find_analysis_action( return None -def get_session_of(panel: HistoryPanel, action: HistoryAction) -> HistorySession | None: - """Return the session that contains ``action``, or None.""" - for session in panel.history_sessions: - if action in session.actions: - return session - return None - - def action_output_uuid(panel: HistoryPanel, action: HistoryAction) -> str | None: """Return the UUID of the object produced by ``action``, or ``None``.""" panel_data = resolve_panel_for_action(panel, action) @@ -259,7 +251,7 @@ def get_downstream_actions( """Return the actions of the current session that depend on ``action``.""" if not panel.history_sessions: return [] - current = get_session_of(panel, action) + current = find_parent_session(panel, action) if current is None: return [] if action.kind == HistoryAction.KIND_MUTATION: @@ -289,28 +281,12 @@ def get_downstream_actions( return downstream -def resolve_target_outputs( - panel: HistoryPanel, panel_data: BaseDataPanel, action: HistoryAction -) -> tuple[list[str], list[str]]: - """Return ``(existing, missing)`` UUIDs registered for ``action``.""" - registered = list(panel.runtime.objects.action_output_uuids.get(action.uuid, [])) - existing_ids = set(panel_data.objmodel.get_object_ids()) - existing: list[str] = [u for u in registered if u in existing_ids] - missing: list[str] = [u for u in registered if u not in existing_ids] - return existing, missing - - def existing_input_uuids(panel_data: BaseDataPanel, action: HistoryAction) -> list[str]: """Return recorded input UUIDs that still exist in ``panel_data``.""" recorded = action.state.selection.get(panel_data.PANEL_STR_ID, []) return [uuid for uuid in recorded if panel_data.objmodel.has_uuid(uuid)] -def prune_output_mapping(panel: HistoryPanel) -> None: - """Drop entries of :attr:`output_to_action` whose object no longer exists.""" - panel.runtime.objects.prune_output_mapping() - - def rewrite_action_source( action: HistoryAction, pstr: str, @@ -444,20 +420,6 @@ def apply_reconnection_plan( remove_single_action(panel, plan.producer_action) -def reconnect_single_removed( - panel: HistoryPanel, - panel_data: BaseDataPanel, - removed_uuid: str, - warnings: list[str], - roots_to_recompute: list[HistoryAction], -) -> None: - """Plan and reconnect consumers of one deleted object.""" - plan = plan_reconnection(panel, panel_data, removed_uuid) - apply_reconnection_plan(panel, panel_data, plan, roots_to_recompute) - if plan.warning is not None: - warnings.append(plan.warning) - - def show_reconnection_warnings(panel: HistoryPanel, warnings: list[str]) -> None: """Show reconnection warnings at the GUI boundary.""" if warnings and not execenv.unattended: diff --git a/datalab/gui/panel/history/chainmodel.py b/datalab/gui/panel/history/chainmodel.py index bf161fd35..7173b2837 100644 --- a/datalab/gui/panel/history/chainmodel.py +++ b/datalab/gui/panel/history/chainmodel.py @@ -5,14 +5,11 @@ from __future__ import annotations from dataclasses import dataclass, field -from typing import TYPE_CHECKING, Any +from typing import Any from datalab.gui.processor.base import ProcessingParameters from datalab.history import HistoryAction, HistorySession -if TYPE_CHECKING: - from datalab.gui.panel.history.panel import HistoryPanel - @dataclass class ProcessingChain: @@ -176,19 +173,3 @@ def build_session_chains(session: HistorySession) -> list[ProcessingChain]: chain = ProcessingChain(root=session.actions[0], session=session) chain.actions = list(session.actions) return [chain] - - -def build_processing_chains( - panel: HistoryPanel, -) -> list[tuple[HistorySession, list[ProcessingChain]]]: - """Return, for each session (in order), its ordered list of processing chains. - - Args: - panel: The history panel owning sessions and output registry. - - Returns: - A list of (session, chains) tuples in session order. - """ - return [ - (session, build_session_chains(session)) for session in panel.history_sessions - ] diff --git a/datalab/gui/panel/history/facade.py b/datalab/gui/panel/history/facade.py index 17b282fe5..65a77a929 100644 --- a/datalab/gui/panel/history/facade.py +++ b/datalab/gui/panel/history/facade.py @@ -144,10 +144,6 @@ def find_analysis_action( """Return the matching analysis action for an object UUID.""" return hchain.find_analysis_action(self, obj_uuid, func_name) - def action_output_uuid(self, action: HistoryAction) -> str | None: - """Return the UUID of the object produced by an action.""" - return hchain.action_output_uuid(self, action) - def refresh_action(self, action: HistoryAction) -> None: """Refresh an action after its arguments are mutated.""" hrec.refresh_action(self, action) diff --git a/datalab/gui/panel/history/interactive_replay.py b/datalab/gui/panel/history/interactive_replay.py index 6804df32e..3aaf93ef1 100644 --- a/datalab/gui/panel/history/interactive_replay.py +++ b/datalab/gui/panel/history/interactive_replay.py @@ -33,7 +33,30 @@ class ActionParamEdit: def replay_restore_actions( panel: HistoryPanel, replay: bool = True, restore_selection: bool = True ) -> None: - """Replay and/or restore selection for the selected actions.""" + """Replay and/or restore selection for the selected actions. + + Entry point of the Replay, Step-by-step and double-click commands. When + nothing is selected in the tree, the last session is targeted (no-op if + the history is empty). Each selected session or action is first checked + against the current workspace state: any incompatibility vetoes the whole + command with an error dialog (skipped in unattended mode). + + When ``replay`` is enabled, the selected actions (sessions contribute all + of their actions) are forwarded to :func:`replay_actions`, with parameter + dialogs when the panel's edit mode is active. When ``replay`` is disabled + and ``restore_selection`` is enabled, each selected entry is restored + instead: if edit mode is active or any action has pending parameter + edits, :func:`restore_action_params` rolls back the edited parameters and + recomputes in place; otherwise the recorded workspace selection is simply + restored. + + Args: + panel: History panel instance + replay: Replay the selected actions through the in-place recompute + engine + restore_selection: When not replaying, restore the recorded workspace + selection (or the original parameters when edits are pending) + """ panel.refresh_compatibility_items() selected = panel.tree.get_selected_actions_or_sessions(panel.history_sessions) if not selected: @@ -43,9 +66,7 @@ def replay_restore_actions( edit_mode = panel.runtime.execution.edit_mode actions_to_replay: list[HistoryAction] = [] for session_or_action in selected: - if not session_or_action.is_current_state_compatible( - panel.mainwindow, restore_selection=restore_selection - ): + if not session_or_action.is_current_state_compatible(panel.mainwindow): if not execenv.unattended: QW.QMessageBox.critical( panel.mainwindow, diff --git a/datalab/gui/panel/history/navigation.py b/datalab/gui/panel/history/navigation.py index ad4e7d683..3008e1138 100644 --- a/datalab/gui/panel/history/navigation.py +++ b/datalab/gui/panel/history/navigation.py @@ -38,11 +38,6 @@ def current_action(self) -> HistoryAction | None: except ValueError: return None - def current_panel_str(self) -> str: - """Return the current data panel identifier, defaulting to signal.""" - panel_str = self.panel.mainwindow.get_current_panel() - return panel_str if panel_str in ("signal", "image") else "signal" - def sync_panel_selection(self) -> None: """Synchronize data-panel selection from the selected history item.""" if self.panel.runtime.execution.replaying_active or self.syncing: diff --git a/datalab/gui/panel/history/panel.py b/datalab/gui/panel/history/panel.py index e55bdec0c..1a6b56226 100644 --- a/datalab/gui/panel/history/panel.py +++ b/datalab/gui/panel/history/panel.py @@ -47,8 +47,6 @@ class HistoryPanel( H5_PREFIX = "DataLab_His" - SIG_OBJECT_MODIFIED = QC.Signal() - FILE_FILTERS = f"{_('History files')} (*.dlhist)" def __init__(self, parent: DLMainWindow) -> None: @@ -101,3 +99,8 @@ def remove_all_objects(self) -> None: """Remove all objects.""" super().remove_all_objects() self.runtime.objects.clear_output_mappings() + self.history_sessions = [] + self.navigation.active_session = None + self.navigation.session_increment = 0 + self.tree.populate_tree(self.history_sessions) + self.ui.update_actions_state() diff --git a/datalab/gui/panel/history/recompute.py b/datalab/gui/panel/history/recompute.py index a5d0afb3c..13c05bc29 100644 --- a/datalab/gui/panel/history/recompute.py +++ b/datalab/gui/panel/history/recompute.py @@ -64,22 +64,25 @@ def update_obj_in_place( else: target_obj.data = new_obj.data target_obj.invalidate_maskdata_cache() + # Read everything that may raise AttributeError (missing/None metadata) + # before wiping the target, so a failure cannot leave metadata half-updated. try: saved_uuid = target_obj.metadata.get("__uuid") saved_number = target_obj.metadata.get("__number") # Align with the 1_to_1 path: keep the target's user ROI when the # freshly computed object does not carry one. saved_roi = target_obj.metadata.get(ROI_KEY) - target_obj.metadata.clear() - target_obj.metadata.update(new_obj.metadata) - if saved_uuid is not None: - target_obj.metadata["__uuid"] = saved_uuid - if saved_number is not None: - target_obj.metadata["__number"] = saved_number - if saved_roi is not None and ROI_KEY not in target_obj.metadata: - target_obj.metadata[ROI_KEY] = saved_roi + new_metadata = dict(new_obj.metadata) except AttributeError: - pass + return + target_obj.metadata.clear() + target_obj.metadata.update(new_metadata) + if saved_uuid is not None: + target_obj.metadata["__uuid"] = saved_uuid + if saved_number is not None: + target_obj.metadata["__number"] = saved_number + if saved_roi is not None and ROI_KEY not in target_obj.metadata: + target_obj.metadata[ROI_KEY] = saved_roi def refresh_target(panel_data: BaseDataPanel, output_uuid: str) -> None: @@ -104,6 +107,48 @@ def refresh_target(panel_data: BaseDataPanel, output_uuid: str) -> None: panel_data.SIG_OBJECT_MODIFIED.emit() +def resolve_output_panel( + panel: HistoryPanel, + out_uuid: str, + new_obj: SignalObj | ImageObj | None, + fallback: BaseDataPanel, +) -> BaseDataPanel: + """Return the data panel that owns (or must own) an action output. + + Cross-panel features (e.g. an image line profile producing a signal) + store their output in the panel matching the output type, not in the + panel of the action. Resolution order: the panel whose object model + currently owns ``out_uuid``, then the panel matching the type of + ``new_obj``, then ``fallback`` (the action's panel). + + Args: + panel: History panel instance. + out_uuid: Recorded UUID of the output object. + new_obj: Freshly recomputed output object, or ``None`` when the + output has not been recomputed yet. + fallback: Panel to return when neither the UUID nor the object + type resolves to a panel. + + Returns: + Data panel that owns (or must own) the output object. + """ + # Stub panels in unit tests have no mainwindow: no cross-panel routing + mainwindow = getattr(panel, "mainwindow", None) + if mainwindow is None: + return fallback + signalpanel = mainwindow.signalpanel + imagepanel = mainwindow.imagepanel + if signalpanel.objmodel.has_uuid(out_uuid): + return signalpanel + if imagepanel.objmodel.has_uuid(out_uuid): + return imagepanel + if isinstance(new_obj, SignalObj): + return signalpanel + if isinstance(new_obj, ImageObj): + return imagepanel + return fallback + + def record_missing_outputs( panel: HistoryPanel, action: HistoryAction, missing: list[str] ) -> None: @@ -271,7 +316,6 @@ def recompute_action_in_place(panel: HistoryPanel, action: HistoryAction) -> boo handle_missing_feature(panel, action, exc) except Exception as exc: # pylint: disable=broad-exception-caught action.is_stale = True - panel.runtime.execution.broken_actions.add(action.uuid) _logger.exception( "Cascade recompute failed for action %s (%s): %s", action.uuid, @@ -290,7 +334,6 @@ def handle_missing_feature( ) -> None: """Flag ``action`` as broken (missing plugin) and queue a user warning.""" action.is_stale = True - panel.runtime.execution.broken_actions.add(action.uuid) plugin_origin = action.plugin_origin or exc.plugin_origin or {} directory = (plugin_origin.get("directory") if plugin_origin else None) or "?" param = action.kwargs.get("param") @@ -322,20 +365,50 @@ def recompute_creation_in_place(panel: HistoryPanel, action: HistoryAction) -> b existing output object so its UUID (and downstream references) are kept. If the output object was deleted, it is re-created under its recorded UUID so the downstream chain remains valid. + + Synthetic session heads (e.g. produced by *Duplicate chain*) carry no + creation ``param``: they represent a pre-existing object. As long as + their recorded outputs still exist, they are a no-op success; if the + object was deleted, it cannot be re-created and a warning is queued. """ + name = action.title or action.uuid panel_data = hchain.resolve_panel_for_action(panel, action) if panel_data is None: + panel.runtime.execution.cascade_warnings.append( + _("Action %s: target panel not found — skipping.") % name + ) return False recorded = hchain.recorded_action_output_uuids(panel, action) if not recorded: + panel.runtime.execution.cascade_warnings.append( + _("Action %s: no recorded output object — skipping.") % name + ) return False output_uuid = recorded[0] param = action.kwargs.get("param") if param is None: + # Outputs may live in either panel (cross-panel routing): resolve + # each one before checking existence. + if all( + resolve_output_panel(panel, uuid, None, panel_data).objmodel.has_uuid(uuid) + for uuid in recorded + ): + return True + panel.runtime.execution.cascade_warnings.append( + _( + "Action %s: the initial object was deleted and cannot be " + "re-created (no creation parameters)." + ) + % name + ) return False if action.target == "signalpanel": prepared = prepare_signal_parameters(param, edit=False) if prepared is None: + panel.runtime.execution.cascade_warnings.append( + _("Action %s: creation parameters could not be prepared — skipping.") + % name + ) return False new_obj = create_signal_from_param(prepared) else: @@ -361,9 +434,10 @@ def recompute_1_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> boo if not recorded: return False output_uuid = recorded[0] + output_panel = resolve_output_panel(panel, output_uuid, None, panel_data) output_obj = ( - panel_data.objmodel[output_uuid] - if panel_data.objmodel.has_uuid(output_uuid) + output_panel.objmodel[output_uuid] + if output_panel.objmodel.has_uuid(output_uuid) else None ) pp = extract_processing_parameters(output_obj) if output_obj is not None else None @@ -406,20 +480,27 @@ def recompute_1_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> boo source_uuid=source_uuid, plugin_origin=plugin_origin, ) + output_panel = resolve_output_panel(panel, output_uuid, new_obj, panel_data) if output_obj is not None: # Preserve the existing output's own metadata (ROIs, annotations...) - panel_data.objprop.apply_recomputed_object_in_place(output_obj, new_obj, pp_new) + output_panel.objprop.apply_recomputed_object_in_place( + output_obj, new_obj, pp_new + ) else: apply_output_in_place_or_recreate( panel, - panel_data, + output_panel, action, output_uuid, new_obj, pp_new, - group_id=panel_data.objmodel.get_object_group_id(source_obj), + group_id=( + panel_data.objmodel.get_object_group_id(source_obj) + if output_panel is panel_data + else None + ), ) - refresh_target(panel_data, output_uuid) + refresh_target(output_panel, output_uuid) return True @@ -436,18 +517,29 @@ def recompute_1_to_n_in_place(panel: HistoryPanel, action: HistoryAction) -> boo recorded = hchain.recorded_action_output_uuids(panel, action) if not recorded or not params: return False + # Resolve against the first recorded output still owned by a panel, so a + # deleted recorded[0] does not fall back to the wrong (action) panel. + resolve_uuid = next( + ( + u + for u in recorded + if resolve_output_panel(panel, u, None, panel_data).objmodel.has_uuid(u) + ), + recorded[0], + ) + output_panel = resolve_output_panel(panel, resolve_uuid, None, panel_data) if len(recorded) != len(params): # Legacy or inconsistent recording: outputs cannot be aligned with # the parameter list, so recreation is impossible. record_missing_outputs( panel, action, - [u for u in recorded if not panel_data.objmodel.has_uuid(u)], + [u for u in recorded if not output_panel.objmodel.has_uuid(u)], ) return False - existing = [u for u in recorded if panel_data.objmodel.has_uuid(u)] + existing = [u for u in recorded if output_panel.objmodel.has_uuid(u)] pp = ( - extract_processing_parameters(panel_data.objmodel[existing[0]]) + extract_processing_parameters(output_panel.objmodel[existing[0]]) if existing else None ) @@ -487,15 +579,22 @@ def recompute_1_to_n_in_place(panel: HistoryPanel, action: HistoryAction) -> boo % (action.func_name or action.uuid, len(new_objs), len(recorded)) ) return False - group_id = panel_data.objmodel.get_object_group_id(source_obj) + output_panel = resolve_output_panel(panel, recorded[0], new_objs[0], panel_data) + group_id = ( + panel_data.objmodel.get_object_group_id(source_obj) + if output_panel is panel_data + else None + ) snapshots = { - out_uuid: copy.deepcopy(panel_data.objmodel[out_uuid]) for out_uuid in existing + out_uuid: copy.deepcopy(output_panel.objmodel[out_uuid]) + for out_uuid in existing + if output_panel.objmodel.has_uuid(out_uuid) } try: for idx, out_uuid in enumerate(recorded): apply_output_in_place_or_recreate( panel, - panel_data, + output_panel, action, out_uuid, new_objs[idx], @@ -509,13 +608,13 @@ def recompute_1_to_n_in_place(panel: HistoryPanel, action: HistoryAction) -> boo group_id=group_id, ) for out_uuid in recorded: - refresh_target(panel_data, out_uuid) + refresh_target(output_panel, out_uuid) except Exception: for out_uuid, snapshot in snapshots.items(): - update_obj_in_place(panel_data.objmodel[out_uuid], snapshot) + update_obj_in_place(output_panel.objmodel[out_uuid], snapshot) for out_uuid in snapshots: try: - refresh_target(panel_data, out_uuid) + refresh_target(output_panel, out_uuid) except Exception: _logger.exception( "Cascade recompute rollback refresh failed for output %s.", @@ -538,9 +637,10 @@ def recompute_n_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> boo if not recorded: return False output_uuid = recorded[0] + output_panel = resolve_output_panel(panel, output_uuid, None, panel_data) output_obj = ( - panel_data.objmodel[output_uuid] - if panel_data.objmodel.has_uuid(output_uuid) + output_panel.objmodel[output_uuid] + if output_panel.objmodel.has_uuid(output_uuid) else None ) pp = extract_processing_parameters(output_obj) if output_obj is not None else None @@ -568,9 +668,10 @@ def recompute_n_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> boo ) if not isinstance(new_obj, (SignalObj, ImageObj)): return False + output_panel = resolve_output_panel(panel, output_uuid, new_obj, panel_data) apply_output_in_place_or_recreate( panel, - panel_data, + output_panel, action, output_uuid, new_obj, @@ -581,9 +682,13 @@ def recompute_n_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> boo source_uuids=[get_uuid(o) for o in src_objs], plugin_origin=plugin_origin, ), - group_id=panel_data.objmodel.get_object_group_id(src_objs[0]), + group_id=( + panel_data.objmodel.get_object_group_id(src_objs[0]) + if output_panel is panel_data + else None + ), ) - refresh_target(panel_data, output_uuid) + refresh_target(output_panel, output_uuid) return True @@ -600,6 +705,7 @@ def recompute_2_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> boo recorded = hchain.recorded_action_output_uuids(panel, action) if not recorded: return False + output_panel = resolve_output_panel(panel, recorded[0], None, panel_data) param = action.kwargs.get("param") obj2_uuids = action.kwargs.get("obj2_uuids") or [] if isinstance(obj2_uuids, str): @@ -616,8 +722,8 @@ def recompute_2_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> boo ] = [] for idx, out_uuid in enumerate(recorded): pp = ( - extract_processing_parameters(panel_data.objmodel[out_uuid]) - if panel_data.objmodel.has_uuid(out_uuid) + extract_processing_parameters(output_panel.objmodel[out_uuid]) + if output_panel.objmodel.has_uuid(out_uuid) else None ) src_uuids = ( @@ -685,16 +791,17 @@ def recompute_2_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> boo if not isinstance(new_obj, (SignalObj, ImageObj)): return False staged.append((out_uuid, new_obj, obj1, obj2, plugin_origin)) + output_panel = resolve_output_panel(panel, recorded[0], staged[0][1], panel_data) snapshots = { - out_uuid: copy.deepcopy(panel_data.objmodel[out_uuid]) + out_uuid: copy.deepcopy(output_panel.objmodel[out_uuid]) for out_uuid, *_rest in staged - if panel_data.objmodel.has_uuid(out_uuid) + if output_panel.objmodel.has_uuid(out_uuid) } try: for out_uuid, new_obj, obj1, obj2, plugin_origin in staged: apply_output_in_place_or_recreate( panel, - panel_data, + output_panel, action, out_uuid, new_obj, @@ -705,19 +812,23 @@ def recompute_2_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> boo source_uuids=[get_uuid(obj1), get_uuid(obj2)], plugin_origin=plugin_origin, ), - group_id=panel_data.objmodel.get_object_group_id(obj1), + group_id=( + panel_data.objmodel.get_object_group_id(obj1) + if output_panel is panel_data + else None + ), ) for out_uuid, *_rest in staged: - refresh_target(panel_data, out_uuid) + refresh_target(output_panel, out_uuid) if source_transaction is not None: for _out_uuid, _new_obj, obj1, _obj2, _origin in staged: source_transaction.commit(obj1) except Exception: for out_uuid, snapshot in snapshots.items(): - update_obj_in_place(panel_data.objmodel[out_uuid], snapshot) + update_obj_in_place(output_panel.objmodel[out_uuid], snapshot) for out_uuid in snapshots: try: - refresh_target(panel_data, out_uuid) + refresh_target(output_panel, out_uuid) except Exception: _logger.exception( "Cascade recompute rollback refresh failed for output %s.", @@ -879,10 +990,7 @@ def recompute_cascade( if not descendants: flush_cascade_warnings(panel) return - with panel.runtime.execution.recomputing_cascade() as started: - if not started: - flush_cascade_warnings(panel) - return + with panel.runtime.execution.recomputing_cascade(): for action in descendants: action.is_stale = True panel.tree.refresh_action_item(action) diff --git a/datalab/gui/panel/history/runtime.py b/datalab/gui/panel/history/runtime.py index 253657f73..de55f27b6 100644 --- a/datalab/gui/panel/history/runtime.py +++ b/datalab/gui/panel/history/runtime.py @@ -29,7 +29,6 @@ def __init__(self) -> None: self.cascade_in_progress = False self.edit_replay_in_progress = False self.cascade_warnings: list[str] = [] - self.broken_actions: set[str] = set() @contextmanager def replaying(self) -> Generator[None, None, None]: @@ -79,7 +78,6 @@ def recomputing_cascade(self) -> Generator[bool, None, None]: if self.cascade_in_progress: yield False return - self.broken_actions.clear() self.cascade_in_progress = True try: yield True diff --git a/datalab/history/action.py b/datalab/history/action.py index c87a10f96..43aebfe93 100644 --- a/datalab/history/action.py +++ b/datalab/history/action.py @@ -348,15 +348,12 @@ def __iter_param_kwargs(self) -> Generator[Any, None, None]: def description(self) -> str: """Return object description (string representing function parameters)""" desc = "" - no_parameters = True for param in self.__iter_param_kwargs(): if desc: desc += os.linesep desc += str(param) - no_parameters = False - if desc or no_parameters: - if desc: - return desc + if desc: + return desc # Fall back to a textual hint of the resolved callable return self.__fallback_doc() @@ -455,16 +452,14 @@ def __roi_exclusions(self) -> set[str] | None: return set(self.target_uuids or []) return None - def is_current_state_compatible( - self, mainwindow: DLMainWindow, restore_selection: bool - ) -> bool: + def is_current_state_compatible(self, mainwindow: DLMainWindow) -> bool: """Check if the current workspace state is compatible with the saved state. Mutation actions exclude their own targets from the ROI signature comparison (the recorded state contains the post-mutation ROI). """ return self.state.is_current_state_compatible( - mainwindow, restore_selection, ignore_roi_uuids=self.__roi_exclusions() + mainwindow, ignore_roi_uuids=self.__roi_exclusions() ) def restore(self, mainwindow: DLMainWindow) -> None: diff --git a/datalab/history/core.py b/datalab/history/core.py index 5fe370dc1..c1d0fc437 100644 --- a/datalab/history/core.py +++ b/datalab/history/core.py @@ -8,7 +8,6 @@ import importlib import json -import logging import warnings from copy import deepcopy from typing import Any @@ -21,7 +20,6 @@ from datalab.config import _ -_logger = logging.getLogger(__name__) _TRUSTED_ROI_MODULE_PREFIX = "sigima." # Schema versions for persisted history sessions/actions. diff --git a/datalab/history/session.py b/datalab/history/session.py index b912aecd5..1a7e624dc 100644 --- a/datalab/history/session.py +++ b/datalab/history/session.py @@ -18,9 +18,12 @@ class HistorySession: """Object representing a history session, i.e. a list of actions. - A history session is a list of actions that can be replayed in the same order - as they were added to the history session. The history session can be saved to - a file and loaded from a file. + A history session groups, in chronological order, the actions forming a + processing chain. Compute actions are recomputed in place by the History + panel recompute engine (:meth:`HistoryAction.replay` raises + ``NotImplementedError`` for the compute kind); UI and mutation actions + are replayed through :meth:`HistoryAction.replay`. The session can be + saved to a file and loaded from a file. Args: title: Title of the history session @@ -75,22 +78,17 @@ def copy_with_uuid_remap( ] return session - def is_current_state_compatible( - self, mainwindow: DLMainWindow, restore_selection: bool - ) -> bool: + def is_current_state_compatible(self, mainwindow: DLMainWindow) -> bool: """Check if the current workspace state is compatible with the saved state Args: mainwindow: DataLab's main window - restore_selection: True to restore the selection before checking the state Returns: bool: True if the current workspace state is compatible with the saved state """ if self.actions: - return self.actions[0].is_current_state_compatible( - mainwindow, restore_selection - ) + return self.actions[0].is_current_state_compatible(mainwindow) return True def restore(self, mainwindow: DLMainWindow) -> None: @@ -134,16 +132,3 @@ def deserialize(self, reader: NativeH5Reader) -> None: with reader.group("dtstr"): self.dtstr = reader.read_any() self.actions = reader.read_object_list("actions", HistoryAction) - - def remove_action(self, action: HistoryAction) -> None: - """Remove an action from the history session - - This implies removing all subsequent actions. If action is not found, this - fails silently. - - Args: - action: Action to remove - """ - if action in self.actions: - index = self.actions.index(action) - self.actions = self.actions[:index] diff --git a/datalab/history/workspace_state.py b/datalab/history/workspace_state.py index 7cd798aa0..277d9a318 100644 --- a/datalab/history/workspace_state.py +++ b/datalab/history/workspace_state.py @@ -238,10 +238,9 @@ def save(self, mainwindow: DLMainWindow, panel_str: str | None = None) -> None: get_uuid(obj): self.get_object_metadata(obj) for obj in panel.objmodel } - def is_current_state_compatible( # pylint: disable=unused-argument + def is_current_state_compatible( self, mainwindow: DLMainWindow, - restore_selection: bool, ignore_roi_uuids: set[str] | None = None, ) -> bool: """Check if the current workspace state is compatible with the saved state. @@ -256,9 +255,6 @@ def is_current_state_compatible( # pylint: disable=unused-argument Args: mainwindow: DataLab's main window - restore_selection: Unused (kept for API symmetry). With UUID-based - identity, the compatibility check no longer depends on the current - selection -- it only depends on object existence. ignore_roi_uuids: UUIDs whose ROI signature must be excluded from the comparison (both saved and current sides). Used by mutation actions whose state was captured after the mutation was applied: @@ -311,7 +307,7 @@ def restore( if not self.selection: return if not self.is_current_state_compatible( - mainwindow, False, ignore_roi_uuids=ignore_roi_uuids + mainwindow, ignore_roi_uuids=ignore_roi_uuids ): raise ValueError( "Current workspace state is not compatible with saved state" diff --git a/datalab/tests/features/common/history_effects_unit_test.py b/datalab/tests/features/common/history_effects_unit_test.py deleted file mode 100644 index 758cbe743..000000000 --- a/datalab/tests/features/common/history_effects_unit_test.py +++ /dev/null @@ -1,263 +0,0 @@ -# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. - -""" -History effects unit test -------------------------- - -Test the analysis effects manifest (:mod:`datalab.history.effects`): -capture of metadata/ROI mutations during 1-to-0 analyses, persistence on -:class:`HistoryAction` and HDF5 round-trip (action schema v2). -""" - -# pylint: disable=invalid-name # Allows short reference names like x, y, ... -# guitest: show - -from __future__ import annotations - -import copy -import os -import tempfile -from unittest.mock import patch - -import numpy as np -import sigima.params as sigima_param -from sigima.objects import Gauss2DParam, create_image_from_param, create_image_roi -from sigima.tests.data import create_peak_image - -from datalab.config import Conf -from datalab.env import execenv -from datalab.gui.panel.history import recompute as hrec -from datalab.h5.native import NativeH5Writer -from datalab.history.effects import AnalysisEffects, capture_effects, merge_effects -from datalab.history.session import HistorySession -from datalab.objectmodel import get_uuid -from datalab.tests import datalab_test_app_context -from datalab.tests.features.common.history_test_helpers import ( - build_history_action, - delete_hdf5_items_by_name, - read_history_sessions, -) - - -def test_capture_effects_metadata_diff() -> None: - """Capture added/replaced metadata keys, excluding bookkeeping keys.""" - obj = create_image_from_param(Gauss2DParam.create(height=16, width=16)) - obj.metadata["untouched"] = 1 - obj.metadata["changed_scalar"] = 5 - obj.metadata["changed_array"] = np.arange(3) - with capture_effects(obj) as effects: - obj.metadata["new_key"] = "hello" - obj.metadata["changed_scalar"] = 6 - obj.metadata["changed_array"] = np.arange(4) - obj.metadata["__uuid"] = "synthetic-uuid" - obj.metadata["__number"] = 42 - assert effects.metadata_added == ["new_key"] - assert effects.metadata_replaced == ["changed_array", "changed_scalar"] - assert "untouched" not in effects.metadata_added - assert "untouched" not in effects.metadata_replaced - assert "__uuid" not in effects.metadata_added - assert "__number" not in effects.metadata_added - assert effects.roi_modified is False - execenv.print("test_capture_effects_metadata_diff: ✓") - - -def test_capture_effects_roi_modified() -> None: - """Detect ROI creation inside the capture window.""" - obj = create_image_from_param(Gauss2DParam.create(height=16, width=16)) - with capture_effects(obj) as effects: - pass - assert effects.roi_modified is False - with capture_effects(obj) as effects: - obj.roi = create_image_roi("rectangle", [2, 2, 5, 5]) - assert effects.roi_modified is True - execenv.print("test_capture_effects_roi_modified: ✓") - - -def test_analysis_effects_dict_round_trip() -> None: - """Round-trip AnalysisEffects through to_dict/from_dict.""" - effects = AnalysisEffects( - metadata_added=["Geometry_peak_detection_dict"], - metadata_replaced=["analysis_parameters"], - roi_modified=True, - ) - payload = effects.to_dict() - assert payload == { - "metadata_added": ["Geometry_peak_detection_dict"], - "metadata_replaced": ["analysis_parameters"], - "roi_modified": True, - } - assert AnalysisEffects.from_dict(payload) == effects - assert AnalysisEffects.from_dict({}) == AnalysisEffects() - execenv.print("test_analysis_effects_dict_round_trip: ✓") - - -def test_analysis_effects_populated_by_1_to_0_compute() -> None: - """Populate the action effects manifest through a real 1-to-0 analysis.""" - with datalab_test_app_context(console=False, history=True) as win: - execenv.print("History effects integration test (image peak detection):") - history = win.historypanel - history.toggle_record_mode(True) - panel = win.imagepanel - img = create_peak_image() - panel.add_object(img) - - det_param = sigima_param.Peak2DDetectionParam.create( - create_rois=True, threshold=0.5 - ) - with Conf.proc.show_result_dialog.temp(False): - panel.processor.run_feature("peak_detection", det_param) - - action = history[len(history)] - assert action.effects is not None, "1-to-0 action must carry effects" - src_uuid = get_uuid(img) - assert src_uuid in action.effects - manifest = AnalysisEffects.from_dict(action.effects[src_uuid]) - assert any( - key.startswith("Geometry_") and key.endswith("_dict") - for key in manifest.metadata_added - ), f"Expected a Geometry_*_dict key, got {manifest.metadata_added}" - assert manifest.roi_modified is True, "Detection ROIs must flag roi_modified" - execenv.print(" ✓ Effects manifest populated with source uuid and keys") - - -def test_merge_effects() -> None: - """Merge manifests: added-stays-added, sticky roi_modified, sorted output.""" - new = AnalysisEffects( - metadata_added=["b", "a"], metadata_replaced=["c"], roi_modified=False - ) - merged = merge_effects(None, new) - assert merged == AnalysisEffects(["a", "b"], ["c"], False) - # Keys created on the first run stay "added" even though a recompute - # observes them as replaced - previous = AnalysisEffects(metadata_added=["result"], roi_modified=True) - recomputed = AnalysisEffects(metadata_replaced=["result", "params"]) - merged = merge_effects(previous, recomputed) - assert merged.metadata_added == ["result"] - assert merged.metadata_replaced == ["params"] - # roi_modified is sticky: True on first run stays True after a recompute - assert merged.roi_modified is True - execenv.print("test_merge_effects: ✓") - - -def test_recompute_updates_effects_manifest() -> None: - """Keep first-run keys under metadata_added after a history recompute.""" - with datalab_test_app_context(console=False, history=True) as win: - execenv.print("History effects recompute integration test:") - history = win.historypanel - history.toggle_record_mode(True) - panel = win.imagepanel - img = create_peak_image() - panel.add_object(img) - det_param = sigima_param.Peak2DDetectionParam.create( - create_rois=True, threshold=0.5 - ) - with Conf.proc.show_result_dialog.temp(False): - panel.processor.run_feature("peak_detection", det_param) - action = history[len(history)] - src_uuid = get_uuid(img) - added_before = AnalysisEffects.from_dict( - action.effects[src_uuid] - ).metadata_added - assert added_before, "First run must have recorded added keys" - - success = hrec.recompute_1_to_0_in_place(history, action) - - assert success is True - manifest = AnalysisEffects.from_dict(action.effects[src_uuid]) - assert set(added_before) <= set(manifest.metadata_added), ( - "First-run keys must stay under metadata_added after recompute" - ) - assert not set(added_before) & set(manifest.metadata_replaced) - execenv.print(" ✓ Manifest keys stayed 'added' after recompute") - - -def test_targeted_rollback_preserves_unrelated_metadata() -> None: - """Roll back only manifest keys when a manifest-driven recompute fails.""" - with datalab_test_app_context(console=False, history=True) as win: - execenv.print("History effects targeted rollback test:") - history = win.historypanel - history.toggle_record_mode(True) - panel = win.imagepanel - img = create_peak_image() - panel.add_object(img) - det_param = sigima_param.Peak2DDetectionParam.create( - create_rois=False, threshold=0.5 - ) - with Conf.proc.show_result_dialog.temp(False): - panel.processor.run_feature("peak_detection", det_param) - action = history[len(history)] - src_uuid = get_uuid(img) - manifest = AnalysisEffects.from_dict(action.effects[src_uuid]) - manifest_keys = manifest.metadata_added + manifest.metadata_replaced - geometry_key = next(key for key in manifest_keys if key.startswith("Geometry_")) - # Simulate a user having deleted one analysis result key beforehand - del img.metadata[geometry_key] - present_key = next(key for key in manifest_keys if key in img.metadata) - value_before = copy.deepcopy(img.metadata[present_key]) - img.metadata["user_marker"] = 123 - effects_before = copy.deepcopy(action.effects) - - def failing_recompute(_func_name, obj, _param, plugin_origin=None): - del plugin_origin - obj.metadata[geometry_key] = "recreated-by-failed-attempt" - obj.metadata[present_key] = "corrupted" - raise RuntimeError("forced recompute failure") - - with patch.object( - panel.processor, "recompute_1_to_0", side_effect=failing_recompute - ): - try: - hrec.recompute_1_to_0_in_place(history, action) - except RuntimeError: - pass - else: - raise AssertionError("RuntimeError should have propagated") - - assert img.metadata["user_marker"] == 123, "Unrelated key must be untouched" - assert geometry_key not in img.metadata, ( - "Manifest key absent before the recompute must be deleted on rollback" - ) - assert img.metadata[present_key] == value_before, ( - "Manifest key must be restored to its pre-recompute value" - ) - assert action.effects == effects_before, "Manifest must be unchanged" - execenv.print(" ✓ Targeted rollback restored only manifest keys") - - -def test_action_effects_hdf5_round_trip_and_legacy() -> None: - """Round-trip effects through HDF5 and tolerate legacy files without it.""" - action = build_history_action() - action.effects = { - "source-uuid": AnalysisEffects( - metadata_added=["Geometry_peak_detection_dict"], - metadata_replaced=["analysis_parameters"], - roi_modified=True, - ).to_dict() - } - session = HistorySession(number=1) - session.add_action(action) - with tempfile.TemporaryDirectory() as tmpdir: - path = os.path.join(tmpdir, "history.dlhist") - with NativeH5Writer(path) as writer: - writer.write_object_list([session], "history_session") - loaded = read_history_sessions(path)[0].actions[0] - assert loaded.effects == action.effects - # Legacy tolerance: files without the effects group deserialize to None - with NativeH5Writer(path) as writer: - writer.write_object_list([session], "history_session") - delete_hdf5_items_by_name(writer.h5, "effects") - legacy = read_history_sessions(path)[0].actions[0] - assert legacy.effects is None - execenv.print("test_action_effects_hdf5_round_trip_and_legacy: ✓") - - -if __name__ == "__main__": - execenv.unattended = True # Auto-close dialogs and event loops (standalone run) - test_capture_effects_metadata_diff() - test_capture_effects_roi_modified() - test_analysis_effects_dict_round_trip() - test_merge_effects() - test_analysis_effects_populated_by_1_to_0_compute() - test_recompute_updates_effects_manifest() - test_targeted_rollback_preserves_unrelated_metadata() - test_action_effects_hdf5_round_trip_and_legacy() diff --git a/datalab/tests/features/common/history_model_unit_test.py b/datalab/tests/features/common/history_model_unit_test.py index 3cafa5be1..c95a7cced 100644 --- a/datalab/tests/features/common/history_model_unit_test.py +++ b/datalab/tests/features/common/history_model_unit_test.py @@ -13,35 +13,44 @@ import numpy as np import pytest -from sigima.objects import Gauss2DParam, ImageObj, create_signal_roi +from sigima.objects import ( + Gauss2DParam, + ImageObj, + SignalROI, + create_image_from_param, + create_image_roi, + create_signal_roi, +) from sigima.tests.data import create_paracetamol_signal from datalab.gui import historysession_ops as hsess from datalab.gui import historytools_ops as hops -from datalab.gui.creation import ( - create_image_from_param, - extract_creation_parameters, -) from datalab.gui.main import DLMainWindow from datalab.gui.panel.history import chain as hchain from datalab.gui.panel.history import interactive_replay as hireplay from datalab.gui.panel.history import recompute as hrec from datalab.gui.panel.history import runtime as hruntime -from datalab.gui.panel.history.ui import HistoryPanelUI +from datalab.gui.panel.history.chainmodel import ProcessingChain, UuidCloneRegistry from datalab.gui.processor.base import ( BaseProcessor, + FeatureNotFoundError, ProcessingParameters, extract_processing_parameters, insert_processing_parameters, ) from datalab.h5.native import NativeH5Reader, NativeH5Writer from datalab.history.action import HistoryAction -from datalab.history.core import HISTORY_ACTION_SCHEMA_VERSION, HISTORY_SCHEMA_VERSION -from datalab.history.effects import AnalysisEffects +from datalab.history.core import ( + HISTORY_ACTION_SCHEMA_VERSION, + HISTORY_SCHEMA_VERSION, + numpy_to_json_safe, +) +from datalab.history.effects import AnalysisEffects, capture_effects, merge_effects from datalab.history.session import HistorySession from datalab.history.workspace_state import WorkspaceState -from datalab.objectmodel import get_uuid, set_uuid +from datalab.objectmodel import get_uuid from datalab.tests.features.common.history_test_helpers import ( + CascadeObjectModel, build_history_action, build_workspace_state, delete_hdf5_items_by_name, @@ -49,25 +58,6 @@ ) -class CascadeObjectModel: - """Minimal object model for pure cascade recomputation tests.""" - - def __init__(self, objects: list[ImageObj]) -> None: - self.objects = {get_uuid(obj): obj for obj in objects} - - def __getitem__(self, uuid: str) -> ImageObj: - """Return the image identified by ``uuid``.""" - return self.objects[uuid] - - def has_uuid(self, uuid: str) -> bool: - """Return whether ``uuid`` exists in the model.""" - return uuid in self.objects - - def get_object_ids(self) -> list[str]: - """Return all object UUIDs in insertion order.""" - return list(self.objects) - - class PromptExecution: """Minimal execution state for input-session prompt tests.""" @@ -98,10 +88,6 @@ class PromptNavigation: def __init__(self, active_session: HistorySession | None) -> None: self.active_session = active_session - def current_panel_str(self) -> str: - """Return the fallback panel used for per-action panel resolution.""" - return "signal" - def get_active_session(self) -> HistorySession | None: """Return the single active recording session.""" return self.active_session @@ -280,61 +266,6 @@ def average(_objects: list[object]) -> None: assert history_panel.add_compute_entry_from_pp.call_args.args[0] == "Moyenne" -@pytest.mark.parametrize("column", (0, 2)) -@pytest.mark.parametrize("selected_kind", ("action", "session")) -def test_history_tree_double_click_replays_current_selection_without_restoring( - selected_kind: str, column: int -) -> None: - """Replay the current action or session selection from either tree column.""" - if selected_kind == "action": - selected_row: HistoryAction | HistorySession = HistoryAction() - expected_actions = [selected_row] - else: - selected_row = HistorySession() - selected_row.add_action(HistoryAction()) - selected_row.add_action(HistoryAction()) - expected_actions = list(selected_row.actions) - selected_row.is_current_state_compatible = Mock(return_value=True) - clicked_row = HistoryAction() - tree = SimpleNamespace( - customContextMenuRequested=Mock(), - itemDoubleClicked=Mock(), - itemSelectionChanged=Mock(), - get_selected_actions_or_sessions=Mock(return_value=[selected_row]), - ) - mainwindow = object() - panel = SimpleNamespace( - tree=tree, - history_sessions=[], - mainwindow=mainwindow, - refresh_compatibility_items=Mock(), - replaying=nullcontext, - output_suppressed=nullcontext, - runtime=SimpleNamespace(execution=SimpleNamespace(edit_mode=False)), - navigation=SimpleNamespace( - sync_panel_selection=Mock(), - update_state_widget=Mock(), - set_active_session_from_selection=Mock(), - ), - ) - panel.replay_restore_actions = lambda **kwargs: hireplay.replay_restore_actions( - panel, **kwargs - ) - ui = HistoryPanelUI.__new__(HistoryPanelUI) - ui.panel = panel - - ui.setup_connections() - double_click_slot = tree.itemDoubleClicked.connect.call_args.args[0] - with patch.object(hireplay, "replay_actions") as replay_actions_mock: - double_click_slot(clicked_row, column) - - selected_row.is_current_state_compatible.assert_called_once_with( - mainwindow, restore_selection=False - ) - replay_actions_mock.assert_called_once_with(panel, expected_actions, prompt=False) - assert clicked_row not in replay_actions_mock.call_args.args[1] - - def test_image_creation_extends_active_signal_session_when_rejected() -> None: """Chain an image creation into the single active recording session.""" signal_session = make_prompt_session("signal", populated=True) @@ -373,58 +304,55 @@ def test_empty_active_session_skips_prompt() -> None: assert panel.created_sessions == [] -def test_omitted_session_behavior_reads_live_general_policy() -> None: - """Resolve the general policy on every omitted-behavior call.""" - image_session = make_prompt_session("image", populated=True) - panel = PromptPanel([image_session]) - option = hsess.Conf.proc.history_new_session_behavior - - with patch.object(option, "get", side_effect=["no", "yes"]) as get_behavior: - first_created = panel.maybe_start_session_for_input() - second_created = panel.maybe_start_session_for_input() - - assert first_created is False - assert second_created is True - assert len(panel.created_sessions) == 1 - assert panel.prompt_behaviors == [None, None] - assert get_behavior.call_count == 2 - +@pytest.mark.parametrize( + ("behavior", "policy_values", "expected_created"), + ( + (None, ("no", "yes"), (False, True)), + ("yes", ("ask",), (True,)), + ("no", ("ask",), (False,)), + ("invalid", (), None), + ), +) +def test_session_behavior_policy_matrix( + behavior: str | None, + policy_values: tuple[str, ...], + expected_created: tuple[bool, ...] | None, +) -> None: + """Resolve omitted, explicit and invalid session policies without dialogs. -def test_explicit_session_behaviors_bypass_prompt() -> None: - """Apply explicit yes/no policies without debounce or a dialog.""" - cases: tuple[tuple[hsess.SessionBehavior, bool], ...] = ( - ("yes", True), - ("no", False), - ) - attended = SimpleNamespace(unattended=False, accept_dialogs=False) - for behavior, expected_created in cases: - image_session = make_prompt_session("image", populated=True) - panel = PromptPanel([image_session]) - with ( - patch.object(hsess, "execenv", attended), - patch.object(hsess.QW, "QMessageBox") as message_box, - ): - created = panel.maybe_start_session_for_input(behavior=behavior) - assert created is expected_created - assert panel.runtime.execution.prompt_count == 0 - assert len(panel.created_sessions) == (1 if expected_created else 0) - message_box.question.assert_not_called() - - -def test_invalid_session_behavior_has_no_side_effects() -> None: - """Reject an invalid policy before debounce or session creation.""" + Omitted behaviors re-read the live general policy on every call, explicit + yes/no policies bypass both debounce and dialog, and invalid policies are + rejected before any side effect. + """ image_session = make_prompt_session("image", populated=True) panel = PromptPanel([image_session]) - - with pytest.raises(ValueError, match="Invalid session behavior"): - hsess.maybe_start_session_for_input( - panel, - behavior=cast(hsess.SessionBehavior, "invalid"), - ) - + attended = SimpleNamespace(unattended=False, accept_dialogs=False) + option = hsess.Conf.proc.history_new_session_behavior + with ( + patch.object(hsess, "execenv", attended), + patch.object(hsess.QW, "QMessageBox") as message_box, + patch.object(option, "get", side_effect=list(policy_values)) as get_policy, + ): + if expected_created is None: + with pytest.raises(ValueError, match="Invalid session behavior"): + panel.maybe_start_session_for_input( + behavior=cast(hsess.SessionBehavior, behavior) + ) + created = [] + else: + created = [ + panel.maybe_start_session_for_input( + behavior=cast(hsess.SessionBehavior, behavior) + ) + for _call in policy_values + ] + assert created == list(expected_created or ()) + assert len(panel.created_sessions) == sum(created) assert panel.runtime.execution.prompt_count == 0 - assert panel.created_sessions == [] - assert panel.history_sessions == [image_session] + message_box.question.assert_not_called() + assert get_policy.call_count == (len(policy_values) if behavior is None else 0) + if expected_created is None: + assert panel.history_sessions == [image_session] def test_accepted_prompt_routes_action_to_new_session() -> None: @@ -468,13 +396,19 @@ def test_accepted_prompt_replaces_active_session() -> None: def test_input_prompt_debounce_is_global() -> None: - """Debounce a synchronous burst of prompts on a single timer window.""" + """Debounce a synchronous prompt burst and keep routing in place. + + Only the first prompt of a synchronous burst opens a dialog; while the + debounce window is pending, further creations are routed to the active + session without starting a new one or prompting again. + """ signal_session = make_prompt_session("signal", populated=True) panel = PromptPanel([signal_session]) + panel.mainwindow = None # dialog parent for the patched QMessageBox execution = hruntime.HistoryExecutionState() panel.runtime = SimpleNamespace(execution=execution) callbacks = [] - unattended = SimpleNamespace(unattended=True, accept_dialogs=False) + attended = SimpleNamespace(unattended=False, accept_dialogs=False) with ( patch.object( @@ -482,15 +416,42 @@ def test_input_prompt_debounce_is_global() -> None: "singleShot", side_effect=lambda _delay, callback: callbacks.append(callback), ), - patch.object(hsess, "execenv", unattended), + patch.object(hsess, "execenv", attended), + patch.object(hsess.QW, "QMessageBox") as message_box, + patch.object( + hsess.Conf.proc.history_new_session_behavior, "get", return_value="ask" + ), ): + # First call passes the debounce and opens the (rejected) dialog assert not hsess.maybe_start_session_for_input(panel, behavior="ask") + # Second call is debounced: no second dialog assert not hsess.maybe_start_session_for_input(panel, behavior="ask") + # Creation entries routed during the window stay in the active session + action = hsess.add_ui_entry( + panel, + "New image", + target="imagepanel", + method_name="new_object", + save_state=False, + ) + assert message_box.question.call_count == 1 assert execution.session_input_pending is True assert len(callbacks) == 1 + assert panel.created_sessions == [] + assert panel.navigation.get_active_session() is signal_session + assert signal_session.actions[-1] is action callbacks[0]() assert execution.session_input_pending is False + # Re-entrance guards yield False when already active + with execution.recomputing_cascade() as started: + assert started is True + with execution.recomputing_cascade() as nested: + assert nested is False + with execution.replaying_edits() as started: + assert started is True + with execution.replaying_edits() as nested: + assert nested is False def test_ui_entries_serialize_data_target_ownership() -> None: @@ -636,32 +597,6 @@ def test_image_histogram_action_keeps_image_ownership_in_active_session() -> Non assert image_session.actions == image_actions + [action] -def test_debounce_rejection_does_not_start_or_prompt() -> None: - """Keep routing in the active session when debounce rejects.""" - image_session = make_prompt_session("image", populated=True) - panel = PromptPanel([image_session], prompt_allowed=False) - attended = SimpleNamespace(unattended=False, accept_dialogs=True) - with ( - patch.object(hsess, "execenv", attended), - patch.object(hsess.QW, "QMessageBox") as message_box, - patch.object( - hsess.Conf.proc.history_new_session_behavior, "get", return_value="ask" - ), - ): - action = hsess.add_ui_entry( - panel, - "New image", - target="imagepanel", - method_name="new_object", - save_state=False, - ) - assert panel.runtime.execution.prompt_count == 1 - assert panel.created_sessions == [] - assert panel.navigation.get_active_session() is image_session - assert image_session.actions[-1] is action - message_box.question.assert_not_called() - - def test_unattended_reject_keeps_populated_active_session() -> None: """Leave the active session untouched after unattended rejection.""" image_session = make_prompt_session("image", populated=True) @@ -886,175 +821,383 @@ def test_state_compatibility_handles_roi_signature_and_legacy_metadata() -> None state.selection = {"signal": [uuid]} recorded = WorkspaceState.get_object_metadata(obj) state.object_metadata = {"signal": {uuid: recorded}} - assert state.is_current_state_compatible(mainwindow, False) + assert state.is_current_state_compatible(mainwindow) # Legacy tolerance: metadata recorded without "roi" vs current object with ROI legacy = dict(recorded) del legacy["roi"] state.object_metadata = {"signal": {uuid: legacy}} - assert state.is_current_state_compatible(mainwindow, False) + assert state.is_current_state_compatible(mainwindow) # ROI drift against a recorded signature flags incompatibility state.object_metadata = {"signal": {uuid: dict(recorded, roi="0" * 16)}} - assert not state.is_current_state_compatible(mainwindow, False) - - -def test_edited_image_creation_recomputes_downstream_in_place() -> None: - """Regenerate an edited image before recomputing its existing descendant.""" - initial_param = Gauss2DParam.create( - title="Initial Gaussian", - height=24, - width=28, - x0=-4.0, - y0=2.0, - sigma=1.2, - a=25.0, + assert not state.is_current_state_compatible(mainwindow) + + +def test_mutation_action_model_contract() -> None: + """Round-trip, copy and remap mutation actions with and without payload.""" + + def roi_as_dict(roi: SignalROI) -> dict: + return numpy_to_json_safe(roi.to_dict()) + + def build_mutation_action(payload: SignalROI | None) -> HistoryAction: + return HistoryAction( + title="Edit regions of interest", + kind=HistoryAction.KIND_MUTATION, + panel_str="signal", + mutation_key="roi", + target_uuids=["first-uuid", "second-uuid"], + kwargs={"payload": payload}, + ) + + def roundtrip(action: HistoryAction) -> HistoryAction: + session = HistorySession(number=1) + session.add_action(action) + with tempfile.TemporaryDirectory() as tmpdir: + path = os.path.join(tmpdir, "history.dlhist") + with NativeH5Writer(path) as writer: + writer.write_object_list([session], "history_session") + return read_history_sessions(path)[0].actions[0] + + payload = create_signal_roi([[26, 41], [125, 146]], indices=True) + loaded = roundtrip(build_mutation_action(payload)) + assert loaded.kind == HistoryAction.KIND_MUTATION + assert loaded.mutation_key == "roi" + assert loaded.target_uuids == ["first-uuid", "second-uuid"] + assert loaded.panel_str == "signal" + loaded_payload = loaded.kwargs.get("payload") + assert isinstance(loaded_payload, SignalROI) + assert type(loaded_payload) is type(payload) + assert roi_as_dict(loaded_payload) == roi_as_dict(payload) + # A None payload (ROI deletion) is dropped at construction time and + # decoded back as a missing kwarg + deletion = build_mutation_action(None) + assert "payload" not in deletion.kwargs + loaded = roundtrip(deletion) + assert loaded.kind == HistoryAction.KIND_MUTATION + assert loaded.target_uuids == ["first-uuid", "second-uuid"] + assert loaded.kwargs.get("payload") is None + # Copies are independent; UUID remapping rewrites the mutation targets + action = build_mutation_action(create_signal_roi([[26, 41]], indices=True)) + copied = action.copy() + assert copied is not action and copied.uuid != action.uuid + assert copied.mutation_key == "roi" + assert copied.target_uuids == action.target_uuids + assert copied.target_uuids is not action.target_uuids + assert roi_as_dict(copied.kwargs["payload"]) == roi_as_dict( + action.kwargs["payload"] ) - edited_param = Gauss2DParam.create( - title="Edited Gaussian", - height=24, - width=28, - x0=3.0, - y0=-2.0, - sigma=3.5, - a=80.0, + remapped = action.copy_with_uuid_remap( + {"signal": {"first-uuid": "new-first", "second-uuid": "new-second"}} ) - source = create_image_from_param(initial_param) - source_uuid = get_uuid(source) - source_identity = id(source) - initial_source_data = source.data.copy() - expected_source = create_image_from_param(edited_param) - - downstream = source.copy() - set_uuid(downstream) - downstream.title = "Initial downstream" - downstream.data = np.full(source.data.shape, -1.0) - downstream_uuid = get_uuid(downstream) - downstream_identity = id(downstream) - initial_downstream_data = downstream.data.copy() - insert_processing_parameters( - downstream, - ProcessingParameters( - func_name="unit_transform", - pattern="1-to-1", - source_uuid=source_uuid, + assert remapped.target_uuids == ["new-first", "new-second"] + assert action.target_uuids == ["first-uuid", "second-uuid"] + + +def test_capture_effects_metadata_and_roi_diff() -> None: + """Diff metadata keys and flag only genuine ROI changes.""" + obj = create_image_from_param(Gauss2DParam.create(height=16, width=16)) + obj.metadata["untouched"] = 1 + obj.metadata["changed_scalar"] = 5 + obj.metadata["changed_array"] = np.arange(3) + with capture_effects(obj) as effects: + obj.metadata["new_key"] = "hello" + obj.metadata["changed_scalar"] = 6 + obj.metadata["changed_array"] = np.arange(4) + obj.metadata["__uuid"] = "synthetic-uuid" + obj.metadata["__number"] = 42 + assert effects.metadata_added == ["new_key"] + assert effects.metadata_replaced == ["changed_array", "changed_scalar"] + assert "untouched" not in effects.metadata_added + effects.metadata_replaced + assert "__uuid" not in effects.metadata_added + assert "__number" not in effects.metadata_added + assert effects.roi_modified is False + # No ROI before/after: unmodified + with capture_effects(obj) as effects: + pass + assert effects.roi_modified is False + # ROI creation flags the capture + with capture_effects(obj) as effects: + obj.roi = create_image_roi("rectangle", [2, 2, 5, 5]) + assert effects.roi_modified is True + # An existing ROI left untouched by the analysis is not modified + with capture_effects(obj) as effects: + obj.metadata["another_key"] = 0 + assert effects.roi_modified is False + # Re-assigning an equal ROI is not a modification (relies on ROI equality) + with capture_effects(obj) as effects: + obj.roi = create_image_roi("rectangle", [2, 2, 5, 5]) + assert effects.roi_modified is False + # Changing the ROI geometry is a modification + with capture_effects(obj) as effects: + obj.roi = create_image_roi("rectangle", [3, 3, 6, 6]) + assert effects.roi_modified is True + + +def test_analysis_effects_round_trip_merge_and_persistence() -> None: + """Round-trip manifests through dict/HDF5 and merge recompute captures.""" + effects = AnalysisEffects( + metadata_added=["Geometry_peak_detection_dict"], + metadata_replaced=["analysis_parameters"], + roi_modified=True, + ) + payload = effects.to_dict() + assert payload == { + "metadata_added": ["Geometry_peak_detection_dict"], + "metadata_replaced": ["analysis_parameters"], + "roi_modified": True, + } + assert AnalysisEffects.from_dict(payload) == effects + assert AnalysisEffects.from_dict({}) == AnalysisEffects() + # Merge semantics: added-stays-added, sticky roi_modified, sorted output + new = AnalysisEffects( + metadata_added=["b", "a"], metadata_replaced=["c"], roi_modified=False + ) + merged = merge_effects(None, new) + assert merged == AnalysisEffects(["a", "b"], ["c"], False) + previous = AnalysisEffects(metadata_added=["result"], roi_modified=True) + recomputed = AnalysisEffects(metadata_replaced=["result", "params"]) + merged = merge_effects(previous, recomputed) + assert merged.metadata_added == ["result"] + assert merged.metadata_replaced == ["params"] + assert merged.roi_modified is True + # HDF5 round-trip on an action, with legacy tolerance (no effects group) + action = build_history_action() + action.effects = {"source-uuid": payload} + session = HistorySession(number=1) + session.add_action(action) + with tempfile.TemporaryDirectory() as tmpdir: + path = os.path.join(tmpdir, "history.dlhist") + with NativeH5Writer(path) as writer: + writer.write_object_list([session], "history_session") + loaded = read_history_sessions(path)[0].actions[0] + assert loaded.effects == action.effects + with NativeH5Writer(path) as writer: + writer.write_object_list([session], "history_session") + delete_hdf5_items_by_name(writer.h5, "effects") + legacy = read_history_sessions(path)[0].actions[0] + assert legacy.effects is None + + +def test_update_obj_in_place_preserves_roi() -> None: + """In-place recompute keeps the target's ROI when the new object has none.""" + target = create_paracetamol_signal() + target.roi = create_signal_roi([[10, 20]], indices=True) + saved_roi_dict = numpy_to_json_safe(target.roi.to_dict()) + new_obj = create_paracetamol_signal() + assert new_obj.roi is None + hrec.update_obj_in_place(target, new_obj) + assert target.roi is not None + assert numpy_to_json_safe(target.roi.to_dict()) == saved_roi_dict + + +def test_recompute_dispatch_guards_and_missing_feature() -> None: + """Reject non-recomputable actions and diagnose missing plugin features.""" + warnings: list[str] = [] + panel = SimpleNamespace( + runtime=SimpleNamespace(execution=SimpleNamespace(cascade_warnings=warnings)), + mainwindow=SimpleNamespace( + signalpanel=SimpleNamespace(objmodel=CascadeObjectModel([])), + imagepanel=SimpleNamespace(objmodel=CascadeObjectModel([])), ), ) + # Non-creation UI actions are silently not recomputable + noncompute = HistoryAction(kind=HistoryAction.KIND_UI, method_name="select_next") + assert hrec.recompute_action_in_place(panel, noncompute) is False + assert warnings == [] + # Unsupported compute patterns queue a warning + unsupported = HistoryAction( + kind=HistoryAction.KIND_COMPUTE, func_name="mystery", pattern="3_to_2" + ) + assert hrec.recompute_action_in_place(panel, unsupported) is False + assert any("mystery" in warning for warning in warnings) + # A missing plugin feature flags the action and queues a diagnostic + action = HistoryAction( + kind=HistoryAction.KIND_COMPUTE, func_name="plugin_func", pattern="1_to_1" + ) + error = FeatureNotFoundError( + "plugin_func", + plugin_origin={"directory": "myplugin"}, + paramclass_name="MyParam", + ) + with patch.object(hrec, "recompute_1_to_1_in_place", side_effect=error): + assert hrec.recompute_action_in_place(panel, action) is False + assert action.is_stale is True + assert any( + "myplugin/plugins:plugin_func" in warning and "MyParam" in warning + for warning in warnings + ) + # Mutation guards: unresolved data panel, then no recorded targets + orphan_mutation = HistoryAction( + title="Edit ROI", kind=HistoryAction.KIND_MUTATION, mutation_key="roi" + ) + assert hrec.recompute_action_in_place(panel, orphan_mutation) is False + targetless = HistoryAction( + title="Edit ROI", + kind=HistoryAction.KIND_MUTATION, + panel_str="signal", + mutation_key="roi", + ) + assert hrec.recompute_action_in_place(panel, targetless) is False + assert sum("Edit ROI" in warning for warning in warnings) == 2 + - creation_action = HistoryAction( - title="Create edited Gaussian", +def test_find_creation_action_for_output_fallback_scan() -> None: + """Fall back to scanning creation outputs when the mapping is stale.""" + creation = HistoryAction( + title="New signal", kind=HistoryAction.KIND_UI, - target="imagepanel", + target="signalpanel", method_name="new_object", - kwargs={"param": edited_param}, ) - creation_action.output_uuids = [source_uuid] - downstream_state = WorkspaceState() - downstream_state.selection = {"image": [source_uuid]} - downstream_action = HistoryAction( - title="Transform edited Gaussian", - kind=HistoryAction.KIND_COMPUTE, - panel_str="image", - func_name="unit_transform", - pattern="1_to_1", - state=downstream_state, + compute = HistoryAction( + kind=HistoryAction.KIND_COMPUTE, func_name="derivative", pattern="1_to_1" ) - downstream_action.output_uuids = [downstream_uuid] session = HistorySession(number=1) - session.add_action(creation_action) - session.add_action(downstream_action) + session.add_action(creation) + session.add_action(compute) + runtime = SimpleNamespace( + objects=SimpleNamespace( + output_to_action={"created-uuid": compute.uuid}, + action_output_uuids={creation.uuid: ["created-uuid"]}, + ) + ) + panel = SimpleNamespace(history_sessions=[session], runtime=runtime) + # The mapped action is not a creation: the fallback scan finds the head + assert hchain.find_creation_action_for_output(panel, "created-uuid") is creation + assert hchain.find_creation_action_for_output(panel, "unknown-uuid") is None + empty = SimpleNamespace(history_sessions=[]) + assert hchain.find_creation_action_for_output(empty, "created-uuid") is None - processor_source_objects: list[ImageObj] = [] - processor_source_data: list[np.ndarray] = [] - def recompute_1_to_1( - func_name: str | None, - source_obj: ImageObj, - param: object, - *, - plugin_origin: dict[str, object] | None, - ) -> SimpleNamespace: - assert func_name == "unit_transform" - assert param is None - assert plugin_origin is None - processor_source_objects.append(source_obj) - processor_source_data.append(source_obj.data.copy()) - new_obj = source_obj.copy() - new_obj.title = f"unit_transform({source_obj.title})" - new_obj.data = source_obj.data.astype(float) * 2.0 + 3.0 - return SimpleNamespace(cancelled=False, error_msg=None, result=new_obj) - - def apply_recomputed_object_in_place( - obj: ImageObj, - new_obj: ImageObj, - proc_params: ProcessingParameters, - ) -> None: - hrec.update_obj_in_place(obj, new_obj) - insert_processing_parameters(obj, proc_params) - - object_model = CascadeObjectModel([source, downstream]) - data_panel = SimpleNamespace( - PANEL_STR_ID="image", - objmodel=object_model, - processor=SimpleNamespace(recompute_1_to_1=recompute_1_to_1), - objprop=SimpleNamespace( - apply_recomputed_object_in_place=apply_recomputed_object_in_place +def test_plan_reconnection_dead_source_warning_and_producer_removal() -> None: + """Warn on dead sources, then reconnect and remove the dead producer.""" + source = create_paracetamol_signal() + source_uuid = get_uuid(source) + removed_uuid = "removed-output" + consumer_obj = create_paracetamol_signal() + consumer_uuid = get_uuid(consumer_obj) + insert_processing_parameters( + consumer_obj, + ProcessingParameters( + func_name="derivative", pattern="1-to-1", source_uuid=removed_uuid ), ) - runtime = SimpleNamespace( - objects=SimpleNamespace( - action_output_uuids={ - creation_action.uuid: [source_uuid], - downstream_action.uuid: [downstream_uuid], - } - ), - execution=SimpleNamespace(cascade_warnings=[], broken_actions=set()), + producer = HistoryAction( + title="Normalize", + kind=HistoryAction.KIND_COMPUTE, + panel_str="signal", + func_name="normalize", + pattern="1_to_1", + state=build_workspace_state([source_uuid]), ) - history_panel = SimpleNamespace( - runtime=runtime, - history_sessions=[session], + producer.output_uuids = [removed_uuid] + consumer_action = HistoryAction( + title="Derivative", + kind=HistoryAction.KIND_COMPUTE, + panel_str="signal", + func_name="derivative", + pattern="1_to_1", + state=build_workspace_state([removed_uuid]), ) - refreshed_uuids: list[str] = [] - - def record_refresh(panel_data: object, output_uuid: str) -> None: - assert panel_data is data_panel - refreshed_uuids.append(output_uuid) - - descendants = hrec.hchain.get_downstream_actions(history_panel, creation_action) - assert descendants == [downstream_action] + session = HistorySession(number=1) + session.add_action(producer) + session.add_action(consumer_action) + def make_panel(objects: list) -> tuple[SimpleNamespace, SimpleNamespace]: + signal_panel = SimpleNamespace( + PANEL_STR_ID="signal", objmodel=CascadeObjectModel(objects) + ) + panel = SimpleNamespace( + history_sessions=[session], + runtime=SimpleNamespace( + objects=SimpleNamespace( + output_to_action={removed_uuid: producer.uuid}, + action_output_uuids={producer.uuid: [removed_uuid]}, + remove_action_outputs=Mock(), + ) + ), + mainwindow=SimpleNamespace( + signalpanel=signal_panel, + imagepanel=SimpleNamespace( + PANEL_STR_ID="image", objmodel=CascadeObjectModel([]) + ), + ), + ) + return panel, signal_panel + + # Dead source: the plan carries a warning and applying it is a no-op + panel, signal_panel = make_panel([consumer_obj]) + plan = hchain.plan_reconnection(panel, signal_panel, removed_uuid) + assert plan.warning is not None and "Normalize" in plan.warning + assert [target.object_uuid for target in plan.targets] == [consumer_uuid] + assert plan.targets[0].action is consumer_action + roots: list[HistoryAction] = [] + hchain.apply_reconnection_plan(panel, signal_panel, plan, roots) + assert roots == [] + assert extract_processing_parameters(consumer_obj).source_uuid == removed_uuid + # Reconnection warnings are silenced in unattended mode with ( - patch.object(hrec.hchain, "resolve_panel_for_action", return_value=data_panel), - patch.object( - hrec, "create_image_from_param", wraps=create_image_from_param - ) as create_image_mock, - patch.object(hrec, "refresh_target", side_effect=record_refresh), + patch.object(hchain, "execenv", SimpleNamespace(unattended=True)), + patch.object(hchain.QW, "QMessageBox") as message_box, ): - assert hrec.recompute_creation_in_place(history_panel, creation_action) - assert hrec.recompute_1_to_1_in_place(history_panel, downstream_action) - - create_image_mock.assert_called_once() - assert create_image_mock.call_args.args[0] is edited_param - - assert id(source) == source_identity - assert object_model[source_uuid] is source - assert get_uuid(source) == source_uuid - np.testing.assert_allclose(source.data, expected_source.data) - assert not np.array_equal(source.data, initial_source_data) - creation_param = extract_creation_parameters(source) - assert isinstance(creation_param, Gauss2DParam) - for name in ("height", "width", "x0", "y0", "sigma", "a"): - assert getattr(creation_param, name) == getattr(edited_param, name) - - assert processor_source_objects == [source] - np.testing.assert_allclose(processor_source_data[0], expected_source.data) - assert id(downstream) == downstream_identity - assert object_model[downstream_uuid] is downstream - assert get_uuid(downstream) == downstream_uuid - np.testing.assert_allclose( - downstream.data, expected_source.data.astype(float) * 2.0 + 3.0 + hchain.show_reconnection_warnings(panel, [plan.warning]) + message_box.warning.assert_not_called() + + # Alive source: reconnect the consumer and remove the outputless producer + panel, signal_panel = make_panel([source, consumer_obj]) + plan = hchain.plan_reconnection(panel, signal_panel, removed_uuid) + assert plan.warning is None + assert plan.source_uuid == source_uuid + assert plan.remove_producer is True + roots = [] + hchain.apply_reconnection_plan(panel, signal_panel, plan, roots) + assert roots == [consumer_action] + assert extract_processing_parameters(consumer_obj).source_uuid == source_uuid + assert consumer_action.state.selection["signal"] == [source_uuid] + assert producer not in session.actions + panel.runtime.objects.remove_action_outputs.assert_called_once_with(producer) + + +def test_prepare_action_param_edit_skips_paramless_actions() -> None: + """Return no edit target (and skip the dialog) for param-less actions.""" + paramless = ( + HistoryAction(kind=HistoryAction.KIND_UI, method_name="new_object"), + HistoryAction(kind=HistoryAction.KIND_COMPUTE, pattern="1_to_1"), + HistoryAction(kind=HistoryAction.KIND_COMPUTE, pattern="1_to_n"), + HistoryAction(kind=HistoryAction.KIND_MUTATION, mutation_key="roi"), + ) + panel = SimpleNamespace(mainwindow=None) + for action in paramless: + assert hireplay.prepare_action_param_edit(action) is None + assert hireplay.prompt_edit_action_params(panel, action) is None + + +def test_make_synthetic_heads_falls_back_to_default_title() -> None: + """Use the default head title when the cloned object cannot be resolved.""" + root = HistoryAction( + kind=HistoryAction.KIND_COMPUTE, + panel_str="signal", + func_name="derivative", + pattern="1_to_1", + state=build_workspace_state(["external-uuid"]), + ) + chain = ProcessingChain(root=root, session=HistorySession(number=1), actions=[root]) + registry = UuidCloneRegistry() + registry.register("signal", "external-uuid", "clone-uuid", object()) + + class RaisingModel: + """Object model whose lookups always fail.""" + + def __getitem__(self, uuid: str) -> None: + raise KeyError(uuid) + + panel = SimpleNamespace( + mainwindow=SimpleNamespace( + signalpanel=SimpleNamespace(objmodel=RaisingModel()), imagepanel=None + ) ) - assert not np.array_equal(downstream.data, initial_downstream_data) - downstream_params = extract_processing_parameters(downstream) - assert downstream_params is not None - assert downstream_params.source_uuid == source_uuid - assert refreshed_uuids == [source_uuid, downstream_uuid] - assert runtime.execution.cascade_warnings == [] + heads = hops.make_synthetic_heads(panel, chain, registry) + assert len(heads) == 1 + head = heads[0] + assert head.method_name == "new_object" + assert head.output_uuids == ["clone-uuid"] + assert head.title == hops._("Initial state") diff --git a/datalab/tests/features/common/history_mutation_model_unit_test.py b/datalab/tests/features/common/history_mutation_model_unit_test.py deleted file mode 100644 index fe582e260..000000000 --- a/datalab/tests/features/common/history_mutation_model_unit_test.py +++ /dev/null @@ -1,89 +0,0 @@ -# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. - -"""Pure unit contracts for mutation-kind history actions.""" - -from __future__ import annotations - -import os -import tempfile - -from sigima.objects import SignalROI, create_signal_roi - -from datalab.h5.native import NativeH5Writer -from datalab.history.action import HistoryAction -from datalab.history.core import numpy_to_json_safe -from datalab.history.session import HistorySession -from datalab.tests.features.common.history_test_helpers import read_history_sessions - - -def roi_as_dict(roi: SignalROI) -> dict: - """Return a plain-Python (comparable) dict representation of a ROI.""" - return numpy_to_json_safe(roi.to_dict()) - - -def build_mutation_action(payload: SignalROI | None) -> HistoryAction: - """Build a ROI mutation action targeting two signal objects.""" - return HistoryAction( - title="Edit regions of interest", - kind=HistoryAction.KIND_MUTATION, - panel_str="signal", - mutation_key="roi", - target_uuids=["first-uuid", "second-uuid"], - kwargs={"payload": payload}, - ) - - -def roundtrip_action(action: HistoryAction) -> HistoryAction: - """Serialize an action to HDF5 and return its deserialized counterpart.""" - session = HistorySession(number=1) - session.add_action(action) - with tempfile.TemporaryDirectory() as tmpdir: - path = os.path.join(tmpdir, "history.dlhist") - with NativeH5Writer(path) as writer: - writer.write_object_list([session], "history_session") - return read_history_sessions(path)[0].actions[0] - - -def test_mutation_action_hdf5_roundtrip() -> None: - """Round-trip a ROI mutation action with its payload and identity fields.""" - payload = create_signal_roi([[26, 41], [125, 146]], indices=True) - action = build_mutation_action(payload) - loaded = roundtrip_action(action) - assert loaded.kind == HistoryAction.KIND_MUTATION - assert loaded.mutation_key == "roi" - assert loaded.target_uuids == ["first-uuid", "second-uuid"] - assert loaded.panel_str == "signal" - loaded_payload = loaded.kwargs.get("payload") - assert isinstance(loaded_payload, SignalROI) - assert type(loaded_payload) is type(payload) - assert roi_as_dict(loaded_payload) == roi_as_dict(payload) - - -def test_mutation_action_deletion_payload_roundtrip() -> None: - """Decode a missing payload kwarg as None (ROI deletion).""" - action = build_mutation_action(None) - # None kwargs are dropped at construction/encoding time: a deletion - # mutation simply has no "payload" kwarg on disk. - assert "payload" not in action.kwargs - loaded = roundtrip_action(action) - assert loaded.kind == HistoryAction.KIND_MUTATION - assert loaded.mutation_key == "roi" - assert loaded.target_uuids == ["first-uuid", "second-uuid"] - assert loaded.kwargs.get("payload") is None - - -def test_mutation_action_copy_and_uuid_remap() -> None: - """Copy a mutation action independently and remap its target UUIDs.""" - payload = create_signal_roi([[26, 41]], indices=True) - action = build_mutation_action(payload) - copied = action.copy() - assert copied is not action and copied.uuid != action.uuid - assert copied.mutation_key == "roi" - assert copied.target_uuids == action.target_uuids - assert copied.target_uuids is not action.target_uuids - assert roi_as_dict(copied.kwargs["payload"]) == roi_as_dict(payload) - remapped = action.copy_with_uuid_remap( - {"signal": {"first-uuid": "new-first", "second-uuid": "new-second"}} - ) - assert remapped.target_uuids == ["new-first", "new-second"] - assert action.target_uuids == ["first-uuid", "second-uuid"] diff --git a/datalab/tests/features/common/history_panel_test.py b/datalab/tests/features/common/history_panel_test.py index 01679fa45..e57b34dee 100644 --- a/datalab/tests/features/common/history_panel_test.py +++ b/datalab/tests/features/common/history_panel_test.py @@ -4,13 +4,23 @@ from __future__ import annotations +from contextlib import nullcontext +from types import SimpleNamespace +from unittest.mock import Mock, patch + +import pytest import sigima.proc.image as sipi import sigima.proc.signal as sips from qtpy import QtCore as QC from qtpy import QtWidgets as QW from sigima.tests.data import create_paracetamol_signal, create_sincos_image +from datalab.gui import historytools_ops as htools from datalab.gui.panel.history import HistoryTree +from datalab.gui.panel.history import interactive_replay as hireplay +from datalab.gui.panel.history.ui import HistoryPanelUI +from datalab.history.action import HistoryAction +from datalab.history.session import HistorySession from datalab.objectmodel import get_uuid from datalab.tests import datalab_test_app_context from datalab.tests.features.common.history_test_helpers import ( @@ -21,6 +31,59 @@ ) +@pytest.mark.parametrize("column", (0, 2)) +@pytest.mark.parametrize("selected_kind", ("action", "session")) +def test_history_tree_double_click_replays_current_selection_without_restoring( + selected_kind: str, column: int +) -> None: + """Replay the current action or session selection from either tree column.""" + if selected_kind == "action": + selected_row: HistoryAction | HistorySession = HistoryAction() + expected_actions = [selected_row] + else: + selected_row = HistorySession() + selected_row.add_action(HistoryAction()) + selected_row.add_action(HistoryAction()) + expected_actions = list(selected_row.actions) + selected_row.is_current_state_compatible = Mock(return_value=True) + clicked_row = HistoryAction() + tree = SimpleNamespace( + customContextMenuRequested=Mock(), + itemDoubleClicked=Mock(), + itemSelectionChanged=Mock(), + get_selected_actions_or_sessions=Mock(return_value=[selected_row]), + ) + mainwindow = object() + panel = SimpleNamespace( + tree=tree, + history_sessions=[], + mainwindow=mainwindow, + refresh_compatibility_items=Mock(), + replaying=nullcontext, + output_suppressed=nullcontext, + runtime=SimpleNamespace(execution=SimpleNamespace(edit_mode=False)), + navigation=SimpleNamespace( + sync_panel_selection=Mock(), + update_state_widget=Mock(), + set_active_session_from_selection=Mock(), + ), + ) + panel.replay_restore_actions = lambda **kwargs: hireplay.replay_restore_actions( + panel, **kwargs + ) + ui = HistoryPanelUI.__new__(HistoryPanelUI) + ui.panel = panel + + ui.setup_connections() + double_click_slot = tree.itemDoubleClicked.connect.call_args.args[0] + with patch.object(hireplay, "replay_actions") as replay_actions_mock: + double_click_slot(clicked_row, column) + + selected_row.is_current_state_compatible.assert_called_once_with(mainwindow) + replay_actions_mock.assert_called_once_with(panel, expected_actions, prompt=False) + assert clicked_row not in replay_actions_mock.call_args.args[1] + + def test_panel_replay_restores_selection_without_outputs() -> None: """Use panel replay to restore selection without recording or new output.""" with datalab_test_app_context(history=True) as win: @@ -150,3 +213,23 @@ def test_cross_panel_sessions_navigation_and_tree_state() -> None: and image_item.foreground(0).color().isValid() and image_item.data(0, QC.Qt.UserRole) == image_action.uuid ) + # Remove-incompatible tool purges flagged actions and keeps the rest + incompatible = [ + action + for session in history.history_sessions + for action in session.actions + if not action.is_current_state_compatible(win) + ] + assert image_action in incompatible + htools.remove_incompatible_actions(history) + remaining = [ + action for session in history.history_sessions for action in session.actions + ] + assert not [action for action in incompatible if action in remaining] + assert all(action.is_current_state_compatible(win) for action in remaining) + assert all(session.actions for session in history.history_sessions) + # Second run: everything is compatible, nothing changes + htools.remove_incompatible_actions(history) + assert [ + action for session in history.history_sessions for action in session.actions + ] == remaining diff --git a/datalab/tests/features/common/history_roi_mutation_test.py b/datalab/tests/features/common/history_roi_mutation_test.py deleted file mode 100644 index 9cee5d12b..000000000 --- a/datalab/tests/features/common/history_roi_mutation_test.py +++ /dev/null @@ -1,194 +0,0 @@ -# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. - -"""Unified ROI mutation recording and replay in the History panel.""" - -# guitest: show - -from __future__ import annotations - -import sigima.proc.signal as sips -from sigima.objects import create_signal_roi -from sigima.tests.data import create_paracetamol_signal - -from datalab.gui.panel.history import chain as hchain -from datalab.gui.panel.history import recompute as hrec -from datalab.history.action import HistoryAction -from datalab.history.core import numpy_to_json_safe -from datalab.objectmodel import get_uuid -from datalab.tests import datalab_test_app_context - -SIZE = 200 -SROI1 = [26, 41] -SROI2 = [125, 146] - - -def test_paste_roi_records_mutation_entry() -> None: - """Pasting a ROI records a per-object mutation entry with the final ROI.""" - with datalab_test_app_context(history=True) as win: - history, panel = win.historypanel, win.signalpanel - history.toggle_record_mode(True) - sig1 = create_paracetamol_signal(SIZE) - sig1.roi = create_signal_roi([SROI1, SROI2], indices=True) - panel.add_object(sig1) - sig2 = create_paracetamol_signal(SIZE) - panel.add_object(sig2) - sig2 = panel.objmodel[get_uuid(sig2)] - # Seed the clipboard from the first signal, then paste on the second - panel.objview.select_objects([1]) - panel.copy_roi() - panel.objview.select_objects([2]) - panel.paste_roi() - action = history.history_sessions[-1].actions[-1] - assert action.kind == HistoryAction.KIND_MUTATION - assert action.mutation_key == "roi" - assert action.target_uuids == [get_uuid(sig2)] - payload = action.kwargs.get("payload") - assert payload is not None - # Payload is the object's post-combination ROI (round-trip check) - assert numpy_to_json_safe(payload.to_dict()) == numpy_to_json_safe( - sig2.roi.to_dict() - ) - - -def test_delete_rois_records_mutation_and_replays() -> None: - """Deleting ROIs records an empty-payload mutation; session replay works.""" - with datalab_test_app_context(history=True) as win: - history, panel = win.historypanel, win.signalpanel - history.toggle_record_mode(True) - sig1 = create_paracetamol_signal(SIZE) - sig1.roi = create_signal_roi([SROI1], indices=True) - panel.add_object(sig1) - sig2 = create_paracetamol_signal(SIZE) - panel.add_object(sig2) - sig2 = panel.objmodel[get_uuid(sig2)] - # Apply ROI to sig2 (records mutation #1 with payload) - panel.objview.select_objects([1]) - panel.copy_roi() - panel.objview.select_objects([2]) - panel.paste_roi() - assert sig2.roi is not None - # Remove all ROIs from sig2 (records mutation #2 without payload) - panel.processor.delete_regions_of_interest() - assert sig2.roi is None - actions = history.history_sessions[-1].actions - apply_action, delete_action = actions[-2], actions[-1] - assert delete_action.kind == HistoryAction.KIND_MUTATION - assert delete_action.mutation_key == "roi" - assert delete_action.target_uuids == [get_uuid(sig2)] - assert delete_action.kwargs.get("payload") is None - # Replaying the session in order restores the ROI, then removes it - apply_action.replay(win, restore_selection=True, edit=False) - assert sig2.roi is not None - delete_action.replay(win, restore_selection=True, edit=False) - assert sig2.roi is None - - -def test_mutation_replay_applies_roi_to_targets() -> None: - """Direct mutation replay re-applies the ROI payload to target objects.""" - with datalab_test_app_context(history=True) as win: - history, panel = win.historypanel, win.signalpanel - history.toggle_record_mode(True) - sig1 = create_paracetamol_signal(SIZE) - sig1.roi = create_signal_roi([SROI1, SROI2], indices=True) - panel.add_object(sig1) - sig2 = create_paracetamol_signal(SIZE) - panel.add_object(sig2) - sig2 = panel.objmodel[get_uuid(sig2)] - panel.objview.select_objects([1]) - panel.copy_roi() - panel.objview.select_objects([2]) - panel.paste_roi() - action = history.history_sessions[-1].actions[-1] - assert action.kind == HistoryAction.KIND_MUTATION - # Clear the ROI, then replay the mutation directly - sig2.roi = None - action.replay(win, restore_selection=True, edit=False) - assert sig2.roi is not None - assert numpy_to_json_safe(sig2.roi.to_dict()) == numpy_to_json_safe( - action.kwargs["payload"].to_dict() - ) - - -def test_cascade_reapplies_roi_mutation() -> None: - """Cascade recompute re-applies a downstream ROI mutation on the output.""" - with datalab_test_app_context(history=True) as win: - history, panel = win.historypanel, win.signalpanel - history.toggle_record_mode(True) - sig1 = create_paracetamol_signal(SIZE) - sig1.roi = create_signal_roi([SROI1, SROI2], indices=True) - panel.add_object(sig1) - src = create_paracetamol_signal(SIZE) - panel.add_object(src) - # Record a compute action producing the output object - panel.objview.select_objects([2]) - panel.processor.run_feature(sips.derivative) - compute_action = history[len(history)] - output = panel.objmodel[compute_action.output_uuids[0]] - # Paste a ROI onto the compute output (records a mutation action) - panel.objview.select_objects([1]) - panel.copy_roi() - panel.objview.select_objects([get_uuid(output)]) - panel.paste_roi() - mutation_action = history.history_sessions[-1].actions[-1] - assert mutation_action.kind == HistoryAction.KIND_MUTATION - # The mutation belongs to the compute action's downstream closure - downstream = hchain.get_downstream_actions(history, compute_action) - assert mutation_action in downstream - # Wipe the ROI, then recompute the cascade from the compute action - output.roi = None - history.recompute_cascade(compute_action) - assert output.roi is not None - assert numpy_to_json_safe(output.roi.to_dict()) == numpy_to_json_safe( - mutation_action.kwargs["payload"].to_dict() - ) - assert mutation_action.is_stale is False - - -def test_update_obj_in_place_preserves_roi() -> None: - """In-place recompute keeps the target's ROI when the new object has none.""" - with datalab_test_app_context(history=True) as win: - panel = win.signalpanel - target = create_paracetamol_signal(SIZE) - target.roi = create_signal_roi([SROI1], indices=True) - panel.add_object(target) - target = panel.objmodel[get_uuid(target)] - saved_roi_dict = numpy_to_json_safe(target.roi.to_dict()) - new_obj = create_paracetamol_signal(SIZE) - assert new_obj.roi is None - hrec.update_obj_in_place(target, new_obj) - assert target.roi is not None - assert numpy_to_json_safe(target.roi.to_dict()) == saved_roi_dict - - -def test_mutation_root_has_downstream_computes() -> None: - """A mutation root seeds its targets: consuming computes are downstream.""" - with datalab_test_app_context(history=True) as win: - history, panel = win.historypanel, win.signalpanel - history.toggle_record_mode(True) - sig1 = create_paracetamol_signal(SIZE) - sig1.roi = create_signal_roi([SROI1], indices=True) - panel.add_object(sig1) - sig2 = create_paracetamol_signal(SIZE) - panel.add_object(sig2) - panel.objview.select_objects([1]) - panel.copy_roi() - panel.objview.select_objects([2]) - panel.paste_roi() - mutation_action = history.history_sessions[-1].actions[-1] - assert mutation_action.kind == HistoryAction.KIND_MUTATION - # Compute consuming the mutated object is downstream of the mutation - panel.objview.select_objects([2]) - panel.processor.run_feature(sips.derivative) - compute_action = history.history_sessions[-1].actions[-1] - assert compute_action.kind == HistoryAction.KIND_COMPUTE - downstream = hchain.get_downstream_actions(history, mutation_action) - assert compute_action in downstream - - -if __name__ == "__main__": - test_paste_roi_records_mutation_entry() - test_delete_rois_records_mutation_and_replays() - test_mutation_replay_applies_roi_to_targets() - test_cascade_reapplies_roi_mutation() - test_update_obj_in_place_preserves_roi() - test_mutation_root_has_downstream_computes() diff --git a/datalab/tests/features/common/history_test_helpers.py b/datalab/tests/features/common/history_test_helpers.py index b55ba55b7..fada09779 100644 --- a/datalab/tests/features/common/history_test_helpers.py +++ b/datalab/tests/features/common/history_test_helpers.py @@ -17,12 +17,36 @@ from datalab.history.action import HistoryAction from datalab.history.session import HistorySession from datalab.history.workspace_state import WorkspaceState +from datalab.objectmodel import get_uuid if TYPE_CHECKING: from datalab.gui.panel.history import HistoryPanel from datalab.gui.panel.signal import SignalPanel +class CascadeObjectModel: + """Minimal object model for pure cascade recomputation tests.""" + + def __init__(self, objects: list[Any]) -> None: + self.objects = {get_uuid(obj): obj for obj in objects} + + def __getitem__(self, uuid: str) -> Any: + """Return the object identified by ``uuid``.""" + return self.objects[uuid] + + def __iter__(self): + """Iterate over the model's objects.""" + return iter(self.objects.values()) + + def has_uuid(self, uuid: str) -> bool: + """Return whether ``uuid`` exists in the model.""" + return uuid in self.objects + + def get_object_ids(self) -> list[str]: + """Return all object UUIDs in insertion order.""" + return list(self.objects) + + @dataclass(frozen=True) class SignalChain: """Objects and actions produced by a three-step signal chain.""" diff --git a/datalab/tests/features/common/history_workflow_test.py b/datalab/tests/features/common/history_workflow_test.py index f6fc223f3..0a3e49dc6 100644 --- a/datalab/tests/features/common/history_workflow_test.py +++ b/datalab/tests/features/common/history_workflow_test.py @@ -4,18 +4,27 @@ from __future__ import annotations +import copy import os import tempfile from types import SimpleNamespace from unittest.mock import patch import numpy as np +import pytest import sigima.params import sigima.proc.signal as sips -from sigima.tests.data import create_paracetamol_signal, create_sincos_image +from sigima.objects import Gauss2DParam, ImageObj, create_signal_roi +from sigima.tests.data import ( + create_paracetamol_signal, + create_peak_image, + create_sincos_image, +) from datalab.adapters_metadata.common import ResultData +from datalab.config import Conf from datalab.gui import historytools_ops as htools +from datalab.gui.creation import create_image_from_param, extract_creation_parameters from datalab.gui.panel.history import HistoryAction from datalab.gui.panel.history import chain as hchain from datalab.gui.panel.history import interactive_replay as hireplay @@ -32,9 +41,14 @@ ) from datalab.gui.processor.catcher import CompOut from datalab.h5.native import NativeH5Reader, NativeH5Writer -from datalab.objectmodel import get_uuid +from datalab.history.core import numpy_to_json_safe +from datalab.history.effects import AnalysisEffects +from datalab.history.session import HistorySession +from datalab.history.workspace_state import WorkspaceState +from datalab.objectmodel import get_uuid, set_uuid from datalab.tests import datalab_test_app_context from datalab.tests.features.common.history_test_helpers import ( + CascadeObjectModel, add_paracetamol_signals, build_signal_chain, get_tree_item, @@ -43,6 +57,10 @@ select_tree_session, ) +SIZE = 200 +SROI1 = [26, 41] +SROI2 = [125, 146] + def assert_compute_action( action: HistoryAction, pattern: str, selection: list[str] @@ -165,6 +183,16 @@ def test_history_hdf5_pristine_load_and_nonempty_import() -> None: assert history.open_dlhist_file(history_path) assert len(history.history_sessions) > pristine_counts[0] assert len(panel.objmodel) > pristine_counts[1] + 1 + # Full history reset drops sessions, mappings, navigation and tree + assert isinstance(history.create_object(), HistoryAction) + history.remove_all_objects() + assert len(history) == 0 and not history.history_sessions + assert not history.runtime.objects.action_output_uuids + assert not history.runtime.objects.output_to_action + assert history.navigation.get_active_session() is None + assert history.tree.topLevelItemCount() == 0 + with pytest.raises(IndexError): + history[1] # pylint: disable=pointless-statement def test_duplicate_creation_and_operation_rooted_chains() -> None: @@ -402,8 +430,13 @@ def fail_second_recompute(*args, **kwargs): assert np.array_equal(failed_output.xydata, failed_data) -def test_multi_action_edit_recomputes_selected_descendants_once() -> None: - """Recompute selected ancestors and their analysis descendant exactly once.""" +def test_multi_action_edit_single_session_planning() -> None: + """Plan selected ancestors, descendants and full-session selections once. + + Selected ancestors are prompted exactly once and their analysis descendant + is recomputed once; selecting the whole session plus one of its (stale) + actions routes through the global replay planner without duplicates. + """ with datalab_test_app_context(history=True) as win: history, panel = win.historypanel, win.signalpanel history.toggle_record_mode(True) @@ -429,24 +462,17 @@ def test_multi_action_edit_recomputes_selected_descendants_once() -> None: assert [call.args[1] for call in recompute.call_args_list] == expected assert all(action.is_stale is False for action in expected) - -def test_edit_mode_selected_session_uses_global_replay_planner() -> None: - """Plan a selected session and duplicate stale action exactly once.""" - with datalab_test_app_context(history=True) as win: - history, panel = win.historypanel, win.signalpanel - history.toggle_record_mode(True) - history.toggle_edit_mode(True) - build_signal_chain(panel, history) + # Selecting the session plus one stale action plans each action once session = history.history_sessions[-1] - expected = list(session.actions) - stale_action = expected[1] + session_expected = list(session.actions) + stale_action = session_expected[1] stale_action.is_stale = True select_tree_session(history, session) get_tree_item(history, stale_action.uuid).setSelected(True) - selected = history.tree.get_selected_actions_or_sessions( + selected_items = history.tree.get_selected_actions_or_sessions( history.history_sessions ) - assert selected == [session, stale_action] + assert selected_items == [session, stale_action] with ( patch.object(hrec, "recompute_cascade") as direct_cascade, @@ -466,11 +492,11 @@ def test_edit_mode_selected_session_uses_global_replay_planner() -> None: direct_cascade.assert_not_called() edit_planner.assert_called_once_with( - history, [*expected, stale_action], prompt=True + history, [*session_expected, stale_action], prompt=True ) - assert [call.args[1] for call in prompt.call_args_list] == expected - assert [call.args[1] for call in recompute.call_args_list] == expected - assert all(action.is_stale is False for action in expected) + assert [call.args[1] for call in prompt.call_args_list] == session_expected + assert [call.args[1] for call in recompute.call_args_list] == session_expected + assert all(action.is_stale is False for action in session_expected) def test_downstream_actions_follow_every_registered_output() -> None: @@ -491,7 +517,7 @@ def test_downstream_actions_follow_every_registered_output() -> None: ) history.runtime.objects.output_to_action[producer_second_output] = producer.uuid history.runtime.objects.output_to_action[consumer_second_output] = consumer.uuid - hchain.prune_output_mapping(history) + history.runtime.objects.prune_output_mapping() assert producer_second_output in producer.output_uuids assert consumer_second_output in consumer.output_uuids assert ( @@ -929,9 +955,23 @@ def refresh_with_failure(_panel, output_uuid): assert np.array_equal(output.xydata, original_data[index]) assert output.metadata == original_metadata[index] + # Legacy misaligned recording: with a deleted output and a params list + # that cannot be aligned with the recorded outputs, the recompute is + # rejected with a missing-outputs warning + history.runtime.execution.cascade_warnings.clear() + panel.objview.select_objects([action.output_uuids[1]]) + panel.remove_object(force=True) + action.kwargs["params"].append(sigima.params.GaussianParam.create(sigma=3.5)) + assert hrec.recompute_action_in_place(history, action) is False + assert any( + "no longer exist" in warning + for warning in history.runtime.execution.cascade_warnings + ) + history.runtime.execution.cascade_warnings.clear() + def test_1_to_0_failure_rolls_back_all_source_metadata() -> None: - """Restore every analysis source when a later recomputation fails.""" + """Roll back analysis sources on failure, full-snapshot and targeted alike.""" with datalab_test_app_context(history=True) as win: history, panel = win.historypanel, win.signalpanel history.toggle_record_mode(True) @@ -964,6 +1004,53 @@ def fail_second_analysis(_func_name, source, _param, plugin_origin=None): assert source.metadata["user_marker"] == index assert "temporary_analysis" not in source.metadata + # Manifest-driven analysis: a failed recompute rolls back only the + # manifest keys and leaves unrelated user metadata untouched + image_panel = win.imagepanel + img = create_peak_image() + image_panel.add_object(img) + det_param = sigima.params.Peak2DDetectionParam.create( + create_rois=False, threshold=0.5 + ) + with Conf.proc.show_result_dialog.temp(False): + image_panel.processor.run_feature("peak_detection", det_param) + img_action = history[len(history)] + img_uuid = get_uuid(img) + manifest = AnalysisEffects.from_dict(img_action.effects[img_uuid]) + manifest_keys = manifest.metadata_added + manifest.metadata_replaced + geometry_key = next(key for key in manifest_keys if key.startswith("Geometry_")) + # Simulate a user having deleted one analysis result key beforehand + del img.metadata[geometry_key] + present_key = next(key for key in manifest_keys if key in img.metadata) + value_before = copy.deepcopy(img.metadata[present_key]) + img.metadata["user_marker"] = 123 + effects_before = copy.deepcopy(img_action.effects) + + def failing_recompute(_func_name, obj, _param, plugin_origin=None): + del plugin_origin + obj.metadata[geometry_key] = "recreated-by-failed-attempt" + obj.metadata[present_key] = "corrupted" + raise RuntimeError("forced recompute failure") + + with patch.object( + image_panel.processor, "recompute_1_to_0", side_effect=failing_recompute + ): + try: + hrec.recompute_1_to_0_in_place(history, img_action) + except RuntimeError: + pass + else: + raise AssertionError("RuntimeError should have propagated") + + assert img.metadata["user_marker"] == 123, "Unrelated key must be untouched" + assert geometry_key not in img.metadata, ( + "Manifest key absent before the recompute must be deleted on rollback" + ) + assert img.metadata[present_key] == value_before, ( + "Manifest key must be restored to its pre-recompute value" + ) + assert img_action.effects == effects_before, "Manifest must be unchanged" + def test_1_to_0_cascade_uses_roi_safe_parameter_copy() -> None: """Disable ROI creation on a copy during analysis cascade recomputation.""" @@ -1076,6 +1163,35 @@ def test_deletion_reconnects_and_splices_chain() -> None: ) chains = build_session_chains(session) assert sum(len(chain.actions) for chain in chains) == len(session.actions) + # Orphan cleanup: unattended runs never auto-remove orphans; explicit + # removal purges the surviving output object + orphan_uuid = action_to_delete.output_uuids[0] + assert panel.objmodel.has_uuid(orphan_uuid) + assert not htools.confirm_orphan_removal(history, [(panel, orphan_uuid)]) + htools.remove_orphan_objects(history, [(panel, orphan_uuid)]) + assert not panel.objmodel.has_uuid(orphan_uuid) + assert len(panel.objmodel) == object_count + # Leaf deletion: no downstream chain to split, output object survives + leaf_output_uuid = downstream_action.output_uuids[0] + select_tree_entry(history, downstream_action.uuid) + htools.delete_selected(history) + assert downstream_action not in session.actions + assert panel.objmodel.has_uuid(leaf_output_uuid) + # Deleting a producer whose output is already gone yields no orphan + derivative_output_uuid = derivative.output_uuids[0] + panel.objview.select_objects([derivative_output_uuid]) + panel.remove_object(force=True) + assert derivative in session.actions + # Keep the session alive with a fresh action before splicing the last + # original one out + panel.objview.select_objects([source_uuid]) + panel.processor.run_feature(sips.derivative) + assert history[len(history)] in session.actions + object_count_before = len(panel.objmodel) + select_tree_entry(history, derivative.uuid) + htools.delete_selected(history) + assert derivative not in session.actions + assert len(panel.objmodel) == object_count_before removed_action_uuids = [action.uuid for action in session.actions] removed_output_uuids = [ output_uuid @@ -1096,12 +1212,20 @@ def test_deletion_reconnects_and_splices_chain() -> None: def test_replay_survives_unexpected_recompute_exception() -> None: - """Contain unexpected exception types raised during an in-place recompute.""" + """Contain unexpected exceptions and warn about pattern-less computes.""" with datalab_test_app_context(history=True) as win: history, panel = win.historypanel, win.signalpanel history.toggle_record_mode(True) history.toggle_edit_mode(True) acts = list(build_signal_chain(panel, history).actions) + patternless = HistoryAction( + title="Legacy compute", + kind=HistoryAction.KIND_COMPUTE, + panel_str="signal", + func_name="mystery", + pattern=None, + ) + history.history_sessions[-1].add_action(patternless) original = hrec.recompute_1_to_1_in_place def flaky(panel_, action_): @@ -1114,7 +1238,7 @@ def flaky(panel_, action_): patch.object(hrec, "recompute_1_to_1_in_place", flaky), patch.object(hrec, "flush_cascade_warnings") as flush, ): - hireplay.replay_actions(history, acts, prompt=True) + hireplay.replay_actions(history, [*acts, patternless], prompt=True) assert acts[0].is_stale is False assert acts[1].is_stale is True # failed action stays flagged @@ -1122,3 +1246,351 @@ def flaky(panel_, action_): flush.assert_called() warnings = history.runtime.execution.cascade_warnings assert any("boom" in w for w in warnings) + assert any("mystery" in w for w in warnings) + + +def test_analysis_effects_manifest_populated_and_recomputed() -> None: + """Populate the effects manifest by a 1-to-0 analysis and keep it stable.""" + with datalab_test_app_context(console=False, history=True) as win: + history = win.historypanel + history.toggle_record_mode(True) + panel = win.imagepanel + img = create_peak_image() + panel.add_object(img) + det_param = sigima.params.Peak2DDetectionParam.create( + create_rois=True, threshold=0.5 + ) + with Conf.proc.show_result_dialog.temp(False): + panel.processor.run_feature("peak_detection", det_param) + action = history[len(history)] + assert action.effects is not None, "1-to-0 action must carry effects" + src_uuid = get_uuid(img) + assert src_uuid in action.effects + manifest = AnalysisEffects.from_dict(action.effects[src_uuid]) + assert any( + key.startswith("Geometry_") and key.endswith("_dict") + for key in manifest.metadata_added + ), f"Expected a Geometry_*_dict key, got {manifest.metadata_added}" + assert manifest.roi_modified is True, "Detection ROIs must flag roi_modified" + added_before = manifest.metadata_added + # A history recompute keeps first-run keys under metadata_added + assert hrec.recompute_1_to_0_in_place(history, action) is True + manifest = AnalysisEffects.from_dict(action.effects[src_uuid]) + assert set(added_before) <= set(manifest.metadata_added), ( + "First-run keys must stay under metadata_added after recompute" + ) + assert not set(added_before) & set(manifest.metadata_replaced) + + +def test_roi_mutation_recording_replay_and_partial_targets() -> None: + """Record paste/delete ROI mutations, replay them, tolerate deleted targets.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + sig1 = create_paracetamol_signal(SIZE) + sig1.roi = create_signal_roi([SROI1, SROI2], indices=True) + panel.add_object(sig1) + sig2 = create_paracetamol_signal(SIZE) + panel.add_object(sig2) + sig2 = panel.objmodel[get_uuid(sig2)] + sig3 = create_paracetamol_signal(SIZE) + panel.add_object(sig3) + sig3 = panel.objmodel[get_uuid(sig3)] + # Paste onto two targets: one mutation entry per object carrying the + # post-combination ROI payload + panel.objview.select_objects([1]) + panel.copy_roi() + panel.objview.select_objects([2, 3]) + panel.paste_roi() + actions = history.history_sessions[-1].actions + paste2, paste3 = actions[-2], actions[-1] + for action, sig in ((paste2, sig2), (paste3, sig3)): + assert action.kind == HistoryAction.KIND_MUTATION + assert action.mutation_key == "roi" + assert action.target_uuids == [get_uuid(sig)] + payload = action.kwargs.get("payload") + assert payload is not None + assert numpy_to_json_safe(payload.to_dict()) == numpy_to_json_safe( + sig.roi.to_dict() + ) + # Direct replay re-applies the payload after the ROI was cleared + sig2.roi = None + paste2.replay(win, restore_selection=True, edit=False) + assert sig2.roi is not None + assert numpy_to_json_safe(sig2.roi.to_dict()) == numpy_to_json_safe( + paste2.kwargs["payload"].to_dict() + ) + # Deleting ROIs records one empty-payload mutation for both targets + panel.objview.select_objects([2, 3]) + panel.processor.delete_regions_of_interest() + assert sig2.roi is None and sig3.roi is None + delete_action = history.history_sessions[-1].actions[-1] + assert delete_action.kind == HistoryAction.KIND_MUTATION + assert delete_action.mutation_key == "roi" + assert delete_action.kwargs.get("payload") is None + assert set(delete_action.target_uuids) == {get_uuid(sig2), get_uuid(sig3)} + # Replaying the recorded sequence restores then removes the ROI + paste2.replay(win, restore_selection=True, edit=False) + assert sig2.roi is not None + delete_action.replay(win, restore_selection=True, edit=False) + assert sig2.roi is None + # Cascade recompute tolerates a deleted target: warn and apply to the rest + sig2.roi = create_signal_roi([SROI1], indices=True) + panel.objview.select_objects([get_uuid(sig3)]) + panel.remove_object(force=True) + assert hrec.recompute_mutation_in_place(history, delete_action) is True + assert sig2.roi is None + assert any( + "deleted" in warning + for warning in history.runtime.execution.cascade_warnings + ) + history.runtime.execution.cascade_warnings.clear() + + +def test_cascade_reapplies_roi_mutation() -> None: + """Cascade recompute re-applies, blocks or edits a downstream ROI mutation.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + sig1 = create_paracetamol_signal(SIZE) + sig1.roi = create_signal_roi([SROI1, SROI2], indices=True) + panel.add_object(sig1) + src = create_paracetamol_signal(SIZE) + panel.add_object(src) + # Record a compute action producing the output object + panel.objview.select_objects([2]) + panel.processor.run_feature(sips.derivative) + compute_action = history[len(history)] + output = panel.objmodel[compute_action.output_uuids[0]] + # Paste a ROI onto the compute output (records a mutation action) + panel.objview.select_objects([1]) + panel.copy_roi() + panel.objview.select_objects([get_uuid(output)]) + panel.paste_roi() + mutation_action = history.history_sessions[-1].actions[-1] + assert mutation_action.kind == HistoryAction.KIND_MUTATION + # The mutation belongs to the compute action's downstream closure + downstream = hchain.get_downstream_actions(history, compute_action) + assert mutation_action in downstream + # Wipe the ROI, then recompute the cascade from the compute action + output.roi = None + history.recompute_cascade(compute_action) + assert output.roi is not None + assert numpy_to_json_safe(output.roi.to_dict()) == numpy_to_json_safe( + mutation_action.kwargs["payload"].to_dict() + ) + assert mutation_action.is_stale is False + # A failed upstream recompute blocks the deferred mutation replay + output.roi = None + with ( + patch.object(hrec, "recompute_action_in_place", return_value=False), + patch.object(hrec, "flush_cascade_warnings"), + ): + hireplay.replay_actions( + history, [compute_action, mutation_action], prompt=False + ) + assert output.roi is None + assert compute_action.is_stale is True + compute_action.is_stale = False + history.runtime.execution.cascade_warnings.clear() + + # An edited mutation payload triggers a downstream cascade recompute + def edit_payload(_mainwindow, restore_selection=True, edit=False): + del restore_selection + assert edit is True + mutation_action.kwargs["payload"] = mutation_action.kwargs["payload"].copy() + + with ( + patch.object(mutation_action, "replay", side_effect=edit_payload), + patch.object(hrec, "recompute_cascade") as cascade, + ): + hireplay.replay_actions(history, [mutation_action], prompt=True) + cascade.assert_called_once_with(history, mutation_action) + + +def test_mutation_root_has_downstream_computes() -> None: + """A mutation root seeds its targets: consuming computes are downstream.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + sig1 = create_paracetamol_signal(SIZE) + sig1.roi = create_signal_roi([SROI1], indices=True) + panel.add_object(sig1) + sig2 = create_paracetamol_signal(SIZE) + panel.add_object(sig2) + panel.objview.select_objects([1]) + panel.copy_roi() + panel.objview.select_objects([2]) + panel.paste_roi() + mutation_action = history.history_sessions[-1].actions[-1] + assert mutation_action.kind == HistoryAction.KIND_MUTATION + # Compute consuming the mutated object is downstream of the mutation + panel.objview.select_objects([2]) + panel.processor.run_feature(sips.derivative) + compute_action = history.history_sessions[-1].actions[-1] + assert compute_action.kind == HistoryAction.KIND_COMPUTE + downstream = hchain.get_downstream_actions(history, mutation_action) + assert compute_action in downstream + + +def test_edited_image_creation_recomputes_downstream_in_place() -> None: + """Regenerate an edited image before recomputing its existing descendant.""" + initial_param = Gauss2DParam.create( + title="Initial Gaussian", + height=24, + width=28, + x0=-4.0, + y0=2.0, + sigma=1.2, + a=25.0, + ) + edited_param = Gauss2DParam.create( + title="Edited Gaussian", + height=24, + width=28, + x0=3.0, + y0=-2.0, + sigma=3.5, + a=80.0, + ) + source = create_image_from_param(initial_param) + source_uuid = get_uuid(source) + source_identity = id(source) + initial_source_data = source.data.copy() + expected_source = create_image_from_param(edited_param) + + downstream = source.copy() + set_uuid(downstream) + downstream.title = "Initial downstream" + downstream.data = np.full(source.data.shape, -1.0) + downstream_uuid = get_uuid(downstream) + downstream_identity = id(downstream) + initial_downstream_data = downstream.data.copy() + insert_processing_parameters( + downstream, + ProcessingParameters( + func_name="unit_transform", + pattern="1-to-1", + source_uuid=source_uuid, + ), + ) + + creation_action = HistoryAction( + title="Create edited Gaussian", + kind=HistoryAction.KIND_UI, + target="imagepanel", + method_name="new_object", + kwargs={"param": edited_param}, + ) + creation_action.output_uuids = [source_uuid] + downstream_state = WorkspaceState() + downstream_state.selection = {"image": [source_uuid]} + downstream_action = HistoryAction( + title="Transform edited Gaussian", + kind=HistoryAction.KIND_COMPUTE, + panel_str="image", + func_name="unit_transform", + pattern="1_to_1", + state=downstream_state, + ) + downstream_action.output_uuids = [downstream_uuid] + session = HistorySession(number=1) + session.add_action(creation_action) + session.add_action(downstream_action) + + processor_source_objects: list[ImageObj] = [] + processor_source_data: list[np.ndarray] = [] + + def recompute_1_to_1( + func_name: str | None, + source_obj: ImageObj, + param: object, + *, + plugin_origin: dict[str, object] | None, + ) -> SimpleNamespace: + assert func_name == "unit_transform" + assert param is None + assert plugin_origin is None + processor_source_objects.append(source_obj) + processor_source_data.append(source_obj.data.copy()) + new_obj = source_obj.copy() + new_obj.title = f"unit_transform({source_obj.title})" + new_obj.data = source_obj.data.astype(float) * 2.0 + 3.0 + return SimpleNamespace(cancelled=False, error_msg=None, result=new_obj) + + def apply_recomputed_object_in_place( + obj: ImageObj, + new_obj: ImageObj, + proc_params: ProcessingParameters, + ) -> None: + hrec.update_obj_in_place(obj, new_obj) + insert_processing_parameters(obj, proc_params) + + object_model = CascadeObjectModel([source, downstream]) + data_panel = SimpleNamespace( + PANEL_STR_ID="image", + objmodel=object_model, + processor=SimpleNamespace(recompute_1_to_1=recompute_1_to_1), + objprop=SimpleNamespace( + apply_recomputed_object_in_place=apply_recomputed_object_in_place + ), + ) + runtime = SimpleNamespace( + objects=SimpleNamespace( + action_output_uuids={ + creation_action.uuid: [source_uuid], + downstream_action.uuid: [downstream_uuid], + } + ), + execution=SimpleNamespace(cascade_warnings=[]), + ) + history_panel = SimpleNamespace( + runtime=runtime, + history_sessions=[session], + ) + refreshed_uuids: list[str] = [] + + def record_refresh(panel_data: object, output_uuid: str) -> None: + assert panel_data is data_panel + refreshed_uuids.append(output_uuid) + + descendants = hrec.hchain.get_downstream_actions(history_panel, creation_action) + assert descendants == [downstream_action] + + with ( + patch.object(hrec.hchain, "resolve_panel_for_action", return_value=data_panel), + patch.object( + hrec, "create_image_from_param", wraps=create_image_from_param + ) as create_image_mock, + patch.object(hrec, "refresh_target", side_effect=record_refresh), + ): + assert hrec.recompute_creation_in_place(history_panel, creation_action) + assert hrec.recompute_1_to_1_in_place(history_panel, downstream_action) + + create_image_mock.assert_called_once() + assert create_image_mock.call_args.args[0] is edited_param + + assert id(source) == source_identity + assert object_model[source_uuid] is source + assert get_uuid(source) == source_uuid + np.testing.assert_allclose(source.data, expected_source.data) + assert not np.array_equal(source.data, initial_source_data) + creation_param = extract_creation_parameters(source) + assert isinstance(creation_param, Gauss2DParam) + for name in ("height", "width", "x0", "y0", "sigma", "a"): + assert getattr(creation_param, name) == getattr(edited_param, name) + + assert processor_source_objects == [source] + np.testing.assert_allclose(processor_source_data[0], expected_source.data) + assert id(downstream) == downstream_identity + assert object_model[downstream_uuid] is downstream + assert get_uuid(downstream) == downstream_uuid + np.testing.assert_allclose( + downstream.data, expected_source.data.astype(float) * 2.0 + 3.0 + ) + assert not np.array_equal(downstream.data, initial_downstream_data) + downstream_params = extract_processing_parameters(downstream) + assert downstream_params is not None + assert downstream_params.source_uuid == source_uuid + assert refreshed_uuids == [source_uuid, downstream_uuid] + assert runtime.execution.cascade_warnings == [] diff --git a/datalab/tests/features/common/worker_unit_test.py b/datalab/tests/features/common/worker_unit_test.py index fa8b2e502..1fa01e357 100644 --- a/datalab/tests/features/common/worker_unit_test.py +++ b/datalab/tests/features/common/worker_unit_test.py @@ -28,6 +28,22 @@ from datalab.gui.processor.catcher import CompOut +@pytest.fixture(autouse=True) +def drain_pending_qt_timers(): + """Fire stale unattended auto-close timers before leaving each test. + + In unattended mode, ``qt_app_context`` schedules a zero-delay + ``close_widgets_and_quit`` timer on exit. Tests here never run the Qt + event loop afterwards, so without this drain the timer stays pending in + the shared ``QApplication`` and fires during a later test, closing that + test's freshly created main window (e.g. unregistering its plugins). + """ + yield + if QW.QApplication.instance() is not None: + for _ in range(3): + QW.QApplication.processEvents() + + class TestWorkerStateMachine: """Test suite for WorkerStateMachine class - independent from Worker class.""" diff --git a/datalab/widgets/historytree.py b/datalab/widgets/historytree.py index a4684edc4..4544e3ff0 100644 --- a/datalab/widgets/historytree.py +++ b/datalab/widgets/historytree.py @@ -123,9 +123,7 @@ def update_compatibility_states( if action is None: iterator += 1 continue - compatible = action.is_current_state_compatible( - mainwindow, restore_selection=True - ) + compatible = action.is_current_state_compatible(mainwindow) item.setData(0, self.COMPATIBILITY_ROLE, compatible) brush = default_brush if compatible else disabled_brush icon = get_icon("apply.svg") if compatible else get_icon("delete.svg") diff --git a/doc/locale/fr/LC_MESSAGES/contributing/dependencies.po b/doc/locale/fr/LC_MESSAGES/contributing/dependencies.po index 6d4022490..af15f6c0b 100644 --- a/doc/locale/fr/LC_MESSAGES/contributing/dependencies.po +++ b/doc/locale/fr/LC_MESSAGES/contributing/dependencies.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/contributing/environment.po b/doc/locale/fr/LC_MESSAGES/contributing/environment.po index 1b9e36aa7..56cc6e57c 100644 --- a/doc/locale/fr/LC_MESSAGES/contributing/environment.po +++ b/doc/locale/fr/LC_MESSAGES/contributing/environment.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/contributing/gitworkflow.po b/doc/locale/fr/LC_MESSAGES/contributing/gitworkflow.po index d11e1a1c2..5cc36c9a8 100644 --- a/doc/locale/fr/LC_MESSAGES/contributing/gitworkflow.po +++ b/doc/locale/fr/LC_MESSAGES/contributing/gitworkflow.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/features/advanced/api.po b/doc/locale/fr/LC_MESSAGES/features/advanced/api.po index ebd1d8ebe..5a96ac49e 100644 --- a/doc/locale/fr/LC_MESSAGES/features/advanced/api.po +++ b/doc/locale/fr/LC_MESSAGES/features/advanced/api.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/features/advanced/api/index.po b/doc/locale/fr/LC_MESSAGES/features/advanced/api/index.po index 44d935dff..0bdc292fa 100644 --- a/doc/locale/fr/LC_MESSAGES/features/advanced/api/index.po +++ b/doc/locale/fr/LC_MESSAGES/features/advanced/api/index.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/features/advanced/macros.po b/doc/locale/fr/LC_MESSAGES/features/advanced/macros.po index 8d1d4e44a..f0ed5de78 100644 --- a/doc/locale/fr/LC_MESSAGES/features/advanced/macros.po +++ b/doc/locale/fr/LC_MESSAGES/features/advanced/macros.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/features/advanced/migration_v020_to_v100.po b/doc/locale/fr/LC_MESSAGES/features/advanced/migration_v020_to_v100.po index 05339cc3b..dca25a94f 100644 --- a/doc/locale/fr/LC_MESSAGES/features/advanced/migration_v020_to_v100.po +++ b/doc/locale/fr/LC_MESSAGES/features/advanced/migration_v020_to_v100.po @@ -5,7 +5,6 @@ # msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/features/advanced/model.po b/doc/locale/fr/LC_MESSAGES/features/advanced/model.po index 978554e4e..9935ba672 100644 --- a/doc/locale/fr/LC_MESSAGES/features/advanced/model.po +++ b/doc/locale/fr/LC_MESSAGES/features/advanced/model.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/features/advanced/proxy.po b/doc/locale/fr/LC_MESSAGES/features/advanced/proxy.po index d85bea1b5..3563e2bb0 100644 --- a/doc/locale/fr/LC_MESSAGES/features/advanced/proxy.po +++ b/doc/locale/fr/LC_MESSAGES/features/advanced/proxy.po @@ -7,17 +7,12 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" -"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2026-08-05 10:58+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" -"Language: fr\n" -"Language-Team: fr <LL@li.org>\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.18.0\n" msgid "Proxy objects (:mod:`datalab.control.proxy`)" msgstr "" @@ -730,4 +725,3 @@ msgid "" "To run a computation feature associated to a processor, you can use the " ":meth:`calc` method of the proxy object:" msgstr "" - diff --git a/doc/locale/fr/LC_MESSAGES/features/advanced/webapi.po b/doc/locale/fr/LC_MESSAGES/features/advanced/webapi.po index d4bf5ba9e..99c5a26ee 100644 --- a/doc/locale/fr/LC_MESSAGES/features/advanced/webapi.po +++ b/doc/locale/fr/LC_MESSAGES/features/advanced/webapi.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/features/common/h5browser.po b/doc/locale/fr/LC_MESSAGES/features/common/h5browser.po index e0833be92..e61715288 100644 --- a/doc/locale/fr/LC_MESSAGES/features/common/h5browser.po +++ b/doc/locale/fr/LC_MESSAGES/features/common/h5browser.po @@ -2,7 +2,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po b/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po index 768230058..a0ba6f4b9 100644 --- a/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po +++ b/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po @@ -6,17 +6,12 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" -"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2026-08-06 09:11+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" -"Language: fr\n" -"Language-Team: fr <LL@li.org>\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.18.0\n" msgid "" "History Panel in DataLab, the open-source scientific data analysis and " diff --git a/doc/locale/fr/LC_MESSAGES/features/common/overview.po b/doc/locale/fr/LC_MESSAGES/features/common/overview.po index eb3f38589..dd8d27008 100644 --- a/doc/locale/fr/LC_MESSAGES/features/common/overview.po +++ b/doc/locale/fr/LC_MESSAGES/features/common/overview.po @@ -7,15 +7,11 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" -"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2026-08-05 14:24+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" -"Language-Team: LANGUAGE <LL@li.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.18.0\n" msgid "Overview and basic concepts of DataLab, the open-source scientific data analysis and visualization platform" msgstr "Vue d'ensemble et concepts de base de DataLab, la plateforme open-source d'analyse et de visualisation de données scientifiques" diff --git a/doc/locale/fr/LC_MESSAGES/features/common/settings.po b/doc/locale/fr/LC_MESSAGES/features/common/settings.po index 11742014f..d230b6e42 100644 --- a/doc/locale/fr/LC_MESSAGES/features/common/settings.po +++ b/doc/locale/fr/LC_MESSAGES/features/common/settings.po @@ -6,17 +6,12 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" -"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2026-08-05 14:24+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" -"Language: fr\n" -"Language-Team: fr <LL@li.org>\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.18.0\n" msgid "Settings of DataLab, the open-source scientific data analysis and visualization platform" msgstr "Préférences de DataLab, la plateforme open-source d'analyse et de visualisation de données scientifiques" diff --git a/doc/locale/fr/LC_MESSAGES/features/image/menu_analysis.po b/doc/locale/fr/LC_MESSAGES/features/image/menu_analysis.po index 7c2c7eb9e..46b4dc7f2 100644 --- a/doc/locale/fr/LC_MESSAGES/features/image/menu_analysis.po +++ b/doc/locale/fr/LC_MESSAGES/features/image/menu_analysis.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/features/image/menu_create.po b/doc/locale/fr/LC_MESSAGES/features/image/menu_create.po index 1d3cd1694..1b125d319 100644 --- a/doc/locale/fr/LC_MESSAGES/features/image/menu_create.po +++ b/doc/locale/fr/LC_MESSAGES/features/image/menu_create.po @@ -5,7 +5,6 @@ # msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/features/image/menu_edit.po b/doc/locale/fr/LC_MESSAGES/features/image/menu_edit.po index 71f157eb3..434463e48 100644 --- a/doc/locale/fr/LC_MESSAGES/features/image/menu_edit.po +++ b/doc/locale/fr/LC_MESSAGES/features/image/menu_edit.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/features/image/menu_file.po b/doc/locale/fr/LC_MESSAGES/features/image/menu_file.po index 22a0c646f..fde4a7016 100644 --- a/doc/locale/fr/LC_MESSAGES/features/image/menu_file.po +++ b/doc/locale/fr/LC_MESSAGES/features/image/menu_file.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/features/image/menu_operations.po b/doc/locale/fr/LC_MESSAGES/features/image/menu_operations.po index 7b1c1a053..20a521342 100644 --- a/doc/locale/fr/LC_MESSAGES/features/image/menu_operations.po +++ b/doc/locale/fr/LC_MESSAGES/features/image/menu_operations.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/features/image/menu_processing.po b/doc/locale/fr/LC_MESSAGES/features/image/menu_processing.po index 5e0045822..8a648e04f 100644 --- a/doc/locale/fr/LC_MESSAGES/features/image/menu_processing.po +++ b/doc/locale/fr/LC_MESSAGES/features/image/menu_processing.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/features/image/menu_roi.po b/doc/locale/fr/LC_MESSAGES/features/image/menu_roi.po index 5fca8a428..ca3baf985 100644 --- a/doc/locale/fr/LC_MESSAGES/features/image/menu_roi.po +++ b/doc/locale/fr/LC_MESSAGES/features/image/menu_roi.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/features/image/menu_view.po b/doc/locale/fr/LC_MESSAGES/features/image/menu_view.po index ce049bd04..125c58e05 100644 --- a/doc/locale/fr/LC_MESSAGES/features/image/menu_view.po +++ b/doc/locale/fr/LC_MESSAGES/features/image/menu_view.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/features/index.po b/doc/locale/fr/LC_MESSAGES/features/index.po index 874b303f2..e5b33d8df 100644 --- a/doc/locale/fr/LC_MESSAGES/features/index.po +++ b/doc/locale/fr/LC_MESSAGES/features/index.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/features/signal/menu_analysis.po b/doc/locale/fr/LC_MESSAGES/features/signal/menu_analysis.po index c65674c35..2f659b3ed 100644 --- a/doc/locale/fr/LC_MESSAGES/features/signal/menu_analysis.po +++ b/doc/locale/fr/LC_MESSAGES/features/signal/menu_analysis.po @@ -5,7 +5,6 @@ # msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/features/signal/menu_create.po b/doc/locale/fr/LC_MESSAGES/features/signal/menu_create.po index 4c0742152..04721894c 100644 --- a/doc/locale/fr/LC_MESSAGES/features/signal/menu_create.po +++ b/doc/locale/fr/LC_MESSAGES/features/signal/menu_create.po @@ -5,7 +5,6 @@ # msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/features/signal/menu_edit.po b/doc/locale/fr/LC_MESSAGES/features/signal/menu_edit.po index 8a398543c..801cddb30 100644 --- a/doc/locale/fr/LC_MESSAGES/features/signal/menu_edit.po +++ b/doc/locale/fr/LC_MESSAGES/features/signal/menu_edit.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/features/signal/menu_file.po b/doc/locale/fr/LC_MESSAGES/features/signal/menu_file.po index 02ae96953..ae55cbe8e 100644 --- a/doc/locale/fr/LC_MESSAGES/features/signal/menu_file.po +++ b/doc/locale/fr/LC_MESSAGES/features/signal/menu_file.po @@ -5,7 +5,6 @@ # msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/features/signal/menu_operations.po b/doc/locale/fr/LC_MESSAGES/features/signal/menu_operations.po index eab89a371..6eeccc184 100644 --- a/doc/locale/fr/LC_MESSAGES/features/signal/menu_operations.po +++ b/doc/locale/fr/LC_MESSAGES/features/signal/menu_operations.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/features/signal/menu_processing.po b/doc/locale/fr/LC_MESSAGES/features/signal/menu_processing.po index 950d80ac8..2b462ead1 100644 --- a/doc/locale/fr/LC_MESSAGES/features/signal/menu_processing.po +++ b/doc/locale/fr/LC_MESSAGES/features/signal/menu_processing.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/features/signal/menu_roi.po b/doc/locale/fr/LC_MESSAGES/features/signal/menu_roi.po index c3a7e5788..c227ecdd3 100644 --- a/doc/locale/fr/LC_MESSAGES/features/signal/menu_roi.po +++ b/doc/locale/fr/LC_MESSAGES/features/signal/menu_roi.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/features/signal/menu_view.po b/doc/locale/fr/LC_MESSAGES/features/signal/menu_view.po index 45b2c8edc..712e6b5c2 100644 --- a/doc/locale/fr/LC_MESSAGES/features/signal/menu_view.po +++ b/doc/locale/fr/LC_MESSAGES/features/signal/menu_view.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/features/validation/functional.po b/doc/locale/fr/LC_MESSAGES/features/validation/functional.po index f77ce381d..eea31a8c8 100644 --- a/doc/locale/fr/LC_MESSAGES/features/validation/functional.po +++ b/doc/locale/fr/LC_MESSAGES/features/validation/functional.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/features/validation/status.po b/doc/locale/fr/LC_MESSAGES/features/validation/status.po index aee38071a..2f0388c14 100644 --- a/doc/locale/fr/LC_MESSAGES/features/validation/status.po +++ b/doc/locale/fr/LC_MESSAGES/features/validation/status.po @@ -7,17 +7,12 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" -"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2026-08-05 10:58+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" -"Language: fr\n" -"Language-Team: fr <LL@li.org>\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.18.0\n" msgid "" "Validation in DataLab, the open-source scientific data analysis and " @@ -3545,4 +3540,3 @@ msgstr "" #~ "`test_image_zero_padding <https://github.com/DataLab-" #~ "Platform/Sigima/blob/v1.1.4/sigima/tests/image/fft2d_unit_test.py#L50>`_" #~ msgstr "" - diff --git a/doc/locale/fr/LC_MESSAGES/features/validation/technical.po b/doc/locale/fr/LC_MESSAGES/features/validation/technical.po index 516321245..36d0fa8c3 100644 --- a/doc/locale/fr/LC_MESSAGES/features/validation/technical.po +++ b/doc/locale/fr/LC_MESSAGES/features/validation/technical.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/intro/ecosystem.po b/doc/locale/fr/LC_MESSAGES/intro/ecosystem.po index 79fc42401..13d8ee60a 100644 --- a/doc/locale/fr/LC_MESSAGES/intro/ecosystem.po +++ b/doc/locale/fr/LC_MESSAGES/intro/ecosystem.po @@ -4,7 +4,6 @@ # msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/intro/installation.po b/doc/locale/fr/LC_MESSAGES/intro/installation.po index 8a4164678..b628a925c 100644 --- a/doc/locale/fr/LC_MESSAGES/intro/installation.po +++ b/doc/locale/fr/LC_MESSAGES/intro/installation.po @@ -7,15 +7,11 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" -"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2026-08-05 10:58+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" -"Language-Team: LANGUAGE <LL@li.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.18.0\n" msgid "" "How to install DataLab, the open-source data analysis and visualization " @@ -719,4 +715,3 @@ msgstr "Python 3.11 et PyQt5 sont les références pour la version de production #~ msgid ">= 1.1.4" #~ msgstr "" - diff --git a/doc/locale/fr/LC_MESSAGES/intro/installation_offline.po b/doc/locale/fr/LC_MESSAGES/intro/installation_offline.po index 225ca4d7e..9c327bb60 100644 --- a/doc/locale/fr/LC_MESSAGES/intro/installation_offline.po +++ b/doc/locale/fr/LC_MESSAGES/intro/installation_offline.po @@ -5,7 +5,6 @@ # msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/intro/introduction.po b/doc/locale/fr/LC_MESSAGES/intro/introduction.po index 26a9b6124..efe3461a0 100644 --- a/doc/locale/fr/LC_MESSAGES/intro/introduction.po +++ b/doc/locale/fr/LC_MESSAGES/intro/introduction.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/intro/tutorials/blobs.po b/doc/locale/fr/LC_MESSAGES/intro/tutorials/blobs.po index 71ba5ca1f..c79ee87b5 100644 --- a/doc/locale/fr/LC_MESSAGES/intro/tutorials/blobs.po +++ b/doc/locale/fr/LC_MESSAGES/intro/tutorials/blobs.po @@ -5,7 +5,6 @@ # msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/intro/tutorials/custom_func.po b/doc/locale/fr/LC_MESSAGES/intro/tutorials/custom_func.po index ffd303e65..daceac357 100644 --- a/doc/locale/fr/LC_MESSAGES/intro/tutorials/custom_func.po +++ b/doc/locale/fr/LC_MESSAGES/intro/tutorials/custom_func.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/intro/tutorials/fabry_perot.po b/doc/locale/fr/LC_MESSAGES/intro/tutorials/fabry_perot.po index 72afa3980..f4d2ef42d 100644 --- a/doc/locale/fr/LC_MESSAGES/intro/tutorials/fabry_perot.po +++ b/doc/locale/fr/LC_MESSAGES/intro/tutorials/fabry_perot.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/intro/tutorials/index.po b/doc/locale/fr/LC_MESSAGES/intro/tutorials/index.po index 5f10f2609..7ad10e5ef 100644 --- a/doc/locale/fr/LC_MESSAGES/intro/tutorials/index.po +++ b/doc/locale/fr/LC_MESSAGES/intro/tutorials/index.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/intro/tutorials/laser_beam.po b/doc/locale/fr/LC_MESSAGES/intro/tutorials/laser_beam.po index 8a91331b1..502e03af4 100644 --- a/doc/locale/fr/LC_MESSAGES/intro/tutorials/laser_beam.po +++ b/doc/locale/fr/LC_MESSAGES/intro/tutorials/laser_beam.po @@ -7,17 +7,12 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" -"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2026-08-05 14:07+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" -"Language: fr\n" -"Language-Team: fr <LL@li.org>\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.18.0\n" msgid "" "Tutorial on how to measure the size of a laser beam using DataLab, the " @@ -575,4 +570,3 @@ msgstr "fileopen_h5" msgid "h5browser" msgstr "h5browser" - diff --git a/doc/locale/fr/LC_MESSAGES/intro/tutorials/spectrum.po b/doc/locale/fr/LC_MESSAGES/intro/tutorials/spectrum.po index 99fc44952..494ae77a9 100644 --- a/doc/locale/fr/LC_MESSAGES/intro/tutorials/spectrum.po +++ b/doc/locale/fr/LC_MESSAGES/intro/tutorials/spectrum.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/intro/tutorials/videos/p1_quick_demo.po b/doc/locale/fr/LC_MESSAGES/intro/tutorials/videos/p1_quick_demo.po index 9668c8c94..12ccc3a74 100644 --- a/doc/locale/fr/LC_MESSAGES/intro/tutorials/videos/p1_quick_demo.po +++ b/doc/locale/fr/LC_MESSAGES/intro/tutorials/videos/p1_quick_demo.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/intro/tutorials/videos/p2_extensibility.po b/doc/locale/fr/LC_MESSAGES/intro/tutorials/videos/p2_extensibility.po index 986ab4c39..3089c39ee 100644 --- a/doc/locale/fr/LC_MESSAGES/intro/tutorials/videos/p2_extensibility.po +++ b/doc/locale/fr/LC_MESSAGES/intro/tutorials/videos/p2_extensibility.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/intro/tutorials/work_with_spyder.po b/doc/locale/fr/LC_MESSAGES/intro/tutorials/work_with_spyder.po index b66115a04..d7c304eda 100644 --- a/doc/locale/fr/LC_MESSAGES/intro/tutorials/work_with_spyder.po +++ b/doc/locale/fr/LC_MESSAGES/intro/tutorials/work_with_spyder.po @@ -5,7 +5,6 @@ # msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/outreach/euroscipy2026.po b/doc/locale/fr/LC_MESSAGES/outreach/euroscipy2026.po index 8a5227bfe..33c7515e5 100644 --- a/doc/locale/fr/LC_MESSAGES/outreach/euroscipy2026.po +++ b/doc/locale/fr/LC_MESSAGES/outreach/euroscipy2026.po @@ -5,7 +5,6 @@ # msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/outreach/index.po b/doc/locale/fr/LC_MESSAGES/outreach/index.po index e47a45573..7138150c4 100644 --- a/doc/locale/fr/LC_MESSAGES/outreach/index.po +++ b/doc/locale/fr/LC_MESSAGES/outreach/index.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/outreach/osxp2024.po b/doc/locale/fr/LC_MESSAGES/outreach/osxp2024.po index 9e121924b..e7a06f47a 100644 --- a/doc/locale/fr/LC_MESSAGES/outreach/osxp2024.po +++ b/doc/locale/fr/LC_MESSAGES/outreach/osxp2024.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/outreach/osxp2025.po b/doc/locale/fr/LC_MESSAGES/outreach/osxp2025.po index 12ddac530..e8224eb80 100644 --- a/doc/locale/fr/LC_MESSAGES/outreach/osxp2025.po +++ b/doc/locale/fr/LC_MESSAGES/outreach/osxp2025.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/outreach/pydata2024.po b/doc/locale/fr/LC_MESSAGES/outreach/pydata2024.po index 04f4d7e88..44c34ed08 100644 --- a/doc/locale/fr/LC_MESSAGES/outreach/pydata2024.po +++ b/doc/locale/fr/LC_MESSAGES/outreach/pydata2024.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/outreach/scipy2024.po b/doc/locale/fr/LC_MESSAGES/outreach/scipy2024.po index a641e6e04..90af1aee9 100644 --- a/doc/locale/fr/LC_MESSAGES/outreach/scipy2024.po +++ b/doc/locale/fr/LC_MESSAGES/outreach/scipy2024.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/release_notes/index.po b/doc/locale/fr/LC_MESSAGES/release_notes/index.po index 5e28f5547..d1aafccd0 100644 --- a/doc/locale/fr/LC_MESSAGES/release_notes/index.po +++ b/doc/locale/fr/LC_MESSAGES/release_notes/index.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/release_notes/release_0.09.po b/doc/locale/fr/LC_MESSAGES/release_notes/release_0.09.po index f3bf580db..3db508e7e 100644 --- a/doc/locale/fr/LC_MESSAGES/release_notes/release_0.09.po +++ b/doc/locale/fr/LC_MESSAGES/release_notes/release_0.09.po @@ -5,7 +5,6 @@ # msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/release_notes/release_0.10.po b/doc/locale/fr/LC_MESSAGES/release_notes/release_0.10.po index c600f9bab..3919df97a 100644 --- a/doc/locale/fr/LC_MESSAGES/release_notes/release_0.10.po +++ b/doc/locale/fr/LC_MESSAGES/release_notes/release_0.10.po @@ -5,7 +5,6 @@ # msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/release_notes/release_0.11.po b/doc/locale/fr/LC_MESSAGES/release_notes/release_0.11.po index 45119e08f..bf103e1ff 100644 --- a/doc/locale/fr/LC_MESSAGES/release_notes/release_0.11.po +++ b/doc/locale/fr/LC_MESSAGES/release_notes/release_0.11.po @@ -5,7 +5,6 @@ # msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/release_notes/release_0.12.po b/doc/locale/fr/LC_MESSAGES/release_notes/release_0.12.po index 28ef44dbe..37ba98922 100644 --- a/doc/locale/fr/LC_MESSAGES/release_notes/release_0.12.po +++ b/doc/locale/fr/LC_MESSAGES/release_notes/release_0.12.po @@ -5,7 +5,6 @@ # msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/release_notes/release_0.14.po b/doc/locale/fr/LC_MESSAGES/release_notes/release_0.14.po index 650d4681a..2c817c25c 100644 --- a/doc/locale/fr/LC_MESSAGES/release_notes/release_0.14.po +++ b/doc/locale/fr/LC_MESSAGES/release_notes/release_0.14.po @@ -5,7 +5,6 @@ # msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/release_notes/release_0.15.po b/doc/locale/fr/LC_MESSAGES/release_notes/release_0.15.po index 7ac711178..d54560ab5 100644 --- a/doc/locale/fr/LC_MESSAGES/release_notes/release_0.15.po +++ b/doc/locale/fr/LC_MESSAGES/release_notes/release_0.15.po @@ -5,7 +5,6 @@ # msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/release_notes/release_0.16.po b/doc/locale/fr/LC_MESSAGES/release_notes/release_0.16.po index 209b83849..b94b2a7f5 100644 --- a/doc/locale/fr/LC_MESSAGES/release_notes/release_0.16.po +++ b/doc/locale/fr/LC_MESSAGES/release_notes/release_0.16.po @@ -5,7 +5,6 @@ # msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/release_notes/release_0.17.po b/doc/locale/fr/LC_MESSAGES/release_notes/release_0.17.po index 5b7ef9e70..8f6cb4757 100644 --- a/doc/locale/fr/LC_MESSAGES/release_notes/release_0.17.po +++ b/doc/locale/fr/LC_MESSAGES/release_notes/release_0.17.po @@ -5,7 +5,6 @@ # msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/release_notes/release_0.18.po b/doc/locale/fr/LC_MESSAGES/release_notes/release_0.18.po index 2337c0d79..de811141d 100644 --- a/doc/locale/fr/LC_MESSAGES/release_notes/release_0.18.po +++ b/doc/locale/fr/LC_MESSAGES/release_notes/release_0.18.po @@ -5,7 +5,6 @@ # msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/release_notes/release_0.19.po b/doc/locale/fr/LC_MESSAGES/release_notes/release_0.19.po index 75e386b67..e756f7954 100644 --- a/doc/locale/fr/LC_MESSAGES/release_notes/release_0.19.po +++ b/doc/locale/fr/LC_MESSAGES/release_notes/release_0.19.po @@ -5,7 +5,6 @@ # msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/release_notes/release_0.20.po b/doc/locale/fr/LC_MESSAGES/release_notes/release_0.20.po index 2eff53cea..495e0ae46 100644 --- a/doc/locale/fr/LC_MESSAGES/release_notes/release_0.20.po +++ b/doc/locale/fr/LC_MESSAGES/release_notes/release_0.20.po @@ -5,7 +5,6 @@ # msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/release_notes/release_1.00.po b/doc/locale/fr/LC_MESSAGES/release_notes/release_1.00.po index e90f5e4d4..1547a64e5 100644 --- a/doc/locale/fr/LC_MESSAGES/release_notes/release_1.00.po +++ b/doc/locale/fr/LC_MESSAGES/release_notes/release_1.00.po @@ -5,7 +5,6 @@ # msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/release_notes/release_1.01.po b/doc/locale/fr/LC_MESSAGES/release_notes/release_1.01.po index c932ae655..05a7fd2a2 100644 --- a/doc/locale/fr/LC_MESSAGES/release_notes/release_1.01.po +++ b/doc/locale/fr/LC_MESSAGES/release_notes/release_1.01.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/release_notes/release_1.02.po b/doc/locale/fr/LC_MESSAGES/release_notes/release_1.02.po index 6582434b4..6fff33a16 100644 --- a/doc/locale/fr/LC_MESSAGES/release_notes/release_1.02.po +++ b/doc/locale/fr/LC_MESSAGES/release_notes/release_1.02.po @@ -6,7 +6,6 @@ #, fuzzy msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/release_notes/release_1.03.po b/doc/locale/fr/LC_MESSAGES/release_notes/release_1.03.po index bce23bbfb..31222a321 100644 --- a/doc/locale/fr/LC_MESSAGES/release_notes/release_1.03.po +++ b/doc/locale/fr/LC_MESSAGES/release_notes/release_1.03.po @@ -5,7 +5,6 @@ # msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/doc/locale/fr/LC_MESSAGES/requirements.po b/doc/locale/fr/LC_MESSAGES/requirements.po index 1c822e5bb..2b6352ed9 100644 --- a/doc/locale/fr/LC_MESSAGES/requirements.po +++ b/doc/locale/fr/LC_MESSAGES/requirements.po @@ -7,17 +7,12 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" -"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2026-08-05 10:58+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" -"Language: fr\n" -"Language-Team: fr <LL@li.org>\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.18.0\n" msgid "The `datalab-platform` package requires the following Python modules:" msgstr "Le paquet `datalab-platform` nécessite les modules Python suivants :" @@ -290,4 +285,3 @@ msgstr "" #~ msgid ">= 1.1.4" #~ msgstr "" - From b8635fc068b81f8bfa0bf4c405e4ec67afb897ab Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Thu, 6 Aug 2026 13:22:13 +0200 Subject: [PATCH 079/108] Fix: Replay of load and save file actions in the History panel Replaying a session containing "Load files" or "Load from directory" actions misbehaved in two opposite ways: entries recorded by load_from_directory carried add_objects=False (the directory loader added the objects itself), so replaying them silently did nothing, while replaying a load action whose outputs were still present in the workspace duplicated the loaded objects. Moreover, replay re-assigns fresh UUIDs to loaded objects, so the action's recorded outputs went stale, breaking duplicate detection and downstream reconnection on the next replay. Finally, replaying a "Save" action silently overwrote files on disk without any confirmation. Load actions are now recorded at the right level and replayed idempotently, and file-save actions ask for confirmation before overwriting. * [FIX] : Skip load actions (new UI_LOAD_METHODS set) whose recorded outputs all still exist in the signal or image panel, so replaying a session no longer duplicates loaded objects * [FIX] : load_from_directory records its own history entry and captures its outputs; load_from_files records an entry only when it actually adds the objects to the workspace, so directory loads no longer leave non-replayable per-batch entries * [FIX] : Self-heal legacy load entries recorded with add_objects=False, and re-bind load actions to the freshly loaded objects after replay so the recorded outputs track the new UUIDs (searched across both data panels) * [FIX] : Ask for confirmation before replaying a file-save action (new FILE_OUTPUT_METHODS set: save_to_h5_file, save_to_files, save_to_directory), listing the files that would be overwritten; in unattended mode the action is skipped unless dialogs are auto-accepted * [CHG] : Add regression tests (history_replay_fixes_test.py) covering cross-panel output routing, load replay skip/self-heal/re-bind and the file-save confirmation; add the new UI strings to the French catalog --- datalab/gui/panel/base.py | 102 +++--- .../gui/panel/history/interactive_replay.py | 114 +++++++ datalab/history/action.py | 9 + datalab/locale/fr/LC_MESSAGES/datalab.po | 31 ++ .../common/history_replay_fixes_test.py | 299 ++++++++++++++++++ 5 files changed, 511 insertions(+), 44 deletions(-) create mode 100644 datalab/tests/features/common/history_replay_fixes_test.py diff --git a/datalab/gui/panel/base.py b/datalab/gui/panel/base.py index add3fff83..5b2592b27 100644 --- a/datalab/gui/panel/base.py +++ b/datalab/gui/panel/base.py @@ -2692,6 +2692,13 @@ def load_from_directory(self, directory: str | None = None) -> list[TypeObj]: return [] # Offer a fresh history session for this batch *before* loading anything. self.mainwindow.historypanel.maybe_start_session_for_input(load=True) + action = self.mainwindow.historypanel.add_ui_entry( + _('Load from directory "%s"') % osp.basename(osp.normpath(directory)), + target=self.PANEL_STR_ID + "panel", + method_name="load_from_directory", + save_state=False, + directory=directory, + ) folders = [ path for path in glob.glob(osp.join(directory, "**"), recursive=True) @@ -2699,38 +2706,39 @@ def load_from_directory(self, directory: str | None = None) -> list[TypeObj]: ] objs = [] with self.mainwindow.historypanel.session_prompt_suppressed(): - with create_progress_bar( - self, _("Scanning directory"), max_=len(folders) - 1 - ) as progress: - # Iterate over all subfolders in the directory: - for i_path, path in enumerate(folders): - progress.setValue(i_path + 1) - if progress.wasCanceled(): - break - path = osp.normpath(path) - fnames = sorted( - [ - osp.join(path, fname) - for fname in os.listdir(path) - if osp.isfile(osp.join(path, fname)) - ] - ) - new_objs = self.load_from_files( - fnames, - create_group=False, - add_objects=False, - ignore_errors=True, - ) - if new_objs: - objs += new_objs - grp_name = osp.relpath(path, directory) - if grp_name == ".": - grp_name = osp.basename(path) - grp = self.add_group(grp_name) - for obj in new_objs: - self.add_object( - obj, group_id=get_uuid(grp), set_current=False - ) + with self.mainwindow.historypanel.capture_outputs(action): + with create_progress_bar( + self, _("Scanning directory"), max_=len(folders) - 1 + ) as progress: + # Iterate over all subfolders in the directory: + for i_path, path in enumerate(folders): + progress.setValue(i_path + 1) + if progress.wasCanceled(): + break + path = osp.normpath(path) + fnames = sorted( + [ + osp.join(path, fname) + for fname in os.listdir(path) + if osp.isfile(osp.join(path, fname)) + ] + ) + new_objs = self.load_from_files( + fnames, + create_group=False, + add_objects=False, + ignore_errors=True, + ) + if new_objs: + objs += new_objs + grp_name = osp.relpath(path, directory) + if grp_name == ".": + grp_name = osp.basename(path) + grp = self.add_group(grp_name) + for obj in new_objs: + self.add_object( + obj, group_id=get_uuid(grp), set_current=False + ) return objs def load_from_files( @@ -2769,18 +2777,24 @@ def load_from_files( entry_title = _("Load from %d files") % nbf else: entry_title = _('Load "%s"') % osp.basename(filenames[0]) - # Offer a fresh history session for this batch *before* recording any entry. - self.mainwindow.historypanel.maybe_start_session_for_input(load=True) - action = self.mainwindow.historypanel.add_ui_entry( - entry_title, - target=self.PANEL_STR_ID + "panel", - method_name="load_from_files", - save_state=False, - filenames=filenames, - create_group=create_group, - add_objects=add_objects, - ignore_errors=ignore_errors, - ) + # Only record a history entry when this call actually adds the objects to + # the workspace; otherwise the caller is responsible for adding *and* + # recording (e.g. ``load_from_directory``). + action = None + if add_objects: + # Offer a fresh history session for this batch *before* recording + # any entry. + self.mainwindow.historypanel.maybe_start_session_for_input(load=True) + action = self.mainwindow.historypanel.add_ui_entry( + entry_title, + target=self.PANEL_STR_ID + "panel", + method_name="load_from_files", + save_state=False, + filenames=filenames, + create_group=create_group, + add_objects=add_objects, + ignore_errors=ignore_errors, + ) objs = [] with self.mainwindow.historypanel.session_prompt_suppressed(): with self.mainwindow.historypanel.capture_outputs(action): diff --git a/datalab/gui/panel/history/interactive_replay.py b/datalab/gui/panel/history/interactive_replay.py index 3aaf93ef1..016af9035 100644 --- a/datalab/gui/panel/history/interactive_replay.py +++ b/datalab/gui/panel/history/interactive_replay.py @@ -131,6 +131,73 @@ def prompt_edit_action_params( return True +def _load_outputs_still_exist(panel: HistoryPanel, action: HistoryAction) -> bool: + """Return True if all recorded load outputs still exist in a data panel. + + Args: + panel: History panel instance + action: Load action (``UI_LOAD_METHODS``) to check + + Returns: + True if the action recorded at least one output UUID and every one of + them still exists in either the signal or the image panel. + """ + output_uuids = hchain.recorded_action_output_uuids(panel, action) + if not output_uuids: + return False + panels = (panel.mainwindow.signalpanel, panel.mainwindow.imagepanel) + return all(any(p.objmodel.has_uuid(uid) for p in panels) for uid in output_uuids) + + +def confirm_file_output_replay(panel: HistoryPanel, action: HistoryAction) -> bool: + """Ask the user to confirm the replay of a file-save action. + + Replaying a file-output action (``FILE_OUTPUT_METHODS``) overwrites the + files recorded in the action kwargs, so one confirmation question is asked + per action. In unattended mode no dialog is shown: the action is skipped + by default and replayed only when ``execenv.accept_dialogs`` is set. + + Args: + panel: History panel instance + action: File-output action (``FILE_OUTPUT_METHODS``) to confirm + + Returns: + True if the action should be replayed. + """ + if execenv.unattended: + return bool(execenv.accept_dialogs) + names: list[str] = [] + filename = action.kwargs.get("filename") + if isinstance(filename, str): + names.append(filename) + filenames = action.kwargs.get("filenames") + if isinstance(filenames, (list, tuple)): + names.extend(str(fname) for fname in filenames) + if not names: + # ``save_to_directory``: the destination is carried by the recorded + # parameter object (inspected defensively, format may evolve). + param = action.kwargs.get("param") + directory = getattr(param, "directory", None) + if directory: + pattern = getattr(param, "basename", None) + extension = getattr(param, "extension", None) + if pattern: + names.append(f"{directory} ({pattern}{extension or ''})") + else: + names.append(str(directory)) + if not names: + names.append(action.title or action.uuid) + answer = QW.QMessageBox.question( + panel.mainwindow, + _("Replay file save"), + _("This action will overwrite the following file(s):\n%s\n\nReplay it?") + % "\n".join(names), + QW.QMessageBox.Yes | QW.QMessageBox.No, + QW.QMessageBox.No, + ) + return answer == QW.QMessageBox.Yes + + def _recompute_stale_actions(panel: HistoryPanel, ordered: list[HistoryAction]) -> None: """Recompute stale actions in place after a dialog rollback. @@ -240,11 +307,58 @@ def replay_actions( # Mutation targeting an object whose recompute failed # upstream: skip it like a blocked compute. continue + is_load_action = ( + action.kind == HistoryAction.KIND_UI + and action.method_name in HistoryAction.UI_LOAD_METHODS + ) + if is_load_action: + if _load_outputs_still_exist(panel, action): + # All loaded objects still exist: replaying would + # duplicate them, so skip the load action. + continue + if action.kwargs.get("add_objects") is False: + # Legacy entries recorded by ``load_from_directory`` + # with ``add_objects=False``: self-heal so replay + # actually adds the loaded objects. + action.kwargs["add_objects"] = True + if ( + action.kind == HistoryAction.KIND_UI + and action.method_name in HistoryAction.FILE_OUTPUT_METHODS + and not confirm_file_output_replay(panel, action) + ): + # User declined (or unattended default): skip the + # file-save action cleanly, the plan continues. + continue + data_panels = ( + panel.mainwindow.signalpanel, + panel.mainwindow.imagepanel, + ) + before_ids = ( + { + p.PANEL_STR_ID: set(p.objmodel.get_object_ids()) + for p in data_panels + } + if is_load_action + else None + ) payload_before = action.kwargs.get("payload") with panel.replaying(), panel.output_suppressed(): action.replay( panel.mainwindow, restore_selection=True, edit=prompt ) + if before_ids is not None: + new_uuids = [ + uid + for p in data_panels + for uid in p.objmodel.get_object_ids() + if uid not in before_ids[p.PANEL_STR_ID] + ] + if new_uuids: + # Re-bind the load action to the freshly loaded + # objects: replay assigns new UUIDs, and stale + # recorded outputs would break duplicate detection + # and downstream reconnection. + panel.register_action_outputs(action, new_uuids) if ( prompt and action.kind == HistoryAction.KIND_MUTATION diff --git a/datalab/history/action.py b/datalab/history/action.py index 43aebfe93..b2de67956 100644 --- a/datalab/history/action.py +++ b/datalab/history/action.py @@ -102,11 +102,20 @@ class HistoryAction(ObjItf): # Object-creation actions skipped during non-persistent (output-suppressed) # replay so the panel object count stays stable. UI_CREATION_METHODS: frozenset[str] = frozenset({"new_object"}) + # UI methods that (re)load objects from disk into the workspace. + UI_LOAD_METHODS: frozenset[str] = frozenset( + {"load_from_files", "load_from_directory"} + ) # UI methods that destroy data objects. Replaying these requires that the # captured selection still resolves to existing objects (see ``replay_ui``). DESTRUCTIVE_METHODS: frozenset[str] = frozenset( {"remove_object", "remove_group", "delete_all_objects"} ) + # UI methods that write files on disk. Replaying them silently would + # overwrite user files, so the replay engine asks for confirmation. + FILE_OUTPUT_METHODS: frozenset[str] = frozenset( + {"save_to_h5_file", "save_to_files", "save_to_directory"} + ) @dataclass class Descriptors: diff --git a/datalab/locale/fr/LC_MESSAGES/datalab.po b/datalab/locale/fr/LC_MESSAGES/datalab.po index 844d1d3fd..d03abd1e2 100644 --- a/datalab/locale/fr/LC_MESSAGES/datalab.po +++ b/datalab/locale/fr/LC_MESSAGES/datalab.po @@ -4186,6 +4186,10 @@ msgstr "Renommer l'objet ou le groupe sélectionné" msgid "Set current object title to \"%s\"" msgstr "Définir le titre de l'objet courant à \"%s\"" +#, python-format +msgid "Load from directory \"%s\"" +msgstr "Charger depuis le répertoire \"%s\"" + #, python-format msgid "Load from %d files" msgstr "Charger depuis %d fichiers" @@ -4242,6 +4246,21 @@ msgstr "" msgid "The current workspace state is not compatible with the action." msgstr "L'état actuel de l'espace de travail n'est pas compatible avec l'action." +msgid "Replay file save" +msgstr "Rejouer l'enregistrement de fichier" + +#, python-format +msgid "" +"This action will overwrite the following file(s):\n" +"%s\n" +"\n" +"Replay it?" +msgstr "" +"Cette action écrasera le(s) fichier(s) suivant(s) :\n" +"%s\n" +"\n" +"La rejouer ?" + #, python-format msgid "Action %s has no recorded pattern and cannot be replayed." msgstr "L'action %s n'a pas de motif enregistré et ne peut pas être rejouée." @@ -4294,6 +4313,18 @@ msgstr "" "Classe de paramètre requise : %(param)s\n" "Réinstallez le plugin pour réactiver cette action." +#, python-format +msgid "Action %s: no recorded output object — skipping." +msgstr "Action %s : aucun objet de sortie enregistré — ignorée." + +#, python-format +msgid "Action %s: the initial object was deleted and cannot be re-created (no creation parameters)." +msgstr "Action %s : l'objet initial a été supprimé et ne peut pas être recréé (aucun paramètre de création)." + +#, python-format +msgid "Action %s: creation parameters could not be prepared — skipping." +msgstr "Action %s : les paramètres de création n'ont pas pu être préparés — ignorée." + #, python-format msgid "Action %s: source object was deleted — skipping." msgstr "Action %s : l'objet source a été supprimé — ignorée." diff --git a/datalab/tests/features/common/history_replay_fixes_test.py b/datalab/tests/features/common/history_replay_fixes_test.py new file mode 100644 index 000000000..675223a6f --- /dev/null +++ b/datalab/tests/features/common/history_replay_fixes_test.py @@ -0,0 +1,299 @@ +# Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file. + +"""Regression tests for History panel replay fixes. + +Covers cross-panel output routing, synthetic session heads, file-save +confirmation and load-action replay (plan ``history-replay-fixes``). +""" + +from __future__ import annotations + +import os +import os.path as osp +from unittest.mock import patch + +import numpy as np +import sigima.params +import sigima.proc.signal as sips +from sigima.tests.data import create_sincos_image + +from datalab.env import execenv +from datalab.gui.panel.history import interactive_replay as hireplay +from datalab.gui.panel.history import recompute as hrec +from datalab.tests import datalab_test_app_context +from datalab.tests.features.common.history_test_helpers import add_paracetamol_signals + + +def record_line_profile(win) -> tuple: + """Record an image line-profile compute and return (action, output_uuid). + + Args: + win: DataLab main window with history recording enabled + + Returns: + Recorded cross-panel compute action and its output signal UUID + """ + history, ipanel = win.historypanel, win.imagepanel + ipanel.add_object(create_sincos_image()) + ipanel.objview.select_objects([1]) + param = sigima.params.LineProfileParam.create( + direction="horizontal", row=100, col=100 + ) + ipanel.processor.run_feature("line_profile", param) + action = history[len(history)] + return action, action.output_uuids[0] + + +def test_replay_cross_panel_output_stays_in_destination_panel() -> None: + """Keep cross-panel compute outputs in the destination panel on replay.""" + with datalab_test_app_context(history=True) as win: + history = win.historypanel + history.toggle_record_mode(True) + action, output_uuid = record_line_profile(win) + spanel, ipanel = win.signalpanel, win.imagepanel + assert spanel.objmodel.has_uuid(output_uuid) + assert not ipanel.objmodel.has_uuid(output_uuid) + image_count = len(ipanel.objmodel) + signal_count = len(spanel.objmodel) + for _replay_nb in range(2): + hireplay.replay_actions(history, [action], prompt=False) + assert action.is_stale is False + assert spanel.objmodel.has_uuid(output_uuid) + assert not ipanel.objmodel.has_uuid(output_uuid) + assert len(ipanel.objmodel) == image_count + assert len(spanel.objmodel) == signal_count + + +def test_replay_recreates_deleted_cross_panel_output_in_destination_panel() -> None: + """Re-create a deleted cross-panel output in the destination panel.""" + with datalab_test_app_context(history=True) as win: + history = win.historypanel + history.toggle_record_mode(True) + action, output_uuid = record_line_profile(win) + spanel, ipanel = win.signalpanel, win.imagepanel + expected_data = spanel.objmodel[output_uuid].xydata.copy() + image_count = len(ipanel.objmodel) + spanel.objview.select_objects([output_uuid]) + spanel.remove_object(force=True) + assert not spanel.objmodel.has_uuid(output_uuid) + + with patch.object(hrec, "flush_cascade_warnings"): + hireplay.replay_actions(history, [action], prompt=False) + + assert history.runtime.execution.cascade_warnings == [] + assert action.is_stale is False + assert spanel.objmodel.has_uuid(output_uuid) + assert not ipanel.objmodel.has_uuid(output_uuid) + assert len(ipanel.objmodel) == image_count + recreated = spanel.objmodel[output_uuid] + assert np.array_equal(recreated.xydata, expected_data) + + +def build_synthetic_head_chain(win) -> list: + """Record a creation + two computes, then clear the head kwargs. + + Mirrors the synthetic session head produced by *Duplicate chain* + (``new_object`` UI action with empty kwargs). + + Args: + win: DataLab main window with history recording enabled + + Returns: + The three recorded actions in session order (head first) + """ + history, panel = win.historypanel, win.signalpanel + panel.new_object(edit=False) + head = history[len(history)] + assert head.method_name == "new_object" + panel.objview.select_objects(head.output_uuids) + panel.processor.run_feature( + sips.gaussian_filter, sigima.params.GaussianParam.create(sigma=1.5) + ) + first = history[len(history)] + panel.objview.select_objects(first.output_uuids) + panel.processor.run_feature(sips.derivative) + second = history[len(history)] + head.kwargs.clear() # Simulate the Duplicate-chain synthetic head + return [head, first, second] + + +def test_replay_synthetic_head_without_param_is_noop_success() -> None: + """Treat a parameterless creation head with live outputs as a no-op.""" + with datalab_test_app_context(history=True) as win: + history = win.historypanel + history.toggle_record_mode(True) + actions = build_synthetic_head_chain(win) + + with patch.object(hrec, "flush_cascade_warnings"): + hireplay.replay_actions(history, actions, prompt=False) + + assert history.runtime.execution.cascade_warnings == [] + assert all(not action.is_stale for action in actions) + + +def test_replay_synthetic_head_with_deleted_output_warns() -> None: + """Warn and keep the chain stale when the head object was deleted.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + actions = build_synthetic_head_chain(win) + head = actions[0] + deleted_uuids = [ + output_uuid for action in actions for output_uuid in action.output_uuids + ] + panel.objview.select_objects(deleted_uuids) + panel.remove_object(force=True) + + with patch.object(hrec, "flush_cascade_warnings"): + hireplay.replay_actions(history, actions, prompt=False) + + warnings = history.runtime.execution.cascade_warnings + assert warnings + assert any(head.title in warning for warning in warnings) + assert all(action.is_stale for action in actions) + history.runtime.execution.cascade_warnings.clear() + + +def record_file_save(win, filename: str): + """Record a ``save_to_files`` action writing one signal to ``filename``. + + Args: + win: DataLab main window with history recording enabled + filename: Destination file name + + Returns: + Recorded file-save UI action + """ + history, panel = win.historypanel, win.signalpanel + add_paracetamol_signals(panel, 1) + panel.objview.select_objects([1]) + panel.save_to_files([filename]) + action = history[len(history)] + assert action.method_name == "save_to_files" + assert osp.isfile(filename) + return action + + +def test_replay_skips_file_save_without_confirmation(tmp_path) -> None: + """Skip file-save actions on unattended replay without accept_dialogs.""" + with datalab_test_app_context(history=True) as win: + history = win.historypanel + history.toggle_record_mode(True) + filename = str(tmp_path / "signal.csv") + action = record_file_save(win, filename) + os.remove(filename) + assert execenv.unattended and not execenv.accept_dialogs + + hireplay.replay_actions(history, [action], prompt=False) + + assert not osp.isfile(filename) + assert action.is_stale is False + + +def test_replay_file_save_with_accept_dialogs(tmp_path) -> None: + """Replay file-save actions when accept_dialogs is enabled.""" + with datalab_test_app_context(history=True) as win: + history = win.historypanel + history.toggle_record_mode(True) + filename = str(tmp_path / "signal.csv") + action = record_file_save(win, filename) + os.remove(filename) + saved_accept_dialogs = execenv.accept_dialogs + execenv.accept_dialogs = True + try: + hireplay.replay_actions(history, [action], prompt=False) + finally: + execenv.accept_dialogs = saved_accept_dialogs + + assert osp.isfile(filename) + assert action.is_stale is False + + +def populate_signal_directory(win, directory, layout: dict[str, list[str]]) -> None: + """Write round-trip-compatible signal files into ``directory``. + + Signals are saved through the panel I/O registry so the written files are + guaranteed to load back. No history entry is recorded (record mode off). + + Args: + win: DataLab main window (record mode must be disabled) + directory: Base directory (``pathlib.Path``) + layout: Mapping of subdirectory name ("" for the base directory) to + file names + """ + panel = win.signalpanel + assert not win.historypanel.record_mode_enabled + add_paracetamol_signals(panel, 1) + panel.objview.select_objects([1]) + for subdir_name, filenames in layout.items(): + subdir = directory / subdir_name if subdir_name else directory + subdir.mkdir(exist_ok=True) + for filename in filenames: + panel.save_to_files([str(subdir / filename)]) + panel.remove_object(force=True) + assert len(panel.objmodel) == 0 + + +def test_replay_load_from_directory_reloads_deleted_objects(tmp_path) -> None: + """Reload deleted objects (and groups) by replaying a directory load.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + populate_signal_directory( + win, + tmp_path, + {"suba": ["s1.csv", "s2.csv"], "subb": ["s3.csv", "s4.csv"]}, + ) + history.toggle_record_mode(True) + objs = panel.load_from_directory(str(tmp_path)) + assert len(objs) == 4 + action = history[len(history)] + assert action.method_name == "load_from_directory" + assert len(action.output_uuids) == 4 + group_titles = [group.title for group in panel.objmodel.get_groups()] + assert "suba" in group_titles and "subb" in group_titles + # Delete every loaded object + history.toggle_record_mode(False) + panel.objview.select_objects(panel.objmodel.get_object_ids()) + panel.remove_object(force=True) + assert len(panel.objmodel) == 0 + history.toggle_record_mode(True) + + hireplay.replay_actions(history, [action], prompt=False) + + assert len(panel.objmodel) == 4 + assert action.is_stale is False + # Outputs re-bound to the freshly loaded objects + assert len(action.output_uuids) == 4 + assert all( + panel.objmodel.has_uuid(output_uuid) for output_uuid in action.output_uuids + ) + # Group structure (one group per subdirectory) is re-created + reloaded_groups = { + group.title: len(group.get_object_ids()) + for group in panel.objmodel.get_groups() + if group.get_object_ids() + } + assert reloaded_groups.get("suba") == 2 + assert reloaded_groups.get("subb") == 2 + + +def test_replay_load_skipped_when_outputs_still_exist(tmp_path) -> None: + """Skip a load-action replay when every loaded object still exists.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + populate_signal_directory(win, tmp_path, {"": ["s1.csv", "s2.csv"]}) + history.toggle_record_mode(True) + objs = panel.load_from_directory(str(tmp_path)) + assert len(objs) == 2 + action = history[len(history)] + assert action.method_name == "load_from_directory" + object_count = len(panel.objmodel) + group_count = len(panel.objmodel.get_groups()) + output_uuids_before = list(action.output_uuids) + + hireplay.replay_actions(history, [action], prompt=False) + + assert len(panel.objmodel) == object_count + assert len(panel.objmodel.get_groups()) == group_count + assert action.output_uuids == output_uuids_before + assert action.is_stale is False From 3d6aa3055e9a6dc760287fe37d2e33a059415405 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Thu, 6 Aug 2026 15:25:00 +0200 Subject: [PATCH 080/108] Fix: Reuse UI processing for history replay and correct load accounting History compute replay used separate per-pattern execution paths that had drifted from the processor behavior used by menus. This broke grouped and batched selections, pairwise operations, and reliable recreation of deleted outputs. Replay now delegates output-producing patterns to the public processor entry points and reconciles temporary results onto recorded UUIDs. Dedicated analysis effects and ROI mutation paths remain preserved, while load records reflect only the files and objects actually loaded. * [FIX] : Replay all output-producing compute patterns through their public processor entry points, including grouped, batched, pairwise, and multi-selection workflows * [FIX] : Reconcile temporary results onto durable recorded UUIDs and recreate deleted outputs in the correct panel and group * [FIX] : Remove temporary outputs and roll back existing objects when replay fails or returns an unexpected output count * [CHG] : Keep 1-to-0 analysis effects and ROI mutations on their dedicated replay paths, with non-interactive X-array compatibility handling * [FIX] : Discard empty load entries and correct partial-load titles and filenames to include only successfully loaded files * [NEW] : Add regression coverage for compute replay, deleted outputs, rollback behavior, load accounting, and updated French translations --- datalab/gui/historysession_ops.py | 47 +- datalab/gui/panel/base.py | 18 +- datalab/gui/panel/history/recompute.py | 704 ++++++++---------- datalab/gui/processor/base.py | 175 +---- datalab/history/action.py | 5 + datalab/locale/fr/LC_MESSAGES/datalab.po | 16 +- .../common/history_model_unit_test.py | 2 +- .../common/history_replay_fixes_test.py | 260 ++++++- .../features/common/history_workflow_test.py | 388 ++++------ datalab/widgets/historytree.py | 1 + 10 files changed, 774 insertions(+), 842 deletions(-) diff --git a/datalab/gui/historysession_ops.py b/datalab/gui/historysession_ops.py index 23648c08d..550abaeae 100644 --- a/datalab/gui/historysession_ops.py +++ b/datalab/gui/historysession_ops.py @@ -131,8 +131,8 @@ def add_compute_entry( func_name: Sigima feature name (resolvable via :meth:`BaseProcessor.get_feature`). pattern: One of ``"1_to_1"``, ``"1_to_0"``, ``"n_to_1"``, ``"2_to_1"``, - ``"1_to_n"``, ``"multiple_1_to_1"`` (the latter is recorded for - traceability but not replayable). + ``"1_to_n"``, ``"multiple_1_to_1"`` (the latter is replayable via + the generic compute replay, like the other compute patterns). save_state: If True, capture the workspace state for replay. output_uuids: Optional list of UUIDs of the data objects produced by this action. When known at call time, prefer passing it here so the @@ -279,19 +279,36 @@ def capture_outputs( if uid not in before_p: new_uuids.append(uid) panel.register_action_outputs(action, new_uuids) - if ( - not new_uuids - and action.kind == HistoryAction.KIND_COMPUTE - and action.pattern in {"1_to_1", "1_to_n", "n_to_1", "2_to_1"} - ): - # The compute produced no output object for any selected input: - # it failed (or was a full no-op). Do not keep a misleading "OK" - # entry in the history — remove the just-recorded action and - # refresh the tree so the panel stays consistent. - hchain.remove_single_action(panel, action) - panel.tree.populate_tree(panel.history_sessions) - panel.refresh_compatibility_items() - panel.ui.update_actions_state() + if not new_uuids: + no_output_compute = action.kind == HistoryAction.KIND_COMPUTE and ( + action.pattern + in {"1_to_1", "multiple_1_to_1", "1_to_n", "n_to_1", "2_to_1"} + ) + no_output_load = ( + action.kind == HistoryAction.KIND_UI + and action.method_name in HistoryAction.UI_LOAD_METHODS + ) + if no_output_compute or no_output_load: + # The action produced no output object: either the compute + # failed (or was a full no-op), or the load found nothing + # readable for the panel. Do not keep a misleading entry in + # the history. + discard_empty_output_action(panel, action) + + +def discard_empty_output_action(panel: HistoryPanel, action: HistoryAction) -> None: + """Remove a just-recorded action that produced no output object. + + Removes the action from the session chain and refreshes the tree so the + panel stays consistent. + + Args: + action: The history action to discard. + """ + hchain.remove_single_action(panel, action) + panel.tree.populate_tree(panel.history_sessions) + panel.refresh_compatibility_items() + panel.ui.update_actions_state() def add_ui_entry( diff --git a/datalab/gui/panel/base.py b/datalab/gui/panel/base.py index 5b2592b27..6d6fb01b4 100644 --- a/datalab/gui/panel/base.py +++ b/datalab/gui/panel/base.py @@ -2796,13 +2796,14 @@ def load_from_files( ignore_errors=ignore_errors, ) objs = [] + loaded_filenames: list[str] = [] with self.mainwindow.historypanel.session_prompt_suppressed(): with self.mainwindow.historypanel.capture_outputs(action): for filename in filenames: with qt_try_loadsave_file(self.parentWidget(), filename, "load"): Conf.main.base_dir.set(filename) try: - objs += self.__load_from_file( + new_objs = self.__load_from_file( filename, create_group=create_group, add_objects=add_objects, @@ -2813,6 +2814,21 @@ def load_from_files( pass else: raise exc + else: + objs += new_objs + if new_objs: + loaded_filenames.append(filename) + if action is not None and loaded_filenames and len(loaded_filenames) < nbf: + # Some files could not be loaded: make the recorded entry reflect + # the files actually loaded, so the title is accurate and replay + # does not re-attempt the failed files. (If *no* file was loaded, + # ``capture_outputs`` already discarded the entry.) + if len(loaded_filenames) > 1: + action.title = _("Load from %d files") % len(loaded_filenames) + else: + action.title = _('Load "%s"') % osp.basename(loaded_filenames[0]) + action.kwargs["filenames"] = loaded_filenames + self.mainwindow.historypanel.tree.refresh_action_item(action) return objs def save_to_files(self, filenames: list[str] | str | None = None) -> None: diff --git a/datalab/gui/panel/history/recompute.py b/datalab/gui/panel/history/recompute.py index 13c05bc29..408b35382 100644 --- a/datalab/gui/panel/history/recompute.py +++ b/datalab/gui/panel/history/recompute.py @@ -149,33 +149,6 @@ def resolve_output_panel( return fallback -def record_missing_outputs( - panel: HistoryPanel, action: HistoryAction, missing: list[str] -) -> None: - """Log + queue a user-facing warning for deleted output objects. - - Only used for genuinely irrecoverable cases (e.g. recorded outputs that - cannot be aligned with the action's parameters); recoverable deletions - are handled by :func:`apply_output_in_place_or_recreate`. - """ - if not missing: - return - name = action.func_name or action.title or action.uuid - _logger.warning( - "Cascade recompute: %d output(s) missing for action %s (%s).", - len(missing), - action.uuid, - name, - ) - panel.runtime.execution.cascade_warnings.append( - _( - "Action %s has been edited but its target output object(s) " - "no longer exist — skipping." - ) - % name - ) - - def apply_output_in_place_or_recreate( panel: HistoryPanel, panel_data: BaseDataPanel, @@ -283,10 +256,11 @@ def recompute_action_in_place(panel: HistoryPanel, action: HistoryAction) -> boo if action.kind != HistoryAction.KIND_COMPUTE: return False method = { - "1_to_1": recompute_1_to_1_in_place, - "1_to_n": recompute_1_to_n_in_place, - "n_to_1": recompute_n_to_1_in_place, - "2_to_1": recompute_2_to_1_in_place, + "1_to_1": recompute_compute_in_place, + "multiple_1_to_1": recompute_compute_in_place, + "1_to_n": recompute_compute_in_place, + "n_to_1": recompute_compute_in_place, + "2_to_1": recompute_compute_in_place, "1_to_0": recompute_1_to_0_in_place, }.get(action.pattern or "") if method is None: @@ -421,283 +395,282 @@ def recompute_creation_in_place(panel: HistoryPanel, action: HistoryAction) -> b return True -def recompute_1_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> bool: - """Recompute a single 1-to-1 action in place. +def execute_compute_via_ui( + panel_data: BaseDataPanel, + action: HistoryAction, + obj2_uuids: list[str], +) -> None: + """Invoke the public processor entry point matching ``action``'s pattern. - If the output object was deleted, it is re-created under its recorded - UUID; the source is then resolved from the action's captured state. + This is the same code path the menus use (``compute_1_to_1``, + ``compute_multiple_1_to_1``, ``compute_1_to_n``, ``compute_n_to_1``, + ``compute_2_to_1``), so multi-selection batching, group creation, + pairwise mode, X-array compatibility, progress bars and error handling + are reused by construction. The recorded parameters are deep-copied so + replay never mutates (nor shares) the action's own kwargs, and + ``edit=False`` suppresses parameter dialogs (edit-mode prompting is + handled upstream by the interactive replay). + + Args: + panel_data: Data panel targeted by the action. + action: Compute-kind history action to re-execute. + obj2_uuids: Recorded second-operand UUIDs (2-to-1 pattern only). + + Raises: + FeatureNotFoundError: If the feature is not registered (missing + plugin), propagated to :func:`recompute_action_in_place`. """ - panel_data = hchain.resolve_panel_for_action(panel, action) - if panel_data is None: - return False - recorded = hchain.recorded_action_output_uuids(panel, action) - if not recorded: - return False - output_uuid = recorded[0] - output_panel = resolve_output_panel(panel, output_uuid, None, panel_data) - output_obj = ( - output_panel.objmodel[output_uuid] - if output_panel.objmodel.has_uuid(output_uuid) - else None - ) - pp = extract_processing_parameters(output_obj) if output_obj is not None else None - source_uuid = pp.source_uuid if pp is not None and pp.source_uuid else None - if source_uuid is None: - selection = action.state.selection.get(panel_data.PANEL_STR_ID, []) - source_uuid = selection[0] if selection else None - if source_uuid is None: - return False - if not panel_data.objmodel.has_uuid(source_uuid): - panel.runtime.execution.cascade_warnings.append( - _("Action %s: source object was deleted — skipping.") - % (action.func_name or action.uuid) + processor = panel_data.processor + title = action.title or action.func_name + if action.pattern == "multiple_1_to_1": + func_names = action.kwargs.get("func_names") or ( + [action.func_name] if action.func_name else [] ) - return False - source_obj = panel_data.objmodel[source_uuid] - param = action.kwargs.get("param") - plugin_origin = action.plugin_origin or (pp.plugin_origin if pp else None) - compout = panel_data.processor.recompute_1_to_1( + funcs = [ + processor.get_feature( + func_name, plugin_origin=action.plugin_origin + ).function + for func_name in func_names + ] + params = action.kwargs.get("params") + processor.compute_multiple_1_to_1( + funcs, + params=copy.deepcopy(params) if params is not None else None, + title=title, + edit=False, + ) + return + if action.pattern == "1_to_n": + params = [copy.deepcopy(param) for param in action.kwargs.get("params") or []] + feature = processor.get_feature( + action.func_name, + plugin_origin=action.plugin_origin, + paramclass_name=type(params[0]).__name__ if params else None, + ) + processor.compute_1_to_n( + feature.function, params=params, title=title, edit=False + ) + return + param = copy.deepcopy(action.kwargs.get("param")) + feature = processor.get_feature( action.func_name, - source_obj, - param, - plugin_origin=plugin_origin, + plugin_origin=action.plugin_origin, + paramclass_name=type(param).__name__ if param is not None else None, ) - if compout.cancelled: - return False - if compout.error_msg: - panel.runtime.execution.cascade_warnings.append( - _("Recompute failed for action %s: %s") - % (action.func_name or action.uuid, compout.error_msg) + if action.pattern == "1_to_1": + processor.compute_1_to_1(feature.function, param=param, title=title, edit=False) + elif action.pattern == "n_to_1": + processor.compute_n_to_1( + feature.function, + param=param, + title=title, + edit=False, + pairwise=bool(action.kwargs.get("pairwise")), ) - return False - new_obj = compout.result - if not isinstance(new_obj, (SignalObj, ImageObj)): - return False - pp_new = ProcessingParameters( - func_name=pp.func_name if pp is not None else action.func_name, - pattern=pp.pattern if pp is not None else "1-to-1", - param=param if param is not None else (pp.param if pp is not None else None), - source_uuid=source_uuid, - plugin_origin=plugin_origin, - ) - output_panel = resolve_output_panel(panel, output_uuid, new_obj, panel_data) - if output_obj is not None: - # Preserve the existing output's own metadata (ROIs, annotations...) - output_panel.objprop.apply_recomputed_object_in_place( - output_obj, new_obj, pp_new + elif action.pattern == "2_to_1": + objs2 = [panel_data.objmodel[uuid] for uuid in obj2_uuids] + pairwise = bool(action.kwargs.get("pairwise")) + processor.compute_2_to_1( + objs2 if pairwise else objs2[0], + action.kwargs.get("obj2_name") or feature.obj2_name or _("Second operand"), + feature.function, + param=param, + title=title, + edit=False, + skip_xarray_compat=feature.skip_xarray_compat, + pairwise=pairwise, + pre_execute_hook=feature.pre_execute_hook, ) else: - apply_output_in_place_or_recreate( - panel, - output_panel, - action, - output_uuid, - new_obj, - pp_new, - group_id=( - panel_data.objmodel.get_object_group_id(source_obj) - if output_panel is panel_data - else None - ), - ) - refresh_target(output_panel, output_uuid) - return True + raise ValueError(f"Unsupported compute pattern: {action.pattern!r}") -def recompute_1_to_n_in_place(panel: HistoryPanel, action: HistoryAction) -> bool: - """Recompute a 1-to-n action in place: replace each of the N outputs. +def _detach_object(panel_data: BaseDataPanel, obj_uuid: str) -> SignalObj | ImageObj: + """Remove ``obj_uuid`` from ``panel_data`` and return the live instance. - Deleted outputs are re-created under their recorded UUIDs; indices of - ``action.output_uuids`` align with the recorded ``params`` list. + Low-level counterpart of ``BaseDataPanel.remove_object`` used for the + temporary objects created by an execute-via-UI replay: no history entry, + no removal signal (the object was never a real workspace output). """ - panel_data = hchain.resolve_panel_for_action(panel, action) - if panel_data is None: - return False - params = action.kwargs.get("params") or [] - recorded = hchain.recorded_action_output_uuids(panel, action) - if not recorded or not params: - return False - # Resolve against the first recorded output still owned by a panel, so a - # deleted recorded[0] does not fall back to the wrong (action) panel. - resolve_uuid = next( + obj = panel_data.objmodel[obj_uuid] + panel_data.plothandler.remove_item(obj_uuid) + panel_data.objview.remove_item(obj_uuid, refresh=False) + panel_data.objmodel.remove_object(obj) + panel_data.objview.update_tree() + return obj + + +def _discard_new_empty_groups( + data_panels: tuple[BaseDataPanel, ...], + before_groups: dict[str, set[str]], +) -> None: + """Remove empty groups created by an execute-via-UI replay batch.""" + for panel_data in data_panels: + removed = False + for group in list(panel_data.objmodel.get_groups()): + group_uuid = get_uuid(group) + if group_uuid in before_groups[panel_data.PANEL_STR_ID]: + continue + if group.get_object_ids(): + continue + panel_data.objview.remove_item(group_uuid, refresh=False) + panel_data.objmodel.remove_group(group) + removed = True + if removed: + panel_data.objview.update_tree() + + +def _restore_selection( + data_panels: tuple[BaseDataPanel, ...], + saved_selection: dict[str, list[str]], +) -> None: + """Best-effort restore of the pre-replay object and group selection.""" + for panel_data in data_panels: + group_uuids = {get_uuid(grp) for grp in panel_data.objmodel.get_groups()} + uuids = [ + uuid + for uuid in saved_selection[panel_data.PANEL_STR_ID] + if panel_data.objmodel.has_uuid(uuid) or uuid in group_uuids + ] + for idx, uuid in enumerate(uuids): + panel_data.objview.set_current_item_id(uuid, extend=idx > 0) + + +def _commit_outputs( + panel: HistoryPanel, + panel_data: BaseDataPanel, + action: HistoryAction, + recorded: list[str], + detached: list[tuple[BaseDataPanel, SignalObj | ImageObj]], +) -> None: + """Commit fresh outputs onto the recorded outputs (index-aligned). + + Recorded outputs that still exist are updated in place; deleted outputs + are re-created under their original recorded UUIDs, preferring the group + of a surviving sibling output, then the first source's group. For 1-to-1 + family patterns, existing outputs keep their own metadata (ROIs, + annotations, analysis results...) and only their processing parameters + are refreshed, matching the behavior of a manual re-processing. On + failure, previously existing outputs are restored from snapshots before + the exception is propagated. + + Args: + panel: History panel instance. + panel_data: Data panel targeted by the action. + action: Compute-kind history action being reconciled. + recorded: Recorded output UUIDs, in recording order. + detached: Freshly computed objects (with their creation panel), in + creation order, index-aligned with ``recorded``. + """ + sources = action.state.selection.get(panel_data.PANEL_STR_ID, []) + fallback_gid = None + if sources and panel_data.objmodel.has_uuid(sources[0]): + fallback_gid = panel_data.objmodel.get_object_group_id( + panel_data.objmodel[sources[0]] + ) + preserve_metadata = action.pattern in {"1_to_1", "multiple_1_to_1"} + plans: list[tuple[str, BaseDataPanel, SignalObj | ImageObj]] = [] + snapshots: dict[str, tuple[BaseDataPanel, SignalObj | ImageObj]] = {} + for out_uuid, (fresh_panel, fresh_obj) in zip(recorded, detached): + output_panel = resolve_output_panel(panel, out_uuid, fresh_obj, fresh_panel) + plans.append((out_uuid, output_panel, fresh_obj)) + if output_panel.objmodel.has_uuid(out_uuid): + snapshots[out_uuid] = ( + output_panel, + copy.deepcopy(output_panel.objmodel[out_uuid]), + ) + sibling_gid = next( ( - u - for u in recorded - if resolve_output_panel(panel, u, None, panel_data).objmodel.has_uuid(u) + output_panel.objmodel.get_object_group_id(output_panel.objmodel[out_uuid]) + for out_uuid, output_panel, _fresh_obj in plans + if output_panel is panel_data and out_uuid in snapshots ), - recorded[0], - ) - output_panel = resolve_output_panel(panel, resolve_uuid, None, panel_data) - if len(recorded) != len(params): - # Legacy or inconsistent recording: outputs cannot be aligned with - # the parameter list, so recreation is impossible. - record_missing_outputs( - panel, - action, - [u for u in recorded if not output_panel.objmodel.has_uuid(u)], - ) - return False - existing = [u for u in recorded if output_panel.objmodel.has_uuid(u)] - pp = ( - extract_processing_parameters(output_panel.objmodel[existing[0]]) - if existing - else None - ) - source_uuid = pp.source_uuid if pp is not None and pp.source_uuid else None - if source_uuid is None: - selection = action.state.selection.get(panel_data.PANEL_STR_ID, []) - source_uuid = selection[0] if selection else None - if source_uuid is None: - return False - if not panel_data.objmodel.has_uuid(source_uuid): - panel.runtime.execution.cascade_warnings.append( - _("Action %s: source object was deleted — skipping.") - % (action.func_name or action.uuid) - ) - return False - source_obj = panel_data.objmodel[source_uuid] - plugin_origin = action.plugin_origin or (pp.plugin_origin if pp else None) - new_objs = panel_data.processor.recompute_1_to_n( - action.func_name, - source_obj, - params, - plugin_origin=plugin_origin, - ) - if not new_objs: - return False - if len(new_objs) != len(recorded) or not all( - isinstance(obj, (SignalObj, ImageObj)) for obj in new_objs - ): - _logger.warning( - "1-to-n cardinality changed for action %s: %d outputs, %d recorded.", - action.uuid, - len(new_objs), - len(recorded), - ) - panel.runtime.execution.cascade_warnings.append( - _("Action %s: recompute returned %d output(s), expected %d.") - % (action.func_name or action.uuid, len(new_objs), len(recorded)) - ) - return False - output_panel = resolve_output_panel(panel, recorded[0], new_objs[0], panel_data) - group_id = ( - panel_data.objmodel.get_object_group_id(source_obj) - if output_panel is panel_data - else None + None, ) - snapshots = { - out_uuid: copy.deepcopy(output_panel.objmodel[out_uuid]) - for out_uuid in existing - if output_panel.objmodel.has_uuid(out_uuid) - } try: - for idx, out_uuid in enumerate(recorded): + for out_uuid, output_panel, fresh_obj in plans: + pparams = extract_processing_parameters(fresh_obj) + existing_pp = ( + extract_processing_parameters(output_panel.objmodel[out_uuid]) + if out_uuid in snapshots + else None + ) + if pparams is not None: + # The freshly registered feature may not carry the plugin + # origin (or a param): fall back to the recorded action, then + # to the metadata stored on the target, as the legacy + # per-pattern engines did. + if pparams.plugin_origin is None: + pparams.plugin_origin = action.plugin_origin or ( + existing_pp.plugin_origin if existing_pp else None + ) + if pparams.param is None and existing_pp is not None: + pparams.param = existing_pp.param + if out_uuid in snapshots and preserve_metadata and pparams is not None: + # Preserve the existing output's own metadata (ROIs, + # annotations, analysis results...) + output_panel.objprop.apply_recomputed_object_in_place( + output_panel.objmodel[out_uuid], fresh_obj, pparams + ) + continue + group_id = None + if output_panel is panel_data and out_uuid not in snapshots: + group_id = sibling_gid or fallback_gid apply_output_in_place_or_recreate( panel, output_panel, action, out_uuid, - new_objs[idx], - ProcessingParameters( - func_name=action.func_name, - pattern="1-to-n", - param=params[idx], - source_uuid=source_uuid, - plugin_origin=plugin_origin, - ), + fresh_obj, + pparams, group_id=group_id, ) - for out_uuid in recorded: + for out_uuid, output_panel, _fresh_obj in plans: refresh_target(output_panel, out_uuid) except Exception: - for out_uuid, snapshot in snapshots.items(): + # Outputs re-created during this failed batch (absent from + # ``snapshots``) must not survive the rollback: detach them. + for out_uuid, output_panel, _fresh_obj in plans: + if out_uuid not in snapshots and output_panel.objmodel.has_uuid(out_uuid): + _detach_object(output_panel, out_uuid) + for out_uuid, (output_panel, snapshot) in snapshots.items(): update_obj_in_place(output_panel.objmodel[out_uuid], snapshot) - for out_uuid in snapshots: + for out_uuid, (output_panel, _snapshot) in snapshots.items(): try: refresh_target(output_panel, out_uuid) - except Exception: + except Exception: # pylint: disable=broad-exception-caught _logger.exception( "Cascade recompute rollback refresh failed for output %s.", out_uuid, ) raise - return True -def recompute_n_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> bool: - """Recompute an n-to-1 action in place. +def recompute_compute_in_place(panel: HistoryPanel, action: HistoryAction) -> bool: + """Replay a compute action through the real UI entry point, then reconcile. - If the output object was deleted, it is re-created under its recorded - UUID; sources are then resolved from the action's captured state. - """ - panel_data = hchain.resolve_panel_for_action(panel, action) - if panel_data is None: - return False - recorded = hchain.recorded_action_output_uuids(panel, action) - if not recorded: - return False - output_uuid = recorded[0] - output_panel = resolve_output_panel(panel, output_uuid, None, panel_data) - output_obj = ( - output_panel.objmodel[output_uuid] - if output_panel.objmodel.has_uuid(output_uuid) - else None - ) - pp = extract_processing_parameters(output_obj) if output_obj is not None else None - source_uuids: list[str] = [] - if pp is not None and pp.source_uuids: - source_uuids = list(pp.source_uuids) - else: - source_uuids = list(action.state.selection.get(panel_data.PANEL_STR_ID, [])) - if not source_uuids or not all( - panel_data.objmodel.has_uuid(uuid) for uuid in source_uuids - ): - panel.runtime.execution.cascade_warnings.append( - _("Action %s: source object(s) were deleted — skipping.") - % (action.func_name or action.uuid) - ) - return False - src_objs = [panel_data.objmodel[uuid] for uuid in source_uuids] - param = action.kwargs.get("param") - plugin_origin = action.plugin_origin or (pp.plugin_origin if pp else None) - new_obj = panel_data.processor.recompute_n_to_1( - action.func_name, - src_objs, - param, - plugin_origin=plugin_origin, - ) - if not isinstance(new_obj, (SignalObj, ImageObj)): - return False - output_panel = resolve_output_panel(panel, output_uuid, new_obj, panel_data) - apply_output_in_place_or_recreate( - panel, - output_panel, - action, - output_uuid, - new_obj, - ProcessingParameters( - func_name=action.func_name, - pattern="n-to-1", - param=param, - source_uuids=[get_uuid(o) for o in src_objs], - plugin_origin=plugin_origin, - ), - group_id=( - panel_data.objmodel.get_object_group_id(src_objs[0]) - if output_panel is panel_data - else None - ), - ) - refresh_target(output_panel, output_uuid) - return True + **Execute**: the recorded selection is restored and the same public + processor method the menus use is invoked with the recorded parameters + (see :func:`execute_compute_via_ui`), under the ``replaying()`` guard so + no new history entry is recorded. + **Reconcile**: the freshly created objects — diffed from both data + panels, in recording order (cross-panel outputs land in the panel + matching their type) — are aligned by index with the recorded output + UUIDs and committed via :func:`_commit_outputs`. The temporary objects + (and any temporary group created by the batch, e.g. pairwise ``dst_gname`` + groups) are then removed so no duplicates remain. -def recompute_2_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> bool: - """Recompute a 2-to-1 action in place (single or pairwise). + If the number of fresh outputs differs from the number of recorded + outputs, the temporary objects are discarded, a warning is queued and the + action is flagged stale. + + Args: + panel: History panel instance. + action: Compute-kind history action to recompute. - Deleted outputs are re-created under their recorded UUIDs; sources are - then resolved from the action's captured inputs (indices of - ``action.output_uuids`` align with the recorded input/operand lists). + Returns: + True when every recorded output was reconciled. """ panel_data = hchain.resolve_panel_for_action(panel, action) if panel_data is None: @@ -705,136 +678,89 @@ def recompute_2_to_1_in_place(panel: HistoryPanel, action: HistoryAction) -> boo recorded = hchain.recorded_action_output_uuids(panel, action) if not recorded: return False - output_panel = resolve_output_panel(panel, recorded[0], None, panel_data) - param = action.kwargs.get("param") + name = action.func_name or action.title or action.uuid + sources = list(action.state.selection.get(panel_data.PANEL_STR_ID, [])) + if not sources: + panel.runtime.execution.cascade_warnings.append( + _("Action %s: no recorded source object — skipping.") % name + ) + return False obj2_uuids = action.kwargs.get("obj2_uuids") or [] if isinstance(obj2_uuids, str): obj2_uuids = [obj2_uuids] - pairwise = bool(action.kwargs.get("pairwise")) - recorded_inputs = list(action.state.selection.get(panel_data.PANEL_STR_ID, [])) - resolved: list[ - tuple[ - str, - SignalObj | ImageObj, - SignalObj | ImageObj, - dict | None, - ] - ] = [] - for idx, out_uuid in enumerate(recorded): - pp = ( - extract_processing_parameters(output_panel.objmodel[out_uuid]) - if output_panel.objmodel.has_uuid(out_uuid) - else None - ) - src_uuids = ( - list(pp.source_uuids) - if pp is not None and pp.source_uuids - else ( - recorded_inputs[idx : idx + 1] + obj2_uuids[idx : idx + 1] - if pairwise - else recorded_inputs[idx : idx + 1] + obj2_uuids[:1] - ) + if action.pattern == "2_to_1" and not obj2_uuids: + panel.runtime.execution.cascade_warnings.append( + _("Action %s: no recorded second operand — skipping.") % name ) - if len(src_uuids) < 2: - panel.runtime.execution.cascade_warnings.append( - _("Action %s: missing source(s) for output #%d — skipping.") - % (action.func_name or action.uuid, idx + 1) - ) - return False - if not ( - panel_data.objmodel.has_uuid(src_uuids[0]) - and panel_data.objmodel.has_uuid(src_uuids[1]) - ): - panel.runtime.execution.cascade_warnings.append( - _("Action %s: source object(s) were deleted — skipping.") - % (action.func_name or action.uuid) - ) - return False - obj1 = panel_data.objmodel[src_uuids[0]] - obj2 = panel_data.objmodel[src_uuids[1]] - plugin_origin = action.plugin_origin or (pp.plugin_origin if pp else None) - resolved.append((out_uuid, obj1, obj2, plugin_origin)) - - paramclass_name = type(param).__name__ if param is not None else None - feature = panel_data.processor.get_feature( - action.func_name, - plugin_origin=resolved[0][3], - paramclass_name=paramclass_name, - ) - preparation = panel_data.processor.prepare_2_to_1_pairs( - [(obj1, obj2) for _out_uuid, obj1, obj2, _origin in resolved], - feature.skip_xarray_compat, - feature.pre_execute_hook, - ) - if preparation is None: return False - prepared_pairs, source_transaction = preparation - staged: list[ - tuple[ - str, - SignalObj | ImageObj, - SignalObj | ImageObj, - SignalObj | ImageObj, - dict | None, - ] - ] = [] - for resolved_item, prepared_pair in zip(resolved, prepared_pairs): - out_uuid, obj1, obj2, plugin_origin = resolved_item - new_obj = panel_data.processor.recompute_2_to_1( - action.func_name, - obj1, - obj2, - param, - plugin_origin=plugin_origin, - prepared_pair=prepared_pair, + required = sources + (obj2_uuids if action.pattern == "2_to_1" else []) + if any(not panel_data.objmodel.has_uuid(uuid) for uuid in required): + panel.runtime.execution.cascade_warnings.append( + _("Action %s: source object(s) were deleted — skipping.") % name ) - if not isinstance(new_obj, (SignalObj, ImageObj)): - return False - staged.append((out_uuid, new_obj, obj1, obj2, plugin_origin)) - output_panel = resolve_output_panel(panel, recorded[0], staged[0][1], panel_data) - snapshots = { - out_uuid: copy.deepcopy(output_panel.objmodel[out_uuid]) - for out_uuid, *_rest in staged - if output_panel.objmodel.has_uuid(out_uuid) + return False + data_panels = (panel.mainwindow.signalpanel, panel.mainwindow.imagepanel) + before_objs = { + p.PANEL_STR_ID: set(p.objmodel.get_object_ids()) for p in data_panels } - try: - for out_uuid, new_obj, obj1, obj2, plugin_origin in staged: - apply_output_in_place_or_recreate( - panel, - output_panel, - action, - out_uuid, - new_obj, - ProcessingParameters( - func_name=action.func_name, - pattern="2-to-1", - param=param, - source_uuids=[get_uuid(obj1), get_uuid(obj2)], - plugin_origin=plugin_origin, - ), - group_id=( - panel_data.objmodel.get_object_group_id(obj1) - if output_panel is panel_data - else None - ), - ) - for out_uuid, *_rest in staged: - refresh_target(output_panel, out_uuid) - if source_transaction is not None: - for _out_uuid, _new_obj, obj1, _obj2, _origin in staged: - source_transaction.commit(obj1) - except Exception: - for out_uuid, snapshot in snapshots.items(): - update_obj_in_place(output_panel.objmodel[out_uuid], snapshot) - for out_uuid in snapshots: + before_grps = { + p.PANEL_STR_ID: {get_uuid(grp) for grp in p.objmodel.get_groups()} + for p in data_panels + } + saved_selection = { + p.PANEL_STR_ID: p.objview.get_sel_object_uuids() + + p.objview.get_sel_group_uuids() + for p in data_panels + } + # ``replaying()`` suppresses history capture and session prompts for the + # whole execute + reconcile scope (temporary insertions included). + with panel.replaying(): + try: + panel_data.objview.select_objects(sources) try: - refresh_target(output_panel, out_uuid) + execute_compute_via_ui(panel_data, action, obj2_uuids) except Exception: - _logger.exception( - "Cascade recompute rollback refresh failed for output %s.", - out_uuid, + # A compute failing mid-batch may already have inserted some + # fresh temporaries: detach them so no duplicates remain. + for p in data_panels: + for uid in list(p.objmodel.get_object_ids()): + if uid not in before_objs[p.PANEL_STR_ID]: + _detach_object(p, uid) + _discard_new_empty_groups(data_panels, before_grps) + raise + fresh = [ + (p, uid) + for p in data_panels + for uid in p.objmodel.get_object_ids() + if uid not in before_objs[p.PANEL_STR_ID] + ] + if len(fresh) != len(recorded): + for fresh_panel, fresh_uuid in fresh: + _detach_object(fresh_panel, fresh_uuid) + _discard_new_empty_groups(data_panels, before_grps) + action.is_stale = True + _logger.warning( + "Cascade recompute: cardinality changed for action %s: " + "%d output(s), %d recorded.", + action.uuid, + len(fresh), + len(recorded), ) - raise + panel.runtime.execution.cascade_warnings.append( + _("Action %s: recompute returned %d output(s), expected %d.") + % (name, len(fresh), len(recorded)) + ) + return False + # Detach the fresh objects: they are temporary carriers whose + # content is committed onto the recorded outputs below. + detached = [ + (fresh_panel, _detach_object(fresh_panel, fresh_uuid)) + for fresh_panel, fresh_uuid in fresh + ] + _discard_new_empty_groups(data_panels, before_grps) + _commit_outputs(panel, panel_data, action, recorded, detached) + finally: + _restore_selection(data_panels, saved_selection) return True diff --git a/datalab/gui/processor/base.py b/datalab/gui/processor/base.py index 69dfcfc4a..238056391 100644 --- a/datalab/gui/processor/base.py +++ b/datalab/gui/processor/base.py @@ -913,7 +913,11 @@ def _check_signal_xarray_compatibility( behavior = Conf.proc.xarray_compat_behavior.get("ask") yes_to_all_selected = False - if behavior == "ask" and not env.execenv.unattended: + # History replay must be non-interactive and deterministic: treat + # "ask" as automatic interpolation while replaying. + hpanel = getattr(self.mainwindow, "historypanel", None) + replaying = hpanel is not None and hpanel.is_replaying() + if behavior == "ask" and not env.execenv.unattended and not replaying: # Create custom message box with "Yes to All" option msg_box = QW.QMessageBox(self.mainwindow) msg_box.setWindowTitle(_("X-array incompatibility")) @@ -1529,112 +1533,6 @@ def recompute_1_to_1( comp_out.result = new_obj return comp_out - # ------------------------------------------------------------------ - # In-place recompute helpers used by the History panel cascade - # (Edit mode tweaks + downstream propagation). They mirror their - # ``compute_*`` counterparts but: - # - never add results to a panel (caller updates targets in place); - # - never record a history entry (cascade runs under ``replaying``); - # - never insert :class:`ProcessingParameters` (caller does, so that - # ``source_uuid`` / ``source_uuids`` stay consistent with the - # existing output object identity). - # ------------------------------------------------------------------ - - def recompute_1_to_n( - self, - func_name: str, - obj: SignalObj | ImageObj, - params: list[gds.DataSet], - plugin_origin: dict[str, Any] | None = None, - ) -> list[SignalObj | ImageObj] | None: - """Recompute a 1-to-n processing operation without adding results to panel. - - Args: - func_name: Name of the processing function. - obj: Source object to process. - params: List of N parameter datasets (one per output). - plugin_origin: Optional plugin origin descriptor. - - Returns: - List of N new objects (in input order), or ``None`` if cancelled - or an unrecoverable error occurred. Shorter lists are possible - when individual sub-calls return ``None``. - """ - paramclass_name = ( - type(params[0]).__name__ if params and params[0] is not None else None - ) - feature = self.get_feature( - func_name, - plugin_origin=plugin_origin, - paramclass_name=paramclass_name, - ) - func = feature.function - results: list[SignalObj | ImageObj] = [] - with create_progress_bar( - self.panel, _("Recomputing..."), max_=len(params) - ) as progress: - for idx, param in enumerate(params): - progress.setValue(idx) - progress.setLabelText(_("Processing object with updated parameters...")) - args = (obj, param) if param is not None else (obj,) - comp_out = self.__exec_func(func, args, progress) - if comp_out is None: - return None - new_obj = self.handle_output(comp_out, _("Recomputing"), progress) - if new_obj is None: - continue - if isinstance(new_obj, (SignalObj, ImageObj)): - self._handle_keep_results(new_obj) - patch_title_with_ids(new_obj, [obj], get_short_id) - results.append(new_obj) - return results - - def recompute_n_to_1( - self, - func_name: str, - objs: list[SignalObj | ImageObj], - param: gds.DataSet | None = None, - plugin_origin: dict[str, Any] | None = None, - ) -> SignalObj | ImageObj | None: - """Recompute an n-to-1 processing operation without adding result to panel. - - Args: - func_name: Name of the processing function. - objs: Source object list to aggregate. - param: Processing parameters (optional). - plugin_origin: Optional plugin origin descriptor. - - Returns: - New aggregated object, or ``None`` if cancelled / errored. - - .. note:: - Pairwise mode is not handled here: each pairwise output is a - distinct single-output recompute -- the caller is expected to - split the work per output and iterate. - """ - paramclass_name = type(param).__name__ if param is not None else None - feature = self.get_feature( - func_name, - plugin_origin=plugin_origin, - paramclass_name=paramclass_name, - ) - func = feature.function - with create_progress_bar(self.panel, _("Recomputing..."), max_=1) as progress: - progress.setValue(0) - progress.setLabelText(_("Processing object with updated parameters...")) - args = (objs, param) if param is not None else (objs,) - comp_out = self.__exec_func(func, args, progress) - if comp_out is None: - return None - new_obj = self.handle_output(comp_out, _("Recomputing"), progress) - if new_obj is None: - return None - if isinstance(new_obj, (SignalObj, ImageObj)): - self._handle_keep_results(new_obj) - self._merge_geometry_results_for_n_to_1(new_obj, objs) - patch_title_with_ids(new_obj, objs, get_short_id) - return new_obj - def prepare_2_to_1_pairs( self, object_pairs: list[tuple[TypeObj, TypeObj]], @@ -1704,69 +1602,6 @@ def prepare_2_to_1_pairs( ] return prepared_pairs, source_transaction - def recompute_2_to_1( - self, - func_name: str, - obj1: SignalObj | ImageObj, - obj2: SignalObj | ImageObj, - param: gds.DataSet | None = None, - plugin_origin: dict[str, Any] | None = None, - prepared_pair: tuple[SignalObj | ImageObj, SignalObj | ImageObj] | None = None, - ) -> SignalObj | ImageObj | None: - """Recompute a 2-to-1 processing operation without adding result to panel. - - Args: - func_name: Name of the processing function. - obj1: First source object. - obj2: Second source object. - param: Processing parameters (optional). - plugin_origin: Optional plugin origin descriptor. - prepared_pair: Optional effective pair prepared by a batch caller. - - Returns: - New combined object, or ``None`` if cancelled / errored. - """ - paramclass_name = type(param).__name__ if param is not None else None - feature = self.get_feature( - func_name, - plugin_origin=plugin_origin, - paramclass_name=paramclass_name, - ) - func = feature.function - source_transaction = None - if prepared_pair is None: - preparation = self.prepare_2_to_1_pairs( - [(obj1, obj2)], - feature.skip_xarray_compat, - feature.pre_execute_hook, - ) - if preparation is None: - return None - prepared_pairs, source_transaction = preparation - actual_obj1, actual_obj2 = prepared_pairs[0] - else: - actual_obj1, actual_obj2 = prepared_pair - with create_progress_bar(self.panel, _("Recomputing..."), max_=1) as progress: - progress.setValue(0) - progress.setLabelText(_("Processing object with updated parameters...")) - args = ( - (actual_obj1, actual_obj2, param) - if param is not None - else (actual_obj1, actual_obj2) - ) - comp_out = self.__exec_func(func, args, progress) - if comp_out is None: - return None - new_obj = self.handle_output(comp_out, _("Recomputing"), progress) - if new_obj is None: - return None - if isinstance(new_obj, (SignalObj, ImageObj)): - self._handle_keep_results(new_obj) - patch_title_with_ids(new_obj, [obj1, obj2], get_short_id) - if source_transaction is not None: - source_transaction.commit(obj1) - return new_obj - def recompute_1_to_0( self, func_name: str, diff --git a/datalab/history/action.py b/datalab/history/action.py index b2de67956..ba7c1035f 100644 --- a/datalab/history/action.py +++ b/datalab/history/action.py @@ -343,6 +343,11 @@ def title(self) -> str: """Return object title""" return self.__title + @title.setter + def title(self, value: str) -> None: + """Set object title""" + self.__title = value or "" + # ------------------------------------------------------------------ # Description rendering (used by the tree view) # ------------------------------------------------------------------ diff --git a/datalab/locale/fr/LC_MESSAGES/datalab.po b/datalab/locale/fr/LC_MESSAGES/datalab.po index d03abd1e2..8c978ed77 100644 --- a/datalab/locale/fr/LC_MESSAGES/datalab.po +++ b/datalab/locale/fr/LC_MESSAGES/datalab.po @@ -4271,10 +4271,6 @@ msgstr "Panneau d'historique" msgid "History files" msgstr "Fichiers d'historique" -#, python-format -msgid "Action %s has been edited but its target output object(s) no longer exist — skipping." -msgstr "L'action %s a été modifiée mais son ou ses objets de sortie cibles n'existent plus — ignorée." - #, python-format msgid "Action %s: target panel not found — skipping." msgstr "Action %s : panneau cible introuvable — ignorée." @@ -4326,20 +4322,20 @@ msgid "Action %s: creation parameters could not be prepared — skipping." msgstr "Action %s : les paramètres de création n'ont pas pu être préparés — ignorée." #, python-format -msgid "Action %s: source object was deleted — skipping." -msgstr "Action %s : l'objet source a été supprimé — ignorée." +msgid "Action %s: no recorded source object — skipping." +msgstr "Action %s : aucun objet source enregistré — ignorée." #, python-format -msgid "Action %s: recompute returned %d output(s), expected %d." -msgstr "Action %s : le recalcul a renvoyé %d sortie(s), %d attendue(s)." +msgid "Action %s: no recorded second operand — skipping." +msgstr "Action %s : aucun second opérande enregistré — ignorée." #, python-format msgid "Action %s: source object(s) were deleted — skipping." msgstr "Action %s : le ou les objets source ont été supprimés — ignorée." #, python-format -msgid "Action %s: missing source(s) for output #%d — skipping." -msgstr "Action %s : source(s) manquante(s) pour la sortie n°%d — ignorée." +msgid "Action %s: recompute returned %d output(s), expected %d." +msgstr "Action %s : le recalcul a renvoyé %d sortie(s), %d attendue(s)." #, python-format msgid "Action %s: %d analysed object(s) were deleted — skipping." diff --git a/datalab/tests/features/common/history_model_unit_test.py b/datalab/tests/features/common/history_model_unit_test.py index c95a7cced..6cb3de4f8 100644 --- a/datalab/tests/features/common/history_model_unit_test.py +++ b/datalab/tests/features/common/history_model_unit_test.py @@ -1018,7 +1018,7 @@ def test_recompute_dispatch_guards_and_missing_feature() -> None: plugin_origin={"directory": "myplugin"}, paramclass_name="MyParam", ) - with patch.object(hrec, "recompute_1_to_1_in_place", side_effect=error): + with patch.object(hrec, "recompute_compute_in_place", side_effect=error): assert hrec.recompute_action_in_place(panel, action) is False assert action.is_stale is True assert any( diff --git a/datalab/tests/features/common/history_replay_fixes_test.py b/datalab/tests/features/common/history_replay_fixes_test.py index 675223a6f..7fb2a309e 100644 --- a/datalab/tests/features/common/history_replay_fixes_test.py +++ b/datalab/tests/features/common/history_replay_fixes_test.py @@ -15,11 +15,13 @@ import numpy as np import sigima.params import sigima.proc.signal as sips -from sigima.tests.data import create_sincos_image +from sigima.tests.data import create_paracetamol_signal, create_sincos_image +from datalab.config import _ from datalab.env import execenv from datalab.gui.panel.history import interactive_replay as hireplay from datalab.gui.panel.history import recompute as hrec +from datalab.objectmodel import get_uuid from datalab.tests import datalab_test_app_context from datalab.tests.features.common.history_test_helpers import add_paracetamol_signals @@ -89,6 +91,34 @@ def test_replay_recreates_deleted_cross_panel_output_in_destination_panel() -> N assert np.array_equal(recreated.xydata, expected_data) +def test_failed_compute_replay_leaves_no_temporary_objects() -> None: + """Detach fresh temporaries when a compute raises mid-batch on replay.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + add_paracetamol_signals(panel, 2) + panel.objview.select_objects([1, 2]) + panel.processor.run_feature( + sips.normalize, sigima.params.NormalizeParam.create() + ) + action = history[len(history)] + object_count = len(panel.objmodel) + original_execute = hrec.execute_compute_via_ui + + def failing_execute(panel_data, act, obj2_uuids) -> None: + """Insert the whole batch of fresh outputs, then fail: simulates + a compute raising after some objects were already created.""" + original_execute(panel_data, act, obj2_uuids) + raise RuntimeError("simulated mid-batch failure") + + with patch.object(hrec, "execute_compute_via_ui", failing_execute): + assert hrec.recompute_action_in_place(history, action) is False + + assert action.is_stale is True + assert len(panel.objmodel) == object_count + history.runtime.execution.cascade_warnings.clear() + + def build_synthetic_head_chain(win) -> list: """Record a creation + two computes, then clear the head kwargs. @@ -297,3 +327,231 @@ def test_replay_load_skipped_when_outputs_still_exist(tmp_path) -> None: assert len(panel.objmodel.get_groups()) == group_count assert action.output_uuids == output_uuids_before assert action.is_stale is False + + +def test_replay_load_legacy_add_objects_false_self_heals(tmp_path) -> None: + """Self-heal legacy load entries recorded with ``add_objects=False``.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + populate_signal_directory(win, tmp_path, {"": ["s1.csv", "s2.csv"]}) + history.toggle_record_mode(True) + fnames = [str(tmp_path / "s1.csv"), str(tmp_path / "s2.csv")] + objs = panel.load_from_files(fnames) + assert len(objs) == 2 + action = history[len(history)] + assert action.method_name == "load_from_files" + # Simulate a legacy entry recorded by the old ``load_from_directory`` + action.kwargs["add_objects"] = False + # Delete every loaded object + history.toggle_record_mode(False) + panel.objview.select_objects(panel.objmodel.get_object_ids()) + panel.remove_object(force=True) + assert len(panel.objmodel) == 0 + history.toggle_record_mode(True) + + hireplay.replay_actions(history, [action], prompt=False) + + assert len(panel.objmodel) == 2 + assert action.is_stale is False + assert action.kwargs["add_objects"] is True + assert all( + panel.objmodel.has_uuid(output_uuid) for output_uuid in action.output_uuids + ) + + +def write_unreadable_files(directory, names: list[str]) -> list[str]: + """Write files that no signal reader can load into ``directory``. + + Args: + directory: Base directory (``pathlib.Path``) + names: File names to create + + Returns: + Full paths of the created files + """ + fnames = [] + for name in names: + path = directory / name + path.write_bytes(b"\x89PNG\r\n\x1a\nnot actually loadable") + fnames.append(str(path)) + return fnames + + +def test_load_from_files_without_loadable_file_records_no_entry(tmp_path) -> None: + """Discard the load entry when no file produced any object.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + fnames = write_unreadable_files(tmp_path, ["i1.png", "i2.png"]) + objs = panel.load_from_files(fnames, ignore_errors=True) + assert objs == [] + assert len(history) == 0 + + +def test_load_from_directory_without_loadable_file_records_no_entry(tmp_path) -> None: + """Discard the directory-load entry when nothing could be loaded.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + write_unreadable_files(tmp_path, ["i1.png", "i2.png"]) + objs = panel.load_from_directory(str(tmp_path)) + assert objs == [] + assert len(history) == 0 + + +def test_load_from_files_partial_failure_updates_entry(tmp_path) -> None: + """Reflect the actually loaded files in the recorded load entry.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + populate_signal_directory(win, tmp_path, {"": ["s1.csv", "s2.csv"]}) + bad = write_unreadable_files(tmp_path, ["i1.png", "i2.png"]) + good = [str(tmp_path / "s1.csv"), str(tmp_path / "s2.csv")] + history.toggle_record_mode(True) + objs = panel.load_from_files(sorted(good + bad), ignore_errors=True) + assert len(objs) == 2 + assert len(history) == 1 + action = history[len(history)] + assert action.method_name == "load_from_files" + assert action.title == _("Load from %d files") % 2 + assert action.kwargs["filenames"] == sorted(good) + assert len(action.output_uuids) == 2 + + +def test_load_from_files_single_success_updates_entry(tmp_path) -> None: + """Use the single-file title when only one file could be loaded.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + populate_signal_directory(win, tmp_path, {"": ["s1.csv"]}) + bad = write_unreadable_files(tmp_path, ["i1.png"]) + good = str(tmp_path / "s1.csv") + history.toggle_record_mode(True) + objs = panel.load_from_files(sorted([good] + bad), ignore_errors=True) + assert len(objs) == 1 + assert len(history) == 1 + action = history[len(history)] + assert action.title == _('Load "%s"') % "s1.csv" + assert action.kwargs["filenames"] == [good] + + +def record_group_gaussian_filter(win) -> tuple: + """Record a 1-to-1 compute applied to a whole image group. + + Args: + win: DataLab main window with history recording enabled + + Returns: + Recorded compute action and the list of source image UUIDs + """ + history, panel = win.historypanel, win.imagepanel + for _index in range(3): + panel.add_object(create_sincos_image()) + source_uuids = panel.objmodel.get_object_ids()[-3:] + group = panel.objmodel.get_group_from_object(panel.objmodel[source_uuids[0]]) + panel.objview.select_groups([get_uuid(group)]) + panel.processor.run_feature( + "gaussian_filter", sigima.params.GaussianParam.create(sigma=2.0) + ) + action = history[len(history)] + assert action.pattern == "1_to_1" + assert len(action.output_uuids) == 3 + return action, source_uuids + + +def test_replay_recreates_single_deleted_1_to_1_output() -> None: + """Re-create one deleted output of a group-wide 1-to-1 compute.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.imagepanel + history.toggle_record_mode(True) + action, _source_uuids = record_group_gaussian_filter(win) + recorded = list(action.output_uuids) + deleted_uuid = recorded[1] + survivors = [uuid for uuid in recorded if uuid != deleted_uuid] + survivor_group_id = panel.objmodel.get_object_group_id( + panel.objmodel[survivors[0]] + ) + expected_data = panel.objmodel[deleted_uuid].data.copy() + object_count = len(panel.objmodel) + survivor_identities = {uuid: id(panel.objmodel[uuid]) for uuid in survivors} + panel.objview.select_objects([deleted_uuid]) + panel.remove_object(force=True) + assert not panel.objmodel.has_uuid(deleted_uuid) + + with patch.object(hrec, "flush_cascade_warnings"): + hireplay.replay_actions(history, [action], prompt=False) + + assert history.runtime.execution.cascade_warnings == [] + assert action.is_stale is False + assert len(panel.objmodel) == object_count + assert action.output_uuids == recorded + # The deleted output is re-created under its recorded UUID, next to + # its surviving siblings + assert panel.objmodel.has_uuid(deleted_uuid) + recreated = panel.objmodel[deleted_uuid] + assert np.array_equal(recreated.data, expected_data) + assert panel.objmodel.get_object_group_id(recreated) == survivor_group_id + # Surviving outputs are updated in place (identity preserved) + for uuid in survivors: + assert id(panel.objmodel[uuid]) == survivor_identities[uuid] + + +def test_replay_recreates_all_deleted_1_to_1_outputs() -> None: + """Re-create every deleted output of a group-wide 1-to-1 compute.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.imagepanel + history.toggle_record_mode(True) + action, source_uuids = record_group_gaussian_filter(win) + recorded = list(action.output_uuids) + expected_data = [panel.objmodel[uuid].data.copy() for uuid in recorded] + object_count = len(panel.objmodel) + panel.objview.select_objects(recorded) + panel.remove_object(force=True) + assert all(not panel.objmodel.has_uuid(uuid) for uuid in recorded) + + with patch.object(hrec, "flush_cascade_warnings"): + hireplay.replay_actions(history, [action], prompt=False) + + assert history.runtime.execution.cascade_warnings == [] + assert action.is_stale is False + assert len(panel.objmodel) == object_count + assert action.output_uuids == recorded + for uuid, data in zip(recorded, expected_data): + assert panel.objmodel.has_uuid(uuid) + assert np.array_equal(panel.objmodel[uuid].data, data) + # Sources are untouched + assert all(panel.objmodel.has_uuid(uuid) for uuid in source_uuids) + + +def test_replay_recreates_deleted_pairwise_n_to_1_output() -> None: + """Re-create a deleted output of a pairwise n-to-1 compute.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + group_a = panel.add_group("group_a") + group_b = panel.add_group("group_b") + for group in (group_a, group_b): + for _index in range(2): + panel.add_object(create_paracetamol_signal(), group_id=get_uuid(group)) + panel.objview.select_groups([get_uuid(group_a), get_uuid(group_b)]) + feature = panel.processor.get_feature("average") + panel.processor.compute_n_to_1(feature.function, edit=False, pairwise=True) + action = history[len(history)] + assert action.pattern == "n_to_1" + assert action.kwargs.get("pairwise") is True + recorded = list(action.output_uuids) + assert len(recorded) == 2 + deleted_uuid = recorded[0] + expected_data = panel.objmodel[deleted_uuid].xydata.copy() + object_count = len(panel.objmodel) + panel.objview.select_objects([deleted_uuid]) + panel.remove_object(force=True) + assert not panel.objmodel.has_uuid(deleted_uuid) + + with patch.object(hrec, "flush_cascade_warnings"): + hireplay.replay_actions(history, [action], prompt=False) + + assert history.runtime.execution.cascade_warnings == [] + assert action.is_stale is False + assert len(panel.objmodel) == object_count + assert action.output_uuids == recorded + assert panel.objmodel.has_uuid(deleted_uuid) + assert np.array_equal(panel.objmodel[deleted_uuid].xydata, expected_data) diff --git a/datalab/tests/features/common/history_workflow_test.py b/datalab/tests/features/common/history_workflow_test.py index 0a3e49dc6..f45f4a051 100644 --- a/datalab/tests/features/common/history_workflow_test.py +++ b/datalab/tests/features/common/history_workflow_test.py @@ -14,7 +14,7 @@ import pytest import sigima.params import sigima.proc.signal as sips -from sigima.objects import Gauss2DParam, ImageObj, create_signal_roi +from sigima.objects import Gauss2DParam, create_signal_roi from sigima.tests.data import ( create_paracetamol_signal, create_peak_image, @@ -39,16 +39,12 @@ extract_processing_parameters, insert_processing_parameters, ) -from datalab.gui.processor.catcher import CompOut from datalab.h5.native import NativeH5Reader, NativeH5Writer from datalab.history.core import numpy_to_json_safe from datalab.history.effects import AnalysisEffects -from datalab.history.session import HistorySession -from datalab.history.workspace_state import WorkspaceState -from datalab.objectmodel import get_uuid, set_uuid +from datalab.objectmodel import get_uuid from datalab.tests import datalab_test_app_context from datalab.tests.features.common.history_test_helpers import ( - CascadeObjectModel, add_paracetamol_signals, build_signal_chain, get_tree_item, @@ -403,21 +399,21 @@ def test_edit_cascade_stops_after_failed_descendant() -> None: panel.processor.run_feature(sips.stats) analysis_action = history[len(history)] first_action.is_stale = True - original_recompute = panel.processor.recompute_1_to_1 + original_compute = panel.processor.compute_1_to_1 call_count = 0 - def fail_second_recompute(*args, **kwargs): + def fail_second_compute(*args, **kwargs): nonlocal call_count call_count += 1 if call_count == 2: - return CompOut(error_msg="expected cascade failure") - return original_recompute(*args, **kwargs) + return None # No output produced: the replay reconcile fails + return original_compute(*args, **kwargs) with ( patch.object( panel.processor, - "recompute_1_to_1", - side_effect=fail_second_recompute, + "compute_1_to_1", + side_effect=fail_second_compute, ), patch.object(panel.processor, "recompute_1_to_0") as recompute_analysis, ): @@ -776,7 +772,7 @@ def test_legacy_resultdata_defaults_execution_success() -> None: def test_2_to_1_failure_does_not_partially_mutate_outputs() -> None: - """Stage every pairwise result before mutating existing outputs.""" + """Discard fresh outputs and warn on a replay cardinality mismatch.""" with datalab_test_app_context(history=True) as win: history, panel = win.historypanel, win.signalpanel history.toggle_record_mode(True) @@ -795,81 +791,56 @@ def test_2_to_1_failure_does_not_partially_mutate_outputs() -> None: ) outputs = [panel.objmodel[uuid] for uuid in action.output_uuids] original_data = [obj.xydata.copy() for obj in outputs] - staged_result = outputs[0].copy() - staged_result.xydata = staged_result.xydata * 0.0 + object_count = len(panel.objmodel) - with patch.object( - panel.processor, - "recompute_2_to_1", - side_effect=[staged_result, None], - ): - success = hrec.recompute_action_in_place(history, action) + # The synthetic action records two outputs but its captured selection + # only produces one: the replay must discard the fresh output and + # leave the recorded outputs untouched + success = hrec.recompute_action_in_place(history, action) assert success is False + assert action.is_stale is True + assert len(panel.objmodel) == object_count + assert any( + "expected 2" in warning + for warning in history.runtime.execution.cascade_warnings + ) + history.runtime.execution.cascade_warnings.clear() for output, data in zip(outputs, original_data): assert np.array_equal(output.xydata, data) def test_2_to_1_refresh_failure_rolls_back_and_resyncs_outputs() -> None: - """Refresh only after commit and resync every target after rollback.""" + """Commit all 2-to-1 outputs before refresh and fully roll back on failure.""" with datalab_test_app_context(history=True) as win: history, panel = win.historypanel, win.signalpanel history.toggle_record_mode(True) - add_paracetamol_signals(panel, 4) - actions = [] - for first, second in ((1, 2), (3, 4)): - panel.objview.select_objects([first]) - panel.processor.run_feature( - sips.difference, panel.objmodel.get_object_from_number(second) - ) - actions.append(history[len(history)]) - action = actions[0] - action.output_uuids.extend(actions[1].output_uuids) - history.runtime.objects.action_output_uuids[action.uuid] = list( - action.output_uuids + add_paracetamol_signals(panel, 3) + panel.objview.select_objects([1, 2]) + panel.processor.run_feature( + sips.difference, panel.objmodel.get_object_from_number(3) ) + action = history[len(history)] + assert len(action.output_uuids) == 2 outputs = [panel.objmodel[uuid] for uuid in action.output_uuids] identities = [id(obj) for obj in outputs] - original_titles = [obj.title for obj in outputs] - original_data = [obj.xydata.copy() for obj in outputs] - original_metadata = [obj.metadata.copy() for obj in outputs] - original_sources = [ - extract_processing_parameters(obj).source_uuids for obj in outputs - ] - staged_results = [obj.copy() for obj in outputs] - staged_titles = [] - for index, result in enumerate(staged_results): - result.title = f"staged-{index}" - staged_titles.append(result.title) - result.xydata = result.xydata * 0.0 + # Mutate the outputs so a successful commit is distinguishable from a + # rollback restoring the pre-replay state + original_titles = [] + original_data = [] + for index, output in enumerate(outputs): + output.title = f"mutated-{index}" + output.xydata = output.xydata * 0.0 + original_titles.append(output.title) + original_data.append(output.xydata.copy()) refresh_effects = [] def refresh_with_failure(_panel, output_uuid): - refresh_effects.append( - ( - output_uuid, - [obj.title for obj in outputs], - [ - extract_processing_parameters(obj).source_uuids - for obj in outputs - ], - ) - ) - if len(refresh_effects) in (2, 3): + refresh_effects.append((output_uuid, [obj.title for obj in outputs])) + if len(refresh_effects) == 2: raise RuntimeError(f"refresh failed #{len(refresh_effects)}") - with ( - patch.object( - panel.processor, - "recompute_2_to_1", - side_effect=staged_results, - ), - patch.object( - hrec, - "refresh_target", - side_effect=refresh_with_failure, - ), - ): + with patch.object(hrec, "refresh_target", side_effect=refresh_with_failure): success = hrec.recompute_action_in_place(history, action) assert success is False @@ -879,14 +850,18 @@ def refresh_with_failure(_panel, output_uuid): action.output_uuids[0], action.output_uuids[1], ] - assert refresh_effects[0][1] == staged_titles - assert refresh_effects[0][2] == original_sources + # Both outputs were committed before the first refresh... + assert all( + title != original + for title, original in zip(refresh_effects[0][1], original_titles) + ) + # ...and both were restored before the rollback refreshes assert refresh_effects[2][1] == original_titles for index, output in enumerate(outputs): assert id(output) == identities[index] assert output.title == original_titles[index] assert np.array_equal(output.xydata, original_data[index]) - assert output.metadata == original_metadata[index] + history.runtime.execution.cascade_warnings.clear() def test_1_to_n_refresh_failure_rolls_back_and_resyncs_outputs() -> None: @@ -895,49 +870,35 @@ def test_1_to_n_refresh_failure_rolls_back_and_resyncs_outputs() -> None: history, panel = win.historypanel, win.signalpanel history.toggle_record_mode(True) source_uuid = add_paracetamol_signals(panel, 1)[0] - actions = [] - for _index in range(2): - panel.objview.select_objects([source_uuid]) - panel.processor.run_feature(sips.derivative) - actions.append(history[len(history)]) - action = actions[0] - action.pattern = "1_to_n" - action.kwargs = { - "params": [ - sigima.params.GaussianParam.create(sigma=1.5), - sigima.params.GaussianParam.create(sigma=2.5), - ] - } - action.output_uuids.extend(actions[1].output_uuids) - history.runtime.objects.action_output_uuids[action.uuid] = list( - action.output_uuids - ) + panel.objview.select_objects([source_uuid]) + feature = panel.processor.get_feature("gaussian_filter") + params = [ + sigima.params.GaussianParam.create(sigma=1.5), + sigima.params.GaussianParam.create(sigma=2.5), + ] + panel.processor.compute_1_to_n(feature.function, params=params, edit=False) + action = history[len(history)] + assert action.pattern == "1_to_n" + assert len(action.output_uuids) == 2 outputs = [panel.objmodel[uuid] for uuid in action.output_uuids] identities = [id(obj) for obj in outputs] - original_titles = [obj.title for obj in outputs] - original_data = [obj.xydata.copy() for obj in outputs] - original_metadata = [obj.metadata.copy() for obj in outputs] - staged_results = [obj.copy() for obj in outputs] - staged_titles = [] - for index, result in enumerate(staged_results): - result.title = f"staged-{index}" - staged_titles.append(result.title) - result.xydata = result.xydata * 0.0 + # Mutate the outputs so a successful commit is distinguishable from a + # rollback restoring the pre-replay state + original_titles = [] + original_data = [] + for index, output in enumerate(outputs): + output.title = f"mutated-{index}" + output.xydata = output.xydata * 0.0 + original_titles.append(output.title) + original_data.append(output.xydata.copy()) refresh_effects = [] def refresh_with_failure(_panel, output_uuid): refresh_effects.append((output_uuid, [obj.title for obj in outputs])) - if len(refresh_effects) in (2, 3): + if len(refresh_effects) == 2: raise RuntimeError(f"refresh failed #{len(refresh_effects)}") - with ( - patch.object( - panel.processor, - "recompute_1_to_n", - return_value=staged_results, - ), - patch.object(hrec, "refresh_target", side_effect=refresh_with_failure), - ): + with patch.object(hrec, "refresh_target", side_effect=refresh_with_failure): success = hrec.recompute_action_in_place(history, action) assert success is False @@ -947,24 +908,26 @@ def refresh_with_failure(_panel, output_uuid): action.output_uuids[0], action.output_uuids[1], ] - assert refresh_effects[0][1] == staged_titles + assert all( + title != original + for title, original in zip(refresh_effects[0][1], original_titles) + ) assert refresh_effects[2][1] == original_titles for index, output in enumerate(outputs): assert id(output) == identities[index] assert output.title == original_titles[index] assert np.array_equal(output.xydata, original_data[index]) - assert output.metadata == original_metadata[index] - - # Legacy misaligned recording: with a deleted output and a params list - # that cannot be aligned with the recorded outputs, the recompute is - # rejected with a missing-outputs warning history.runtime.execution.cascade_warnings.clear() - panel.objview.select_objects([action.output_uuids[1]]) - panel.remove_object(force=True) + + # Misaligned recording: with a params list longer than the recorded + # outputs, the replay produces more objects than expected and the + # cardinality guard rejects the recompute action.kwargs["params"].append(sigima.params.GaussianParam.create(sigma=3.5)) + object_count = len(panel.objmodel) assert hrec.recompute_action_in_place(history, action) is False + assert len(panel.objmodel) == object_count assert any( - "no longer exist" in warning + "expected 2" in warning for warning in history.runtime.execution.cascade_warnings ) history.runtime.execution.cascade_warnings.clear() @@ -1226,7 +1189,7 @@ def test_replay_survives_unexpected_recompute_exception() -> None: pattern=None, ) history.history_sessions[-1].add_action(patternless) - original = hrec.recompute_1_to_1_in_place + original = hrec.recompute_compute_in_place def flaky(panel_, action_): if action_ is acts[1]: @@ -1235,7 +1198,7 @@ def flaky(panel_, action_): with ( patch.object(hireplay, "prompt_edit_action_params", return_value=True), - patch.object(hrec, "recompute_1_to_1_in_place", flaky), + patch.object(hrec, "recompute_compute_in_place", flaky), patch.object(hrec, "flush_cascade_warnings") as flush, ): hireplay.replay_actions(history, [*acts, patternless], prompt=True) @@ -1453,144 +1416,59 @@ def test_edited_image_creation_recomputes_downstream_in_place() -> None: sigma=3.5, a=80.0, ) - source = create_image_from_param(initial_param) - source_uuid = get_uuid(source) - source_identity = id(source) - initial_source_data = source.data.copy() expected_source = create_image_from_param(edited_param) + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.imagepanel + history.toggle_record_mode(True) + source = create_image_from_param(initial_param) + source_uuid = get_uuid(source) + panel.add_object(source) + source = panel.objmodel[source_uuid] + source_identity = id(source) + initial_source_data = source.data.copy() + # Synthetic creation action carrying the edited parameters (the + # recorded output is the pre-existing source object) + creation_action = HistoryAction( + title="Create edited Gaussian", + kind=HistoryAction.KIND_UI, + target="imagepanel", + method_name="new_object", + kwargs={"param": edited_param}, + ) + creation_action.output_uuids = [source_uuid] + # Record the real downstream compute through the UI path + panel.objview.select_objects([source_uuid]) + panel.processor.run_feature( + "gaussian_filter", sigima.params.GaussianParam.create(sigma=2.0) + ) + downstream_action = history[len(history)] + downstream_uuid = downstream_action.output_uuids[0] + downstream = panel.objmodel[downstream_uuid] + downstream_identity = id(downstream) + initial_downstream_data = downstream.data.copy() - downstream = source.copy() - set_uuid(downstream) - downstream.title = "Initial downstream" - downstream.data = np.full(source.data.shape, -1.0) - downstream_uuid = get_uuid(downstream) - downstream_identity = id(downstream) - initial_downstream_data = downstream.data.copy() - insert_processing_parameters( - downstream, - ProcessingParameters( - func_name="unit_transform", - pattern="1-to-1", - source_uuid=source_uuid, - ), - ) - - creation_action = HistoryAction( - title="Create edited Gaussian", - kind=HistoryAction.KIND_UI, - target="imagepanel", - method_name="new_object", - kwargs={"param": edited_param}, - ) - creation_action.output_uuids = [source_uuid] - downstream_state = WorkspaceState() - downstream_state.selection = {"image": [source_uuid]} - downstream_action = HistoryAction( - title="Transform edited Gaussian", - kind=HistoryAction.KIND_COMPUTE, - panel_str="image", - func_name="unit_transform", - pattern="1_to_1", - state=downstream_state, - ) - downstream_action.output_uuids = [downstream_uuid] - session = HistorySession(number=1) - session.add_action(creation_action) - session.add_action(downstream_action) - - processor_source_objects: list[ImageObj] = [] - processor_source_data: list[np.ndarray] = [] - - def recompute_1_to_1( - func_name: str | None, - source_obj: ImageObj, - param: object, - *, - plugin_origin: dict[str, object] | None, - ) -> SimpleNamespace: - assert func_name == "unit_transform" - assert param is None - assert plugin_origin is None - processor_source_objects.append(source_obj) - processor_source_data.append(source_obj.data.copy()) - new_obj = source_obj.copy() - new_obj.title = f"unit_transform({source_obj.title})" - new_obj.data = source_obj.data.astype(float) * 2.0 + 3.0 - return SimpleNamespace(cancelled=False, error_msg=None, result=new_obj) - - def apply_recomputed_object_in_place( - obj: ImageObj, - new_obj: ImageObj, - proc_params: ProcessingParameters, - ) -> None: - hrec.update_obj_in_place(obj, new_obj) - insert_processing_parameters(obj, proc_params) - - object_model = CascadeObjectModel([source, downstream]) - data_panel = SimpleNamespace( - PANEL_STR_ID="image", - objmodel=object_model, - processor=SimpleNamespace(recompute_1_to_1=recompute_1_to_1), - objprop=SimpleNamespace( - apply_recomputed_object_in_place=apply_recomputed_object_in_place - ), - ) - runtime = SimpleNamespace( - objects=SimpleNamespace( - action_output_uuids={ - creation_action.uuid: [source_uuid], - downstream_action.uuid: [downstream_uuid], - } - ), - execution=SimpleNamespace(cascade_warnings=[]), - ) - history_panel = SimpleNamespace( - runtime=runtime, - history_sessions=[session], - ) - refreshed_uuids: list[str] = [] - - def record_refresh(panel_data: object, output_uuid: str) -> None: - assert panel_data is data_panel - refreshed_uuids.append(output_uuid) + with patch.object( + hrec, "create_image_from_param", wraps=create_image_from_param + ) as create_image_mock: + assert hrec.recompute_creation_in_place(history, creation_action) + assert hrec.recompute_compute_in_place(history, downstream_action) - descendants = hrec.hchain.get_downstream_actions(history_panel, creation_action) - assert descendants == [downstream_action] + create_image_mock.assert_called_once() + assert create_image_mock.call_args.args[0] is edited_param + assert history.runtime.execution.cascade_warnings == [] - with ( - patch.object(hrec.hchain, "resolve_panel_for_action", return_value=data_panel), - patch.object( - hrec, "create_image_from_param", wraps=create_image_from_param - ) as create_image_mock, - patch.object(hrec, "refresh_target", side_effect=record_refresh), - ): - assert hrec.recompute_creation_in_place(history_panel, creation_action) - assert hrec.recompute_1_to_1_in_place(history_panel, downstream_action) - - create_image_mock.assert_called_once() - assert create_image_mock.call_args.args[0] is edited_param - - assert id(source) == source_identity - assert object_model[source_uuid] is source - assert get_uuid(source) == source_uuid - np.testing.assert_allclose(source.data, expected_source.data) - assert not np.array_equal(source.data, initial_source_data) - creation_param = extract_creation_parameters(source) - assert isinstance(creation_param, Gauss2DParam) - for name in ("height", "width", "x0", "y0", "sigma", "a"): - assert getattr(creation_param, name) == getattr(edited_param, name) - - assert processor_source_objects == [source] - np.testing.assert_allclose(processor_source_data[0], expected_source.data) - assert id(downstream) == downstream_identity - assert object_model[downstream_uuid] is downstream - assert get_uuid(downstream) == downstream_uuid - np.testing.assert_allclose( - downstream.data, expected_source.data.astype(float) * 2.0 + 3.0 - ) - assert not np.array_equal(downstream.data, initial_downstream_data) - downstream_params = extract_processing_parameters(downstream) - assert downstream_params is not None - assert downstream_params.source_uuid == source_uuid - assert refreshed_uuids == [source_uuid, downstream_uuid] - assert runtime.execution.cascade_warnings == [] + assert panel.objmodel[source_uuid] is source + assert id(source) == source_identity + np.testing.assert_allclose(source.data, expected_source.data) + assert not np.array_equal(source.data, initial_source_data) + creation_param = extract_creation_parameters(source) + assert isinstance(creation_param, Gauss2DParam) + for name in ("height", "width", "x0", "y0", "sigma", "a"): + assert getattr(creation_param, name) == getattr(edited_param, name) + + assert panel.objmodel[downstream_uuid] is downstream + assert id(downstream) == downstream_identity + assert not np.array_equal(downstream.data, initial_downstream_data) + downstream_params = extract_processing_parameters(downstream) + assert downstream_params is not None + assert downstream_params.source_uuid == source_uuid diff --git a/datalab/widgets/historytree.py b/datalab/widgets/historytree.py index 4544e3ff0..ec274175e 100644 --- a/datalab/widgets/historytree.py +++ b/datalab/widgets/historytree.py @@ -250,6 +250,7 @@ def refresh_action_item(self, action: HistoryAction) -> None: # it reflects the mutated ``action.kwargs``. self.removeItemWidget(item, self.DESCRIPTION_COLUMN) self.install_description_widget(item, action) + item.setText(0, action.title) brush = stale_brush if action.is_stale else normal_brush for col in range(self.columnCount()): item.setBackground(col, brush) From a1849374e0cb27db439d852f42aa6a975d0abe75 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Fri, 7 Aug 2026 11:22:41 +0200 Subject: [PATCH 081/108] Fix: Persistent yellow highlighting in History panel after failed replay The History tree painted a light orange background on actions flagged as stale (being recomputed in a cascade). When a recompute failed during replay, the flag remained set and the highlight persisted indefinitely, confusing users. The visual marker is removed; the is_stale flag is kept as an internal state of the cascade engine. * [FIX] : Always reset action row background to the default brush in HistoryTree.refresh_action_item, removing the stale highlight --- datalab/widgets/historytree.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/datalab/widgets/historytree.py b/datalab/widgets/historytree.py index ec274175e..1561aaefa 100644 --- a/datalab/widgets/historytree.py +++ b/datalab/widgets/historytree.py @@ -235,13 +235,12 @@ def refresh_action_item(self, action: HistoryAction) -> None: Re-installs the description widget so it reflects the current ``action.kwargs`` (e.g. after the user edited a ``param`` via the - Processing tab of the Signal/Image panel). Also applies a light - orange background when ``action.is_stale`` is True, to signal that - the action is currently being recomputed in a cascade. + Processing tab of the Signal/Image panel). Also resets the item + background to the default brush on all columns, clearing any + highlight previously painted on the row. """ target_uuid = action.uuid - stale_brush = QG.QBrush(QG.QColor(255, 220, 150)) # light orange - normal_brush = QG.QBrush() + default_brush = QG.QBrush() iterator = QW.QTreeWidgetItemIterator(self) while iterator.value(): item = iterator.value() @@ -251,9 +250,8 @@ def refresh_action_item(self, action: HistoryAction) -> None: self.removeItemWidget(item, self.DESCRIPTION_COLUMN) self.install_description_widget(item, action) item.setText(0, action.title) - brush = stale_brush if action.is_stale else normal_brush for col in range(self.columnCount()): - item.setBackground(col, brush) + item.setBackground(col, default_brush) self.scheduleDelayedItemsLayout() return iterator += 1 From 831065b92a806fd27db1143bc3850fb0007b75fd Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Fri, 7 Aug 2026 13:48:26 +0200 Subject: [PATCH 082/108] Feat: Delete key support in the History panel The keyboard Delete key had no effect in the History panel tree, unlike the Signal/Image panels where it removes the selected objects. The data panels register a window-level Delete shortcut, so the history tree must consume the key itself to avoid triggering deletions in the data panels while it has focus. * [NEW] : Intercept ShortcutOverride for Delete in HistoryTree so the window-level Remove shortcut does not fire when the tree has focus * [NEW] : Trigger the panel Delete action from HistoryTree.keyPressEvent when the Delete key is pressed --- datalab/widgets/historytree.py | 36 ++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/datalab/widgets/historytree.py b/datalab/widgets/historytree.py index 1561aaefa..211b819d8 100644 --- a/datalab/widgets/historytree.py +++ b/datalab/widgets/historytree.py @@ -46,6 +46,42 @@ def __init__(self, parent: QW.QWidget) -> None: # Used to highlight the active session and survive tree repopulation. self.__active_session_number: int | None = None + def event(self, event: QC.QEvent) -> bool: + """Intercept Delete shortcut overrides while the tree has focus. + + Accepting the ShortcutOverride event prevents window-level Delete + shortcuts (e.g. the data panels' Remove action) from being triggered + while the history tree has focus; the key is then delivered to + :py:meth:`keyPressEvent` instead. + + Args: + event: Event to process. + + Returns: + True if the event was handled. + """ + if event.type() == QC.QEvent.ShortcutOverride and event.matches( + QG.QKeySequence.Delete + ): + event.accept() + return True + return super().event(event) + + def keyPressEvent(self, event: QG.QKeyEvent) -> None: + """Trigger the panel's Delete action when the Delete key is pressed. + + Args: + event: Key event. + """ + if event.matches(QG.QKeySequence.Delete): + ui = getattr(self._panel, "ui", None) + action = None if ui is None else ui.actions.get("delete") + if action is not None and action.isEnabled(): + action.trigger() + event.accept() + return + super().keyPressEvent(event) + def on_description_toggled(self, uuid: str, expanded: bool) -> None: """Remember the expanded state of a description cell.""" self.__expanded_state[uuid] = expanded From 7e719e8a88df47fc7ae933abce9e1544d60008c4 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Fri, 7 Aug 2026 16:31:09 +0200 Subject: [PATCH 083/108] Fix: History replay of load actions aborted after a recorded deletion With history recording enabled, loading objects then deleting them records a remove action in the same session. Replaying the session (e.g. Replay button with no tree selection, which targets the last session) crashed: the deferred destructive action called WorkspaceState.restore on captured UUIDs that no longer exist, raising ValueError and aborting the whole plan before objects could be reloaded. * [FIX] : Skip deferred destructive UI actions whose captured workspace state is no longer compatible, instead of letting restore() abort the execution plan * [NEW] : Emit a cascade warning when such a destructive action is skipped so the user knows the recorded deletion was dropped * [NEW] : GUI-faithful regression tests (record mode ON during deletion, replay via replay_restore_actions) for file loads, directory loads and the session-fallback scenario --- .../gui/panel/history/interactive_replay.py | 18 ++++ .../common/history_replay_fixes_test.py | 100 +++++++++++++++++- 2 files changed, 117 insertions(+), 1 deletion(-) diff --git a/datalab/gui/panel/history/interactive_replay.py b/datalab/gui/panel/history/interactive_replay.py index 016af9035..e69c542b9 100644 --- a/datalab/gui/panel/history/interactive_replay.py +++ b/datalab/gui/panel/history/interactive_replay.py @@ -307,6 +307,24 @@ def replay_actions( # Mutation targeting an object whose recompute failed # upstream: skip it like a blocked compute. continue + if ( + action.kind == HistoryAction.KIND_UI + and action.method_name in HistoryAction.DESTRUCTIVE_METHODS + and not action.is_current_state_compatible(panel.mainwindow) + ): + # Destructive action whose captured selection no longer + # resolves (e.g. recorded deletion of objects that a + # replayed load just re-created under new UUIDs): skip + # it instead of failing the whole plan on restore. + name = action.title or action.method_name or action.uuid + panel.runtime.execution.cascade_warnings.append( + _( + "Action %s targets objects that no longer exist " + "and was skipped." + ) + % name + ) + continue is_load_action = ( action.kind == HistoryAction.KIND_UI and action.method_name in HistoryAction.UI_LOAD_METHODS diff --git a/datalab/tests/features/common/history_replay_fixes_test.py b/datalab/tests/features/common/history_replay_fixes_test.py index 7fb2a309e..2f1524e85 100644 --- a/datalab/tests/features/common/history_replay_fixes_test.py +++ b/datalab/tests/features/common/history_replay_fixes_test.py @@ -23,7 +23,10 @@ from datalab.gui.panel.history import recompute as hrec from datalab.objectmodel import get_uuid from datalab.tests import datalab_test_app_context -from datalab.tests.features.common.history_test_helpers import add_paracetamol_signals +from datalab.tests.features.common.history_test_helpers import ( + add_paracetamol_signals, + select_tree_entry, +) def record_line_profile(win) -> tuple: @@ -307,6 +310,101 @@ def test_replay_load_from_directory_reloads_deleted_objects(tmp_path) -> None: assert reloaded_groups.get("subb") == 2 +def test_replay_load_reloads_after_recorded_deletion(tmp_path) -> None: + """Reload deleted objects when the deletion itself was recorded. + + Faithful GUI scenario: record mode stays ON during the deletion (so a + ``remove_object`` UI action is recorded and the reconnection machinery + runs), and the replay goes through the real GUI entry point + ``replay_restore_actions`` (Replay button / double-click) with the load + action selected in the tree. + """ + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + populate_signal_directory(win, tmp_path, {"": ["s1.csv", "s2.csv"]}) + history.toggle_record_mode(True) + fnames = [str(tmp_path / "s1.csv"), str(tmp_path / "s2.csv")] + objs = panel.load_from_files(fnames) + assert len(objs) == 2 + action = history[len(history)] + assert action.method_name == "load_from_files" + # Record mode stays ON: the deletion is recorded as a UI action + panel.objview.select_objects(panel.objmodel.get_object_ids()) + panel.remove_object(force=True) + assert len(panel.objmodel) == 0 + remove_action = history[len(history)] + assert remove_action.method_name == "remove_object" + + select_tree_entry(history, action.uuid) + history.replay_restore_actions(restore_selection=False) + + assert len(panel.objmodel) == 2 + assert action.is_stale is False + assert len(action.output_uuids) == 2 + assert all( + panel.objmodel.has_uuid(output_uuid) for output_uuid in action.output_uuids + ) + + +def test_replay_directory_load_reloads_after_recorded_deletion(tmp_path) -> None: + """Directory-load variant of the recorded-deletion replay scenario.""" + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + populate_signal_directory( + win, tmp_path, {"suba": ["s1.csv", "s2.csv"], "subb": ["s3.csv"]} + ) + history.toggle_record_mode(True) + objs = panel.load_from_directory(str(tmp_path)) + assert len(objs) == 3 + action = history[len(history)] + assert action.method_name == "load_from_directory" + # Record mode stays ON: the deletion is recorded as a UI action + panel.objview.select_objects(panel.objmodel.get_object_ids()) + panel.remove_object(force=True) + assert len(panel.objmodel) == 0 + + select_tree_entry(history, action.uuid) + history.replay_restore_actions(restore_selection=False) + + assert len(panel.objmodel) == 3 + assert action.is_stale is False + assert len(action.output_uuids) == 3 + assert all( + panel.objmodel.has_uuid(output_uuid) for output_uuid in action.output_uuids + ) + + +def test_replay_session_fallback_after_recorded_deletion(tmp_path) -> None: + """Replay with no tree selection after a recorded deletion. + + With nothing selected in the tree, ``replay_restore_actions`` targets the + last session, which contains both the load action and the recorded + ``remove_object`` action. The load must be replayed and the destructive + action skipped (its captured UUIDs no longer exist), leaving the reloaded + objects in place. + """ + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + populate_signal_directory(win, tmp_path, {"": ["s1.csv", "s2.csv"]}) + history.toggle_record_mode(True) + fnames = [str(tmp_path / "s1.csv"), str(tmp_path / "s2.csv")] + objs = panel.load_from_files(fnames) + assert len(objs) == 2 + action = history[len(history)] + # Record mode stays ON: the deletion is recorded as a UI action + panel.objview.select_objects(panel.objmodel.get_object_ids()) + panel.remove_object(force=True) + assert len(panel.objmodel) == 0 + + history.tree.clearSelection() + history.replay_restore_actions(restore_selection=False) + + assert len(panel.objmodel) == 2 + assert all( + panel.objmodel.has_uuid(output_uuid) for output_uuid in action.output_uuids + ) + + def test_replay_load_skipped_when_outputs_still_exist(tmp_path) -> None: """Skip a load-action replay when every loaded object still exists.""" with datalab_test_app_context(history=True) as win: From 344e24c158852cde928de467d8f566557ba9aed1 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Mon, 10 Aug 2026 10:12:44 +0200 Subject: [PATCH 084/108] Fix: Duplicated history chains no longer interfere with their source chain Duplicating a processing chain in the History panel, replaying the copy, then deleting the original objects group caused both history sessions to drive the same remaining chain: replaying a session recreated its objects under their recorded UUIDs, which made a recorded deletion compatible again so it wiped the freshly recreated results, and legacy resolution heuristics could bind an action onto objects produced by another session. * [FIX] : Add plan-level guards for deferred destructive actions: skip when the recorded state no longer matches, when targets were recreated earlier in the same replay plan, or when targets belong to another session; emit a cascade warning on each skip * [FIX] : Scope legacy output/action resolution heuristics to the owning session (pre-registry single-session histories unchanged) * [CHG] : Log UUID remap failures during duplication instead of silently ignoring them, and verify post-duplication independence (warn-only invariant) * [NEW] : GUI-faithful regression tests for chain independence after deleting the original group, and for cross-session recorded deletions --- datalab/gui/historytools_ops.py | 94 ++++++++- datalab/gui/panel/history/chain.py | 48 ++++- .../gui/panel/history/interactive_replay.py | 85 ++++++-- .../common/history_replay_fixes_test.py | 181 ++++++++++++++++++ 4 files changed, 388 insertions(+), 20 deletions(-) diff --git a/datalab/gui/historytools_ops.py b/datalab/gui/historytools_ops.py index 6acc39d4b..0566b0bee 100644 --- a/datalab/gui/historytools_ops.py +++ b/datalab/gui/historytools_ops.py @@ -4,6 +4,7 @@ from __future__ import annotations +import logging from copy import deepcopy from typing import TYPE_CHECKING, Any from uuid import uuid4 @@ -40,6 +41,8 @@ from datalab.gui.panel.base import BaseDataPanel from datalab.gui.panel.history import HistoryPanel +logger = logging.getLogger(__name__) + def action_panel_str(action: HistoryAction) -> str: """Return the panel an action operates on, using target as fallback.""" @@ -196,7 +199,13 @@ def clone_referenced_objects( def remap_cloned_object_sources(registry: UuidCloneRegistry) -> None: - """Rewrite processing-parameter source UUIDs in all cloned objects.""" + """Rewrite processing-parameter source UUIDs in all cloned objects. + + Any failure to read, parse or write a clone's processing parameters is + logged: a clone silently keeping ``source_uuid``/``source_uuids`` + references to the original objects would break the independence of the + duplicated chain. + """ for panel_str, clones in registry.clones_by_panel.items(): panel_remap = registry.uuid_remap.get(panel_str, {}) for clone in clones: @@ -204,13 +213,25 @@ def remap_cloned_object_sources(registry: UuidCloneRegistry) -> None: parameters_dict = clone.get_metadata_option( PROCESSING_PARAMETERS_OPTION ) - except (AttributeError, ValueError): + except ValueError: + # Normal case: source objects carry no processing parameters. + continue + except AttributeError: + logger.warning( + "Duplicate: cannot read processing parameters of clone %r.", + getattr(clone, "title", clone), + ) continue if not parameters_dict: continue try: parameters = ProcessingParameters.from_dict(parameters_dict) except (TypeError, ValueError, AttributeError): + logger.warning( + "Duplicate: unparsable processing parameters on clone %r " + "— source UUIDs were not remapped.", + getattr(clone, "title", clone), + ) continue remapped = remap_processing_parameters(parameters, panel_remap) if remapped == parameters: @@ -220,6 +241,11 @@ def remap_cloned_object_sources(registry: UuidCloneRegistry) -> None: PROCESSING_PARAMETERS_OPTION, remapped.to_dict() ) except (AttributeError, ValueError): + logger.warning( + "Duplicate: failed to store remapped processing " + "parameters on clone %r.", + getattr(clone, "title", clone), + ) continue @@ -287,6 +313,69 @@ def register_session_outputs(panel: HistoryPanel, session: HistorySession) -> No panel.runtime.objects.register_action_outputs(action, action.output_uuids) +def action_referenced_uuids(action: HistoryAction) -> set[str]: + """Return every object UUID referenced by an action (inputs and outputs).""" + referenced: set[str] = set() + for uuids in action.state.selection.values(): + referenced.update(uuids) + obj2_uuids = action.kwargs.get("obj2_uuids") or [] + if isinstance(obj2_uuids, str): + obj2_uuids = [obj2_uuids] + referenced.update(obj2_uuids) + referenced.update(action.output_uuids) + referenced.update(action.target_uuids or []) + if action.effects: + referenced.update(action.effects) + return referenced + + +def verify_duplicated_session_independence( + session: HistorySession, registry: UuidCloneRegistry +) -> None: + """Log a warning when a duplicated session still references source UUIDs. + + Post-duplication invariant: no duplicated action and no clone processing + parameters may reference a UUID from the original (remapped) mapping. A + violation means the duplicated chain is not fully independent from the + original one; it is logged (not raised) so the duplication still succeeds. + + Args: + session: The freshly assembled duplicated session. + registry: Clone registry holding the source-to-clone UUID mapping. + """ + source_uuids = { + old_uuid for pmap in registry.uuid_remap.values() for old_uuid in pmap + } + if not source_uuids: + return + for action in session.actions: + leaked = action_referenced_uuids(action) & source_uuids + if leaked: + logger.warning( + "Duplicate: action %r of session %r still references original " + "object UUID(s) %s.", + action.title, + session.title, + sorted(leaked), + ) + for clones in registry.clones_by_panel.values(): + for clone in clones: + parameters = extract_processing_parameters(clone) + if parameters is None: + continue + sources = set(parameters.source_uuids or []) + if parameters.source_uuid is not None: + sources.add(parameters.source_uuid) + leaked = sources & source_uuids + if leaked: + logger.warning( + "Duplicate: clone %r still references original object " + "UUID(s) %s in its processing parameters.", + getattr(clone, "title", clone), + sorted(leaked), + ) + + def duplicate_chain_plan( panel: HistoryPanel, plan: ChainSelectionPlan, copy_suffix: str ) -> DuplicatedSession: @@ -300,6 +389,7 @@ def duplicate_chain_plan( ) new_session.actions = assemble_duplicated_actions(panel, plan, registry) register_session_outputs(panel, new_session) + verify_duplicated_session_independence(new_session, registry) return DuplicatedSession(plan.source_session, new_session) diff --git a/datalab/gui/panel/history/chain.py b/datalab/gui/panel/history/chain.py index d13e09b05..3691e13ae 100644 --- a/datalab/gui/panel/history/chain.py +++ b/datalab/gui/panel/history/chain.py @@ -62,7 +62,11 @@ def find_output_object_uuid( """Find the UUID of the output object produced by ``action`` in ``panel_data``. Primary path: consult the bijective ``action_output_uuids`` mapping. - Fallback path: legacy heuristic on ``processing_parameters`` metadata. + Fallback path: legacy heuristic on ``processing_parameters`` metadata, + scoped to ``action``'s own session: an object whose producing action + (via the ``output_to_action`` registry) belongs to a different session is + never matched, so an action can never resolve onto an object produced by + another session (e.g. a duplicated chain's clone). """ registered = panel.runtime.objects.action_output_uuids.get(action.uuid) if registered: @@ -78,21 +82,42 @@ def find_output_object_uuid( recorded_uuids = set(action.state.selection.get(panel_data.PANEL_STR_ID, [])) if not recorded_uuids: return None + own_session = find_parent_session(panel, action) + own_action_uuids = ( + {act.uuid for act in own_session.actions} if own_session is not None else None + ) for obj in panel_data.objmodel: + obj_uuid = get_uuid(obj) + producer_uuid = panel.runtime.objects.output_to_action.get(obj_uuid) + if ( + producer_uuid is not None + and own_action_uuids is not None + and producer_uuid not in own_action_uuids + ): + # Produced by another session's action: out of scope. + continue pp = extract_processing_parameters(obj) if pp is None or pp.func_name != action.func_name: continue if pp.source_uuid is not None and pp.source_uuid in recorded_uuids: - return get_uuid(obj) + return obj_uuid if pp.source_uuids is not None and recorded_uuids.intersection(pp.source_uuids): - return get_uuid(obj) + return obj_uuid return None def find_action_for_output( panel: HistoryPanel, output_uuid: str, func_name: str ) -> HistoryAction | None: - """Find the :class:`HistoryAction` that produced ``output_uuid``.""" + """Find the :class:`HistoryAction` that produced ``output_uuid``. + + Primary path: consult the ``output_to_action`` registry. Fallback path: + legacy heuristic matching ``func_name`` and the output's recorded source + UUID; when the source object's own producing action is registered, the + scan is scoped to that action's session so the output is never attributed + to an action of a different session (e.g. matching an original-session + action for a duplicated chain's clone, or vice versa). + """ if not panel.history_sessions: return None action_uuid = panel.runtime.objects.output_to_action.get(output_uuid) @@ -121,7 +146,20 @@ def find_action_for_output( if pp is None or pp.func_name != func_name or pp.source_uuid is None: return None target_source_uuid = pp.source_uuid - for current_session in reversed(panel.history_sessions): + sessions = list(panel.history_sessions) + source_action_uuid = panel.runtime.objects.output_to_action.get(target_source_uuid) + if source_action_uuid is not None: + owner_session = next( + ( + session + for session in sessions + if any(act.uuid == source_action_uuid for act in session.actions) + ), + None, + ) + if owner_session is not None: + sessions = [owner_session] + for current_session in reversed(sessions): for action in reversed(current_session.actions): if action.kind != HistoryAction.KIND_COMPUTE: continue diff --git a/datalab/gui/panel/history/interactive_replay.py b/datalab/gui/panel/history/interactive_replay.py index e69c542b9..640c17e6b 100644 --- a/datalab/gui/panel/history/interactive_replay.py +++ b/datalab/gui/panel/history/interactive_replay.py @@ -217,6 +217,68 @@ def _recompute_stale_actions(panel: HistoryPanel, ordered: list[HistoryAction]) hrec.flush_cascade_warnings(panel) +def destructive_replay_skip_reason( + panel: HistoryPanel, + action: HistoryAction, + recreated_outputs: set[str], +) -> str | None: + """Return a warning when a destructive action must not be replayed. + + A destructive UI action (``DESTRUCTIVE_METHODS``) is skipped when: + + 1. Its captured selection no longer resolves (e.g. recorded deletion of + objects that a replayed load just re-created under new UUIDs). + 2. It targets objects that were (re)computed earlier in the same + execution plan: replaying the recorded deletion would immediately + destroy the outputs this replay just restored. + 3. It targets outputs produced by another session's actions: replaying + one session must never delete objects owned by a different session + (e.g. a deletion of the original chain recorded while a duplicated + session was active). + + Args: + panel: History panel instance + action: Destructive UI action about to be replayed + recreated_outputs: Output UUIDs already (re)computed by this plan + + Returns: + The warning message when the action must be skipped, ``None`` when + the action may be replayed. + """ + name = action.title or action.method_name or action.uuid + if not action.is_current_state_compatible(panel.mainwindow): + return ( + _( + "Action %s was skipped: its recorded workspace state no " + "longer matches the current workspace." + ) + % name + ) + captured = {uuid for uuids in action.state.selection.values() for uuid in uuids} + if captured & recreated_outputs: + return ( + _( + "Action %s would delete objects that this replay just " + "recomputed and was skipped." + ) + % name + ) + own_session = hchain.find_parent_session(panel, action) + if own_session is not None: + own_action_uuids = {act.uuid for act in own_session.actions} + for uuid in captured: + producer_uuid = panel.runtime.objects.output_to_action.get(uuid) + if producer_uuid is not None and producer_uuid not in own_action_uuids: + return ( + _( + "Action %s targets objects produced by another " + "session and was skipped." + ) + % name + ) + return None + + def replay_actions( panel: HistoryPanel, actions: list[HistoryAction], prompt: bool = True ) -> None: @@ -300,6 +362,7 @@ def replay_actions( panel.tree.refresh_action_item(action) QW.QApplication.processEvents() blocked_outputs: set[str] = set() + recreated_outputs: set[str] = set() try: for action in execution_plan: if action in deferred_actions: @@ -310,21 +373,13 @@ def replay_actions( if ( action.kind == HistoryAction.KIND_UI and action.method_name in HistoryAction.DESTRUCTIVE_METHODS - and not action.is_current_state_compatible(panel.mainwindow) ): - # Destructive action whose captured selection no longer - # resolves (e.g. recorded deletion of objects that a - # replayed load just re-created under new UUIDs): skip - # it instead of failing the whole plan on restore. - name = action.title or action.method_name or action.uuid - panel.runtime.execution.cascade_warnings.append( - _( - "Action %s targets objects that no longer exist " - "and was skipped." - ) - % name + skip_reason = destructive_replay_skip_reason( + panel, action, recreated_outputs ) - continue + if skip_reason is not None: + panel.runtime.execution.cascade_warnings.append(skip_reason) + continue is_load_action = ( action.kind == HistoryAction.KIND_UI and action.method_name in HistoryAction.UI_LOAD_METHODS @@ -400,6 +455,10 @@ def replay_actions( blocked_outputs.update( hchain.recorded_action_output_uuids(panel, action) ) + else: + recreated_outputs.update( + hchain.recorded_action_output_uuids(panel, action) + ) finally: hrec.flush_cascade_warnings(panel) QW.QApplication.processEvents() diff --git a/datalab/tests/features/common/history_replay_fixes_test.py b/datalab/tests/features/common/history_replay_fixes_test.py index 2f1524e85..35511bc64 100644 --- a/datalab/tests/features/common/history_replay_fixes_test.py +++ b/datalab/tests/features/common/history_replay_fixes_test.py @@ -13,19 +13,23 @@ from unittest.mock import patch import numpy as np +import sigima.objects import sigima.params import sigima.proc.signal as sips from sigima.tests.data import create_paracetamol_signal, create_sincos_image from datalab.config import _ from datalab.env import execenv +from datalab.gui import historytools_ops as htools from datalab.gui.panel.history import interactive_replay as hireplay from datalab.gui.panel.history import recompute as hrec +from datalab.gui.processor.base import extract_processing_parameters from datalab.objectmodel import get_uuid from datalab.tests import datalab_test_app_context from datalab.tests.features.common.history_test_helpers import ( add_paracetamol_signals, select_tree_entry, + select_tree_session, ) @@ -653,3 +657,180 @@ def test_replay_recreates_deleted_pairwise_n_to_1_output() -> None: assert action.output_uuids == recorded assert panel.objmodel.has_uuid(deleted_uuid) assert np.array_equal(panel.objmodel[deleted_uuid].xydata, expected_data) + + +def assert_no_original_reference(action, original_uuids: set[str]) -> None: + """Assert that a duplicated action references no original object UUID. + + Args: + action: Duplicated history action to inspect + original_uuids: UUIDs of the original (source) chain objects + """ + captured = set(action.state.selection.get("signal", [])) + assert not captured & original_uuids, action.title + obj2 = action.kwargs.get("obj2_uuids") or [] + if isinstance(obj2, str): + obj2 = [obj2] + assert not set(obj2) & original_uuids, action.title + assert not set(action.output_uuids) & original_uuids, action.title + + +def test_duplicated_chain_independent_after_original_group_deletion() -> None: + """Keep a duplicated chain fully independent after deleting the originals. + + User scenario: build a chain (recorded creation + two computes), duplicate + it from the History panel, re-run the duplicated chain with different + parameters, then delete the ORIGINAL objects group from the Signal panel. + Replaying each session afterwards must only touch that session's own + objects: the duplicate is a fully standalone deep copy. + """ + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + # Original chain: recorded creation + two 1-to-1 computes + panel.new_object(param=sigima.objects.GaussParam(), edit=False) + source_uuid = get_uuid(panel.objmodel.get_object_from_number(1)) + panel.objview.select_objects([source_uuid]) + panel.processor.run_feature( + sips.gaussian_filter, sigima.params.GaussianParam.create(sigma=1.5) + ) + gaussian = history[len(history)] + panel.objview.select_objects(gaussian.output_uuids) + panel.processor.run_feature(sips.derivative) + original = history.history_sessions[-1] + original_uuids = [ + uuid for action in original.actions for uuid in action.output_uuids + ] + assert original_uuids[0] == source_uuid + # Duplicate the whole session (History panel "Duplicate" command) + select_tree_session(history, original) + htools.duplicate_selected_entries(history) + duplicate = history.history_sessions[-1] + assert duplicate is not original + clone_uuids = [ + uuid for action in duplicate.actions for uuid in action.output_uuids + ] + assert set(clone_uuids).isdisjoint(original_uuids) + # No duplicated action nor clone object references an original UUID + for action in duplicate.actions: + assert_no_original_reference(action, set(original_uuids)) + for uuid in clone_uuids: + parameters = extract_processing_parameters(panel.objmodel[uuid]) + if parameters is None: + continue + sources = list(parameters.source_uuids or []) + if parameters.source_uuid is not None: + sources.append(parameters.source_uuid) + assert not set(sources) & set(original_uuids), uuid + # Re-run the duplicated chain with a different parameter + dup_gaussian = next( + action + for action in duplicate.actions + if action.func_name == "gaussian_filter" + ) + dup_gaussian.kwargs["param"] = sigima.params.GaussianParam.create(sigma=4.0) + with patch.object(hrec, "flush_cascade_warnings"): + hireplay.replay_actions(history, list(duplicate.actions), prompt=False) + # Delete the ORIGINAL objects group from the Signal panel + original_group_id = panel.objmodel.get_object_group_id( + panel.objmodel[source_uuid] + ) + panel.objview.select_groups([original_group_id]) + panel.remove_object(force=True) + assert all(not panel.objmodel.has_uuid(uuid) for uuid in original_uuids) + clone_data = {uuid: panel.objmodel[uuid].xydata.copy() for uuid in clone_uuids} + # The deletion must not rewire the duplicated session onto originals + for action in duplicate.actions: + if action.kind == action.KIND_COMPUTE: + assert_no_original_reference(action, set(original_uuids)) + # Replay the ORIGINAL session: it must only touch its own objects + select_tree_session(history, original) + with patch.object(hrec, "flush_cascade_warnings"): + hireplay.replay_restore_actions(history) + for uuid in clone_uuids: + assert panel.objmodel.has_uuid(uuid), "clone deleted by original replay" + assert np.array_equal(panel.objmodel[uuid].xydata, clone_data[uuid]), ( + "original session replay modified a clone object" + ) + for uuid in original_uuids: + assert panel.objmodel.has_uuid(uuid), ( + "original session replay did not recreate its own objects" + ) + original_data = { + uuid: panel.objmodel[uuid].xydata.copy() for uuid in original_uuids + } + # Replay the DUPLICATED session: original objects must stay untouched + select_tree_session(history, duplicate) + with patch.object(hrec, "flush_cascade_warnings"): + hireplay.replay_restore_actions(history) + for uuid in original_uuids: + assert panel.objmodel.has_uuid(uuid), ( + "duplicate session replay deleted an original object" + ) + assert np.array_equal(panel.objmodel[uuid].xydata, original_data[uuid]), ( + "duplicate session replay modified an original object" + ) + for uuid in clone_uuids: + assert np.array_equal(panel.objmodel[uuid].xydata, clone_data[uuid]) + + +def test_replay_skips_recorded_deletion_of_another_session_objects() -> None: + """Skip a recorded deletion targeting objects owned by another session. + + Variant of the duplication scenario where the duplicated session is the + active recording session when the ORIGINAL objects group is deleted: the + ``remove_object`` action lands in the duplicated session but captures the + original session's objects. Replaying the duplicated session must never + delete the original session's (recreated) objects. + """ + with datalab_test_app_context(history=True) as win: + history, panel = win.historypanel, win.signalpanel + history.toggle_record_mode(True) + panel.new_object(param=sigima.objects.GaussParam(), edit=False) + source_uuid = get_uuid(panel.objmodel.get_object_from_number(1)) + panel.objview.select_objects([source_uuid]) + panel.processor.run_feature( + sips.gaussian_filter, sigima.params.GaussianParam.create(sigma=1.5) + ) + original = history.history_sessions[-1] + original_uuids = [ + uuid for action in original.actions for uuid in action.output_uuids + ] + select_tree_session(history, original) + htools.duplicate_selected_entries(history) + duplicate = history.history_sessions[-1] + # The duplicated session is the active recording session when the + # original group is deleted: the remove action lands in it. + history.navigation.set_active_session(duplicate) + original_group_id = panel.objmodel.get_object_group_id( + panel.objmodel[source_uuid] + ) + panel.objview.select_groups([original_group_id]) + panel.remove_object(force=True) + remove_action = duplicate.actions[-1] + assert remove_action.method_name == "remove_object" + # Replay the ORIGINAL session: its objects are recreated + select_tree_session(history, original) + with patch.object(hrec, "flush_cascade_warnings"): + hireplay.replay_restore_actions(history) + assert all(panel.objmodel.has_uuid(uuid) for uuid in original_uuids) + # Replay the DUPLICATED session: the recorded deletion of the original + # session's objects must be skipped + select_tree_session(history, duplicate) + history.runtime.execution.cascade_warnings.clear() + with patch.object(hrec, "flush_cascade_warnings"): + hireplay.replay_restore_actions(history) + assert all(panel.objmodel.has_uuid(uuid) for uuid in original_uuids), ( + "duplicate session replay deleted another session's objects" + ) + # The skip must come from guard 3 (objects produced by another session) + remove_name = ( + remove_action.title or remove_action.method_name or remove_action.uuid + ) + guard3_message = ( + _("Action %s targets objects produced by another session and was skipped.") + % remove_name + ) + assert guard3_message in history.runtime.execution.cascade_warnings, ( + "recorded deletion was not skipped by the cross-session guard" + ) From ed33c1dd787bdea0dded0c0e9c91582ee75e5a5c Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Mon, 10 Aug 2026 11:30:00 +0200 Subject: [PATCH 085/108] Fix: Active session no longer highlighted after loading an HDF5 file After loading a workspace from an HDF5 file, creating a new history session raised a TypeError and the active session title was no longer displayed in bold. Session numbers deserialized from HDF5 are NumPy scalars, so comparing them to the active session number produced a numpy.bool that Qt's QFont.setBold() rejects, aborting the highlight refresh. * [FIX] : Coerce the session number to a plain Python int when deserializing a history session from HDF5 * [FIX] : Cast the active-session comparison to bool in the history tree highlight refresh, so sessions loaded from older files remain safe --- datalab/history/session.py | 3 ++- datalab/widgets/historytree.py | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/datalab/history/session.py b/datalab/history/session.py index 1a7e624dc..724769fdc 100644 --- a/datalab/history/session.py +++ b/datalab/history/session.py @@ -128,7 +128,8 @@ def deserialize(self, reader: NativeH5Reader) -> None: with reader.group("title"): self.title = reader.read_any() with reader.group("number"): - self.number = reader.read_any() + # HDF5 readers return NumPy scalars: coerce to a plain Python int + self.number = int(reader.read_any()) with reader.group("dtstr"): self.dtstr = reader.read_any() self.actions = reader.read_object_list("actions", HistoryAction) diff --git a/datalab/widgets/historytree.py b/datalab/widgets/historytree.py index 211b819d8..b4c7a2484 100644 --- a/datalab/widgets/historytree.py +++ b/datalab/widgets/historytree.py @@ -239,7 +239,9 @@ def __apply_active_highlight(self) -> None: for i in range(self.topLevelItemCount()): item = self.topLevelItem(i) number = item.data(0, self.SESSION_NUMBER_ROLE) - is_active = number is not None and number == self.__active_session_number + is_active = bool( + number is not None and number == self.__active_session_number + ) font = item.font(0) font.setBold(is_active) for col in (0, 1): From dbde9b2d3faec13fc433dfe828eb3bc678add13e Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Mon, 10 Aug 2026 13:26:31 +0200 Subject: [PATCH 086/108] Feat: Broken-chain resolution dialog when replaying history When objects consumed by a recorded processing chain were deleted, the Replay, Step-by-step and double-click commands were vetoed with a bare error dialog (or a silent no-op), leaving the user stuck with a broken history. A resolution dialog now explains that deleted objects broke the chain and offers to repair it or cancel. * [NEW] : Replace the compatibility veto with a dialog offering "Repair and continue" (prune broken actions and their downstream descendants, then replay the remaining valid actions) or Cancel (history left untouched; the dialog reappears until repaired) * [NEW] : Unattended mode follows the accept_dialogs setting, keeping the previous conservative default (cancel) * [NEW] : Regression tests for the repair and cancel paths on a genuinely broken signal chain --- .../gui/panel/history/interactive_replay.py | 148 ++++++++++++++++-- .../common/history_replay_fixes_test.py | 93 +++++++++++ 2 files changed, 231 insertions(+), 10 deletions(-) diff --git a/datalab/gui/panel/history/interactive_replay.py b/datalab/gui/panel/history/interactive_replay.py index 640c17e6b..a27f79376 100644 --- a/datalab/gui/panel/history/interactive_replay.py +++ b/datalab/gui/panel/history/interactive_replay.py @@ -38,8 +38,11 @@ def replay_restore_actions( Entry point of the Replay, Step-by-step and double-click commands. When nothing is selected in the tree, the last session is targeted (no-op if the history is empty). Each selected session or action is first checked - against the current workspace state: any incompatibility vetoes the whole - command with an error dialog (skipped in unattended mode). + against the current workspace state: any incompatibility (e.g. an input + object was deleted, breaking the chain) triggers a resolution dialog + proposing to repair the history — remove the broken actions and their + downstream dependents, then continue with the remaining actions — or to + cancel the whole command (see :func:`confirm_broken_chain_repair`). When ``replay`` is enabled, the selected actions (sessions contribute all of their actions) are forwarded to :func:`replay_actions`, with parameter @@ -63,17 +66,27 @@ def replay_restore_actions( if not panel.history_sessions: return selected = [panel.history_sessions[-1]] + broken = [ + entry + for entry in selected + if not entry.is_current_state_compatible(panel.mainwindow) + ] + if broken: + if not confirm_broken_chain_repair(panel, broken): + return + repair_broken_entries(panel, broken) + hchain.refresh_reconnected_history(panel) + selected = [ + entry + for entry in selected + if _entry_still_in_history(panel, entry) + and entry.is_current_state_compatible(panel.mainwindow) + ] + if not selected: + return edit_mode = panel.runtime.execution.edit_mode actions_to_replay: list[HistoryAction] = [] for session_or_action in selected: - if not session_or_action.is_current_state_compatible(panel.mainwindow): - if not execenv.unattended: - QW.QMessageBox.critical( - panel.mainwindow, - _("Error"), - _("The current workspace state is not compatible with the action."), - ) - return if replay: if isinstance(session_or_action, HistorySession): actions_to_replay.extend(session_or_action.actions) @@ -92,6 +105,121 @@ def replay_restore_actions( replay_actions(panel, actions_to_replay, prompt=edit_mode) +def confirm_broken_chain_repair( + panel: HistoryPanel, broken: list[HistorySession | HistoryAction] +) -> bool: + """Propose repairing the history when the selected chain is broken. + + One or more selected sessions or actions reference objects that no longer + exist in the workspace (deleted inputs), so their processing chain is no + longer guaranteed. The user may repair the history — remove the broken + actions and their downstream dependents, then continue with the remaining + actions — or cancel (nothing is modified). In unattended mode no dialog + is shown: repair is chosen when ``execenv.accept_dialogs`` is set, + otherwise the command is cancelled. + + Args: + panel: History panel instance + broken: Selected sessions or actions whose recorded workspace state + no longer matches the current workspace + + Returns: + True if the history should be repaired and the command continued. + """ + if execenv.unattended: + return bool(execenv.accept_dialogs) + names: list[str] = [] + for entry in broken: + if isinstance(entry, HistorySession): + names.append(entry.title) + else: + names.append(entry.title or entry.func_name or entry.uuid) + msgbox = QW.QMessageBox(panel.mainwindow) + msgbox.setWindowTitle(_("Broken processing chain")) + msgbox.setIcon(QW.QMessageBox.Icon.Warning) + msgbox.setText( + _( + "One or more objects used by the selected processing chain were " + "deleted: the chain is broken and the following entries can no " + "longer be replayed:\n%s\n\n" + "Repair the history by removing the broken actions (and the " + "actions depending on them), then continue with the remaining " + "actions?" + ) + % "\n".join("• " + name for name in names) + ) + repair_button = msgbox.addButton( + _("Repair and continue"), QW.QMessageBox.ButtonRole.YesRole + ) + cancel_button = msgbox.addButton(QW.QMessageBox.Cancel) + msgbox.setDefaultButton(cancel_button) + msgbox.exec() + return msgbox.clickedButton() is repair_button + + +def collect_broken_chain_actions( + panel: HistoryPanel, broken: list[HistorySession | HistoryAction] +) -> list[HistoryAction]: + """Return the incompatible actions of ``broken`` plus their dependents. + + For a selected session, every action whose recorded workspace state is + incompatible with the current workspace is included; a directly selected + action is included as is. The downstream closure of each broken action + (actions consuming its outputs, transitively) is appended through + :func:`datalab.gui.panel.history.chain.get_downstream_actions`. + + Args: + panel: History panel instance + broken: Selected sessions or actions flagged as incompatible + + Returns: + Actions to remove from the history, in discovery order + """ + roots: list[HistoryAction] = [] + for entry in broken: + candidates = ( + [ + action + for action in entry.actions + if not action.is_current_state_compatible(panel.mainwindow) + ] + if isinstance(entry, HistorySession) + else [entry] + ) + for action in candidates: + if action not in roots: + roots.append(action) + to_remove = list(roots) + for action in roots: + # Same-session closure only: later sessions survive (objects not deleted) + for downstream in hchain.get_downstream_actions(panel, action): + if downstream not in to_remove: + to_remove.append(downstream) + return to_remove + + +def repair_broken_entries( + panel: HistoryPanel, broken: list[HistorySession | HistoryAction] +) -> None: + """Remove broken actions and their downstream dependents from the history. + + Args: + panel: History panel instance + broken: Selected sessions or actions flagged as incompatible + """ + for action in collect_broken_chain_actions(panel, broken): + hchain.remove_single_action(panel, action) + + +def _entry_still_in_history( + panel: HistoryPanel, entry: HistorySession | HistoryAction +) -> bool: + """Return True if ``entry`` survived the history repair.""" + if isinstance(entry, HistorySession): + return entry in panel.history_sessions and bool(entry.actions) + return hchain.find_parent_session(panel, entry) is not None + + def prepare_action_param_edit(action: HistoryAction) -> ActionParamEdit | None: """Prepare the editable parameter copy for ``action``.""" result = None diff --git a/datalab/tests/features/common/history_replay_fixes_test.py b/datalab/tests/features/common/history_replay_fixes_test.py index 35511bc64..707ab03a9 100644 --- a/datalab/tests/features/common/history_replay_fixes_test.py +++ b/datalab/tests/features/common/history_replay_fixes_test.py @@ -834,3 +834,96 @@ def test_replay_skips_recorded_deletion_of_another_session_objects() -> None: assert guard3_message in history.runtime.execution.cascade_warnings, ( "recorded deletion was not skipped by the cross-session guard" ) + + +def build_broken_signal_chain(win) -> tuple: + """Record a compute chain, then delete its root input (record mode OFF). + + The root signals are created with record mode disabled so no producer + action is registered: deleting ``root1`` afterwards cannot be reconnected + and the recorded chain is genuinely broken. The session records three + computes: a Gaussian filter and its derivative (both depending on + ``root1``) plus an independent normalize on ``root2``. + + Args: + win: DataLab main window + + Returns: + Tuple (session, broken actions, still-valid action) + """ + history, panel = win.historypanel, win.signalpanel + root1, root2 = add_paracetamol_signals(panel, 2) + history.toggle_record_mode(True) + panel.objview.select_objects([root1]) + panel.processor.run_feature( + sips.gaussian_filter, sigima.params.GaussianParam.create(sigma=1.5) + ) + gaussian = history[len(history)] + panel.objview.select_objects(gaussian.output_uuids) + panel.processor.run_feature(sips.derivative) + derivative = history[len(history)] + panel.objview.select_objects([root2]) + panel.processor.run_feature(sips.normalize, sigima.params.NormalizeParam.create()) + normalize = history[len(history)] + history.toggle_record_mode(False) + panel.objview.select_objects([root1]) + panel.remove_object(force=True) + history.toggle_record_mode(True) + session = history.history_sessions[-1] + assert not session.is_current_state_compatible(win) + return session, [gaussian, derivative], normalize + + +def test_replay_broken_chain_repair_and_continue() -> None: + """Repair a broken chain on replay, then replay the remaining actions. + + With ``accept_dialogs`` enabled, the broken-chain resolution dialog + defaults to "Repair and continue": the incompatible actions and their + downstream dependents are pruned from the history, the tree is refreshed + and the remaining valid action of the selection is replayed. + """ + with datalab_test_app_context(history=True) as win: + history = win.historypanel + session, broken_actions, valid_action = build_broken_signal_chain(win) + select_tree_session(history, session) + saved_accept_dialogs = execenv.accept_dialogs + execenv.accept_dialogs = True + try: + with patch.object(hrec, "flush_cascade_warnings"): + history.replay_restore_actions(restore_selection=False) + finally: + execenv.accept_dialogs = saved_accept_dialogs + # Broken actions and their downstream dependents were pruned + assert session in history.history_sessions + assert session.actions == [valid_action] + for action in broken_actions: + assert all( + action not in other.actions for other in history.history_sessions + ) + # The tree reflects the pruned history + assert history.tree.topLevelItemCount() == len(history.history_sessions) + # The remaining valid action was replayed + assert valid_action.is_stale is False + history.runtime.execution.cascade_warnings.clear() + + +def test_replay_broken_chain_cancel_keeps_history_intact() -> None: + """Cancel the broken-chain dialog: nothing is modified, nothing replayed. + + In unattended mode without ``accept_dialogs``, the resolution dialog + defaults to "Cancel": the history is left untouched and no action is + replayed. The dialog will simply reappear on the next replay attempt. + """ + with datalab_test_app_context(history=True) as win: + history = win.historypanel + session, broken_actions, valid_action = build_broken_signal_chain(win) + actions_before = list(session.actions) + select_tree_session(history, session) + assert execenv.unattended and not execenv.accept_dialogs + with patch.object(hireplay, "replay_actions") as replay_mock: + history.replay_restore_actions(restore_selection=False) + replay_mock.assert_not_called() + assert session in history.history_sessions + assert session.actions == actions_before + assert all(action in session.actions for action in broken_actions) + assert valid_action in session.actions From f4885a75099188e3c2509eaf0b8a830ffce138c7 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Mon, 10 Aug 2026 16:04:18 +0200 Subject: [PATCH 087/108] Doc: Document History panel replay, duplication and Delete key behavior * [DOC] : Document the Delete key, the broken-chain resolution dialog, duplication independence semantics and replay behavior with recorded deletions in the History panel feature page * [DOC] : Add user-focused release notes entries for the History panel fixes and new features --- doc/features/common/historypanel.rst | 40 +++++++++++++++++++++++----- doc/release_notes/release_1.03.md | 11 ++++++++ 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/doc/features/common/historypanel.rst b/doc/features/common/historypanel.rst index ffca2c063..ec71444d2 100644 --- a/doc/features/common/historypanel.rst +++ b/doc/features/common/historypanel.rst @@ -187,9 +187,14 @@ The toolbar at the top of the panel exposes the following actions: recompute fails the previous results are restored. Analyses recorded with earlier versions of DataLab replay using their saved state. UI actions are replayed by invoking their recorded method and may reproduce side - effects, including creating, importing, or duplicating objects; - destructive actions are skipped when their captured targets no longer - resolve. + effects, including creating, importing, or duplicating objects; load + actions reload their objects even if these were deleted after being + recorded. Recorded destructive actions (e.g. object removals) are skipped + with a warning whenever replaying them would be unsafe: when their + captured state no longer matches the current workspace, when their targets + were re-created earlier in the same replay, or when their targets belong + to another session. As a consequence, a replayed session may intentionally + not reproduce a recorded end state that included such deletions. - |step_by_step| **Step-by-step**: replay the same selection one step at a time, opening the parameter dialog for each supported action (object creation, computation, ROI extraction) before recomputing it. Accepted @@ -199,13 +204,18 @@ The toolbar at the top of the panel exposes the following actions: outdated so the chain stays up to date. - |duplicate| **Duplicate**: duplicate the processing chain containing each selected action, or the processing chains in each selected session. DataLab - clones the required objects and creates independent history sessions. + clones the required objects and creates independent history sessions. The + duplicate is a standalone deep copy of the chain — as if the recorded + operations had been redone by hand on the cloned objects — so replaying + either the original or the duplicated session only affects its own objects. - |remove_incompatible| **Remove incompatible**: remove all actions whose workspace state is no longer compatible with the current workspace. A confirmation dialog shows how many actions will be removed. - |delete| **Delete**: remove the selected actions or sessions from the - history. Removing an intermediate action splices it out and preserves its - downstream steps as an independent chain. + history (keyboard shortcut: :kbd:`Del`, active only while the history tree + has focus, so it never deletes signal or image objects instead). Removing + an intermediate action splices it out and preserves its downstream steps + as an independent chain. .. note:: @@ -239,7 +249,23 @@ Actions that are not compatible with the current workspace state (for example because a referenced object identifier no longer exists, or because its data array shape changed) are shown with a disabled foreground and an explanatory tooltip. -They cannot be replayed until the workspace matches the recorded state again. +Attempting to replay them opens the broken chain resolution dialog described +below. + +Broken chain resolution +----------------------- + +Starting **Replay** or **Step-by-step** (or double-clicking a tree item) on a +selection containing actions that are incompatible with the current workspace +— typically because the objects they rely on were deleted — opens a +resolution dialog. Two choices are offered: + +- **Repair and continue**: the broken actions and all their downstream + descendants are removed from the history, then the remaining valid actions + of the selection are replayed. +- **Cancel**: nothing is modified, neither the history nor the workspace. The + dialog is shown again on the next replay attempt until the chain is + repaired. Workspace state display ----------------------- diff --git a/doc/release_notes/release_1.03.md b/doc/release_notes/release_1.03.md index 4cf47018b..9f15d7bfc 100644 --- a/doc/release_notes/release_1.03.md +++ b/doc/release_notes/release_1.03.md @@ -16,6 +16,8 @@ * Added serialized and replayable history sessions with workspace-state validation * Added `.dlhist` import/export support and separated reset sessions from regular history sessions * Improved replay compatibility reporting for clearer user feedback +* The Delete key now removes the selected entries in the History panel (same behavior as in the Signal and Image panels), and only applies while the history tree has focus +* Added a resolution dialog when replaying a processing chain broken by deleted objects: choose "Repair and continue" to prune the broken steps and replay the remaining valid ones, or cancel without modifying anything **Replace special values processing (signal and image):** @@ -69,3 +71,12 @@ and Image panels. been renamed to `recompute_selected`; `recompute_analysis` now refers to a different processor-level helper dedicated to explicit 1-to-0 analysis refresh + +### 🛠️ Bug Fixes ### + +**History Panel:** + +* Fixed replay of load actions doing nothing when the loaded objects had been deleted while recording was active — the objects are now reloaded from their files +* Fixed duplicated processing chains interfering with their source chain: replaying either session now only affects its own objects +* Fixed session replay aborting when the session contained a recorded object deletion — recorded deletions that can no longer be safely applied (captured state mismatch, targets re-created earlier in the same replay, or targets belonging to another session) are now skipped with a warning +* Removed the yellow highlight that could persist on history entries after a failed replay From 12ef1e89a936b77ea7e56a1e7c6b5ac7ea41d65a Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Tue, 11 Aug 2026 10:18:36 +0200 Subject: [PATCH 088/108] Chore: Update French translations for History panel replay strings * [CHG] : Translate the new broken-chain resolution dialog and the destructive-action skip warnings; resolve fuzzy entries introduced by the translation scan --- datalab/locale/fr/LC_MESSAGES/datalab.po | 31 ++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/datalab/locale/fr/LC_MESSAGES/datalab.po b/datalab/locale/fr/LC_MESSAGES/datalab.po index 8c978ed77..1bded89ca 100644 --- a/datalab/locale/fr/LC_MESSAGES/datalab.po +++ b/datalab/locale/fr/LC_MESSAGES/datalab.po @@ -4243,8 +4243,23 @@ msgstr "" "\n" "Souhaitez-vous continuer ?" -msgid "The current workspace state is not compatible with the action." -msgstr "L'état actuel de l'espace de travail n'est pas compatible avec l'action." +msgid "Broken processing chain" +msgstr "Chaîne de traitement rompue" + +#, python-format +msgid "" +"One or more objects used by the selected processing chain were deleted: the chain is broken and the following entries can no longer be replayed:\n" +"%s\n" +"\n" +"Repair the history by removing the broken actions (and the actions depending on them), then continue with the remaining actions?" +msgstr "" +"Un ou plusieurs objets utilisés par la chaîne de traitement sélectionnée ont été supprimés : la chaîne est rompue et les entrées suivantes ne peuvent plus être rejouées :\n" +"%s\n" +"\n" +"Réparer l'historique en supprimant les actions rompues (ainsi que les actions qui en dépendent), puis continuer avec les actions restantes ?" + +msgid "Repair and continue" +msgstr "Réparer et continuer" msgid "Replay file save" msgstr "Rejouer l'enregistrement de fichier" @@ -4261,6 +4276,18 @@ msgstr "" "\n" "La rejouer ?" +#, python-format +msgid "Action %s was skipped: its recorded workspace state no longer matches the current workspace." +msgstr "L'action %s a été ignorée : l'état de l'espace de travail enregistré ne correspond plus à l'espace de travail actuel." + +#, python-format +msgid "Action %s would delete objects that this replay just recomputed and was skipped." +msgstr "L'action %s supprimerait des objets que ce rejeu vient de recalculer ; elle a été ignorée." + +#, python-format +msgid "Action %s targets objects produced by another session and was skipped." +msgstr "L'action %s cible des objets produits par une autre session ; elle a été ignorée." + #, python-format msgid "Action %s has no recorded pattern and cannot be replayed." msgstr "L'action %s n'a pas de motif enregistré et ne peut pas être rejouée." From 586c7bc315a6b6421c1fd6fb133674750e0a0f22 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Tue, 11 Aug 2026 14:16:26 +0200 Subject: [PATCH 089/108] Fix: History panel: render the missing 'stale' visual marker in the tree Actions flagged as outdated (is_stale) after a failed or interrupted cascade recompute, a reconnection, or pending parameter edits were tracked internally but not shown to the user: refresh_action_item was resetting the row background to the default brush, leaving no visual feedback when a processing chain was left desynchronized. The history tree now tints stale action rows with an amber highlight (alpha-based, dark/light theme friendly) and adds an explanatory tooltip, without clobbering the workspace-compatibility rendering. Styling is centralized in HistoryTree.apply_stale_style and applied consistently on item build, refresh and compatibility updates. --- datalab/widgets/historytree.py | 50 ++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/datalab/widgets/historytree.py b/datalab/widgets/historytree.py index b4c7a2484..fc422c1a6 100644 --- a/datalab/widgets/historytree.py +++ b/datalab/widgets/historytree.py @@ -19,6 +19,12 @@ from datalab.gui.main import DLMainWindow from datalab.gui.panel.history.panel import HistoryPanel +# Amber warning tint painted on stale (outdated) action rows. The alpha +# matches the active-session highlight technique so the tint blends with +# both light and dark themes. +STALE_TINT_COLOR = "#ffa500" +STALE_TINT_ALPHA = 60 + class HistoryTree(QW.QTreeWidget): """Tree widget for the history panel""" @@ -169,8 +175,41 @@ def update_compatibility_states( item.setToolTip( col, compatible_tip if compatible else incompatible_tip ) + self.apply_stale_style(item, action) iterator += 1 + def apply_stale_style( + self, item: QW.QTreeWidgetItem, action: HistoryAction + ) -> None: + """Apply or clear the stale visual marker on an action row. + + When ``action.is_stale`` is True, the whole row is tinted with a + warning color and an explanatory tooltip is appended on the Title + column (after the compatibility tooltip, if any). Otherwise, the + default background is restored and the stale tooltip is removed; + the compatibility tooltip is preserved in both cases. + + Args: + item: Tree item associated with ``action``. + action: History action driving the stale state. + """ + stale_tip = _("This step is outdated: replay it to refresh its result.") + # Strip any previously appended stale message from the Title tooltip, + # keeping the compatibility tooltip (or any other base text) intact. + tip = "\n".join( + line for line in item.toolTip(0).split("\n") if line != stale_tip + ) + if action.is_stale: + color = QG.QColor(STALE_TINT_COLOR) + color.setAlpha(STALE_TINT_ALPHA) + brush = QG.QBrush(color) + tip = f"{tip}\n{stale_tip}" if tip else stale_tip + else: + brush = QG.QBrush() + item.setToolTip(0, tip) + for col in range(self.columnCount()): + item.setBackground(col, brush) + def forget_orphan_expanded_states( self, history_sessions: list[HistorySession] ) -> None: @@ -218,6 +257,7 @@ def build_session_children( child = self.action_to_tree_item(action) session_item.addChild(child) self.install_description_widget(child, action) + self.apply_stale_style(child, action) def set_active_session(self, active_session_number: int | None) -> None: """Flag the active recording session by session number. @@ -273,12 +313,11 @@ def refresh_action_item(self, action: HistoryAction) -> None: Re-installs the description widget so it reflects the current ``action.kwargs`` (e.g. after the user edited a ``param`` via the - Processing tab of the Signal/Image panel). Also resets the item - background to the default brush on all columns, clearing any - highlight previously painted on the row. + Processing tab of the Signal/Image panel). Also updates the stale + visual marker: a warning tint and tooltip when ``action.is_stale`` + is True, or the default background otherwise. """ target_uuid = action.uuid - default_brush = QG.QBrush() iterator = QW.QTreeWidgetItemIterator(self) while iterator.value(): item = iterator.value() @@ -288,8 +327,7 @@ def refresh_action_item(self, action: HistoryAction) -> None: self.removeItemWidget(item, self.DESCRIPTION_COLUMN) self.install_description_widget(item, action) item.setText(0, action.title) - for col in range(self.columnCount()): - item.setBackground(col, default_brush) + self.apply_stale_style(item, action) self.scheduleDelayedItemsLayout() return iterator += 1 From 5b15c5cd059abd8710e884a4e48312130cdab652 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Tue, 11 Aug 2026 15:12:37 +0200 Subject: [PATCH 090/108] Fix: History panel: block user re-entrance during cascade recompute and replay recompute_cascade and replay_actions pump the event loop (processEvents) while iterating over session actions, so a user click on Delete, Replay, Duplicate, etc. could mutate the action lists being processed and corrupt the run. History panel commands triggered from the UI (toolbar actions, context menu, double-click, Delete key in the tree) are now silently ignored while the recompute/replay engine is busy (new HistoryExecutionState.is_busy guard), and the toolbar actions are visually disabled for the duration of engine runs (is_engine_busy: cascade or edit-replay in progress), with guaranteed re-enabling through try/finally epilogues. Internal engine calls and programmatic/test entry points are unaffected. --- .../gui/panel/history/interactive_replay.py | 17 +++++ datalab/gui/panel/history/recompute.py | 28 ++++---- datalab/gui/panel/history/runtime.py | 25 +++++++ datalab/gui/panel/history/ui.py | 68 ++++++++++++++----- datalab/widgets/historytree.py | 4 ++ 5 files changed, 114 insertions(+), 28 deletions(-) diff --git a/datalab/gui/panel/history/interactive_replay.py b/datalab/gui/panel/history/interactive_replay.py index a27f79376..5321dd91b 100644 --- a/datalab/gui/panel/history/interactive_replay.py +++ b/datalab/gui/panel/history/interactive_replay.py @@ -420,6 +420,22 @@ def replay_actions( global plan is deduplicated and executed in session order. A re-entrance guard prevents nested prompt loops. + Args: + panel: History panel instance + actions: Selected actions to replay + prompt: Open parameter dialogs before recomputing + """ + try: + run_replay_actions(panel, actions, prompt) + finally: + panel.ui.update_actions_state() + + +def run_replay_actions( + panel: HistoryPanel, actions: list[HistoryAction], prompt: bool +) -> None: + """Execute the replay plan (engine core of :func:`replay_actions`). + Args: panel: History panel instance actions: Selected actions to replay @@ -432,6 +448,7 @@ def replay_actions( with panel.runtime.execution.replaying_edits() as started: if not started: return + panel.ui.update_actions_state() entry_states = ( { action.uuid: ( diff --git a/datalab/gui/panel/history/recompute.py b/datalab/gui/panel/history/recompute.py index 408b35382..fdb08e355 100644 --- a/datalab/gui/panel/history/recompute.py +++ b/datalab/gui/panel/history/recompute.py @@ -916,19 +916,23 @@ def recompute_cascade( if not descendants: flush_cascade_warnings(panel) return - with panel.runtime.execution.recomputing_cascade(): - for action in descendants: - action.is_stale = True - panel.tree.refresh_action_item(action) - QW.QApplication.processEvents() - for action in descendants: - success = recompute_action_in_place(panel, action) - if success: - action.is_stale = False - panel.tree.refresh_action_item(action) + try: + with panel.runtime.execution.recomputing_cascade(): + panel.ui.update_actions_state() + for action in descendants: + action.is_stale = True + panel.tree.refresh_action_item(action) QW.QApplication.processEvents() - if not success: - break + for action in descendants: + success = recompute_action_in_place(panel, action) + if success: + action.is_stale = False + panel.tree.refresh_action_item(action) + QW.QApplication.processEvents() + if not success: + break + finally: + panel.ui.update_actions_state() flush_cascade_warnings(panel) diff --git a/datalab/gui/panel/history/runtime.py b/datalab/gui/panel/history/runtime.py index de55f27b6..31dfc730b 100644 --- a/datalab/gui/panel/history/runtime.py +++ b/datalab/gui/panel/history/runtime.py @@ -30,6 +30,31 @@ def __init__(self) -> None: self.edit_replay_in_progress = False self.cascade_warnings: list[str] = [] + def is_busy(self) -> bool: + """Return whether a replay or cascade recompute is currently running. + + Returns: + True when user-facing History panel commands must be ignored. + """ + return ( + self.replaying_active + or self.cascade_in_progress + or self.edit_replay_in_progress + ) + + def is_engine_busy(self) -> bool: + """Return whether a history engine run is currently in progress. + + Drives the visual disabling of toolbar actions: it only covers flags + set by code paths with a guaranteed `update_actions_state` epilogue, + unlike :meth:`is_busy` (which also includes `replaying_active`) used + for the functional no-op guards. + + Returns: + True when a cascade recompute or edit-mode replay is running. + """ + return self.cascade_in_progress or self.edit_replay_in_progress + @contextmanager def replaying(self) -> Generator[None, None, None]: """Suppress history capture during the context scope.""" diff --git a/datalab/gui/panel/history/ui.py b/datalab/gui/panel/history/ui.py index a9ba57983..4f60c32a8 100644 --- a/datalab/gui/panel/history/ui.py +++ b/datalab/gui/panel/history/ui.py @@ -4,7 +4,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Any, Callable from guidata.configtools import get_icon from guidata.qthelpers import add_actions, create_action @@ -32,6 +32,24 @@ def __init__(self, panel: HistoryPanel) -> None: self.setup_connections() self.setup_layout() + def guarded(self, callback: Callable[[], None]) -> Callable[..., None]: + """Wrap a user-facing slot so it is ignored while a replay/recompute runs. + + Args: + callback: Slot to invoke when the panel is not busy. + + Returns: + Wrapper suitable for Qt signal connections (extra signal + arguments are discarded). + """ + + def wrapper(*args: Any, **kwargs: Any) -> None: # pylint: disable=W0613 + if self.panel.runtime.execution.is_busy(): + return + callback() + + return wrapper + def create_actions(self) -> dict[str, QW.QAction]: """Create named actions used by history menus and toolbar.""" panel = self.panel @@ -45,34 +63,34 @@ def create_actions(self) -> dict[str, QW.QAction]: "new_session": create_action( panel, _("New session"), - lambda checked=False: panel.create_new_session(), + self.guarded(lambda: panel.create_new_session()), icon=get_icon("libre-gui-add.svg"), tip=_("Start a new history session"), ), "open": create_action( panel, _("Open history file..."), - triggered=lambda checked=False: panel.open_dlhist_file(), + triggered=self.guarded(lambda: panel.open_dlhist_file()), icon=get_icon("fileopen_h5.svg"), tip=_("Open history from a standalone .dlhist file"), ), "save": create_action( panel, _("Save history file..."), - triggered=lambda checked=False: panel.save_to_dlhist_file(), + triggered=self.guarded(lambda: panel.save_to_dlhist_file()), icon=get_icon("filesave_h5.svg"), tip=_("Save history to a standalone .dlhist file"), ), "delete": create_action( panel, _("Delete"), - lambda: htools.delete_selected(panel), + self.guarded(lambda: htools.delete_selected(panel)), icon=get_icon("delete.svg"), ), "duplicate": create_action( panel, _("Duplicate"), - lambda: htools.duplicate_selected_entries(panel), + self.guarded(lambda: htools.duplicate_selected_entries(panel)), icon=get_icon("duplicate.svg"), tip=_("Duplicate selected history action/session"), ), @@ -95,21 +113,23 @@ def create_actions(self) -> dict[str, QW.QAction]: "remove_incompatible": create_action( panel, _("Remove incompatible"), - lambda: htools.remove_incompatible_actions(panel), + self.guarded(lambda: htools.remove_incompatible_actions(panel)), icon=get_icon("edit/delete_all.svg"), tip=_("Remove actions incompatible with the current workspace"), ), "replay": create_action( panel, _("Replay"), - lambda: panel.replay_restore_actions(restore_selection=False), + self.guarded( + lambda: panel.replay_restore_actions(restore_selection=False) + ), icon=get_icon("replay.svg"), tip=_("Replay the selection silently (no parameter dialogs)"), ), "step_by_step": create_action( panel, _("Step-by-step"), - triggered=lambda checked=False: panel.replay_step_by_step(), + triggered=self.guarded(lambda: panel.replay_step_by_step()), icon=get_icon("edit_mode.svg"), tip=_( "Replay the selection step by step, editing parameters at each step" @@ -146,8 +166,8 @@ def setup_connections(self) -> None: tree = self.panel.tree tree.customContextMenuRequested.connect(self.show_context_menu) tree.itemDoubleClicked.connect( - lambda _item, _column: self.panel.replay_restore_actions( - restore_selection=False + self.guarded( + lambda: self.panel.replay_restore_actions(restore_selection=False) ) ) tree.itemSelectionChanged.connect(self.panel.navigation.sync_panel_selection) @@ -171,15 +191,31 @@ def setup_layout(self) -> None: self.panel.addWidget(widget) def update_actions_state(self) -> None: - """Update action availability from history and step state.""" + """Update action availability from history, step and busy state.""" + busy = self.panel.runtime.execution.is_engine_busy() has_history = len(self.panel) > 0 - self.actions["delete"].setEnabled(has_history) - self.actions["duplicate"].setEnabled(has_history) - self.actions["step_prev"].setEnabled(self.panel.navigation.can_step_prev()) - self.actions["step_next"].setEnabled(self.panel.navigation.can_step_next()) + for name in ( + "new_session", + "open", + "save", + "replay", + "step_by_step", + "remove_incompatible", + ): + self.actions[name].setEnabled(not busy) + self.actions["delete"].setEnabled(has_history and not busy) + self.actions["duplicate"].setEnabled(has_history and not busy) + self.actions["step_prev"].setEnabled( + not busy and self.panel.navigation.can_step_prev() + ) + self.actions["step_next"].setEnabled( + not busy and self.panel.navigation.can_step_next() + ) def show_context_menu(self, pos: QC.QPoint) -> None: """Show the history context menu at a tree position.""" + if self.panel.runtime.execution.is_busy(): + return self.panel.refresh_compatibility_items() menu = QW.QMenu() add_actions(menu, self.menu_actions) diff --git a/datalab/widgets/historytree.py b/datalab/widgets/historytree.py index fc422c1a6..d18823de3 100644 --- a/datalab/widgets/historytree.py +++ b/datalab/widgets/historytree.py @@ -80,6 +80,10 @@ def keyPressEvent(self, event: QG.QKeyEvent) -> None: event: Key event. """ if event.matches(QG.QKeySequence.Delete): + runtime = getattr(self._panel, "runtime", None) + if runtime is not None and runtime.execution.is_busy(): + event.accept() + return ui = getattr(self._panel, "ui", None) action = None if ui is None else ui.actions.get("delete") if action is not None and action.isEnabled(): From 9d4906a58cf14ce9ecb42d902fd4a9f285e89f9b Mon Sep 17 00:00:00 2001 From: Stefano Pierini <s.pierini@codra.fr> Date: Wed, 12 Aug 2026 17:14:32 +0200 Subject: [PATCH 091/108] History panel tutorial - first part --- doc/images/tutorials/history_panel/01.png | Bin 0 -> 35845 bytes doc/images/tutorials/history_panel/02.png | Bin 0 -> 26689 bytes doc/images/tutorials/history_panel/03.png | Bin 0 -> 140451 bytes doc/images/tutorials/history_panel/04.png | Bin 0 -> 249837 bytes doc/images/tutorials/history_panel/05.png | Bin 0 -> 110922 bytes doc/images/tutorials/history_panel/06.png | Bin 0 -> 142707 bytes doc/images/tutorials/history_panel/07.png | Bin 0 -> 125717 bytes doc/images/tutorials/history_panel/08.png | Bin 0 -> 189709 bytes doc/images/tutorials/history_panel/09.png | Bin 0 -> 316785 bytes doc/intro/tutorials/history_panel.rst | 173 ++++++++++++++++++++++ doc/intro/tutorials/index.rst | 1 + 11 files changed, 174 insertions(+) create mode 100644 doc/images/tutorials/history_panel/01.png create mode 100644 doc/images/tutorials/history_panel/02.png create mode 100644 doc/images/tutorials/history_panel/03.png create mode 100644 doc/images/tutorials/history_panel/04.png create mode 100644 doc/images/tutorials/history_panel/05.png create mode 100644 doc/images/tutorials/history_panel/06.png create mode 100644 doc/images/tutorials/history_panel/07.png create mode 100644 doc/images/tutorials/history_panel/08.png create mode 100644 doc/images/tutorials/history_panel/09.png create mode 100644 doc/intro/tutorials/history_panel.rst diff --git a/doc/images/tutorials/history_panel/01.png b/doc/images/tutorials/history_panel/01.png new file mode 100644 index 0000000000000000000000000000000000000000..caf1ac9d34c196d7879930b07e9b77d4d0d3ffb1 GIT binary patch literal 35845 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 IM6N<$g6zJucmMzZ literal 0 HcmV?d00001 diff --git a/doc/images/tutorials/history_panel/02.png b/doc/images/tutorials/history_panel/02.png new file mode 100644 index 0000000000000000000000000000000000000000..a111a24acd7cbd41b0137b48ee0b742632b8450a GIT binary patch literal 26689 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 literal 0 HcmV?d00001 diff --git a/doc/images/tutorials/history_panel/03.png b/doc/images/tutorials/history_panel/03.png new file mode 100644 index 0000000000000000000000000000000000000000..c27e0142c2c4e89cc9707a353a812863b90d88c2 GIT binary patch literal 140451 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 b5rT2YPLN0KoscVMQi<{l$n#>kx1aw9@m6ZU literal 0 HcmV?d00001 diff --git a/doc/images/tutorials/history_panel/04.png b/doc/images/tutorials/history_panel/04.png new file mode 100644 index 0000000000000000000000000000000000000000..352d342540230875127032d265f228757afb944b GIT binary patch literal 249837 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�qNk0RHuOyHkKMstH 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�u%bA1BE}V%i8fr+gMw2p;O(d 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�OfOm<|f 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�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%0A4UjJe7Y#EXWC2Q~AGXFrN~4 z|0HN56@(n+$0_l6oc*%jlv<;kOjZYC!#`4PcP$bLO@8w)-^%8+<%D)eQ*CgqGn~na zyR1qgw^-;u6+oSiwPz}Sm<ZlfTXo=(OjTNDDk}sq(GU(zl&xnUIQvb^Q4oyd6;)Sz zhf29XB}s1v7;Lk1fRHC#U?#vDn)7>V>i6`du8o+?3!Zu>XjP$wKE+Z5k)5I82S>-S zd+OW9N7DSQj5l9t3v;(1vN4YHX0r+kM{g2-z57+CIlG4Kd`qarKyT~3uimm(=I3L= zCL!e*9CKwg?sWI%OM~^a;+pz}2e=%a`9ec}ytqes%J-gjH=gmMjjEtxQC=$^_QYzP zviBVuXo*Psi&;@U4Y>=3;2M>$Rf#Z?QSbs>Wvq80Jm72?k=xd0Q9mzUwg7s#BJSdD zk&tzO$-O&J@@Wr7Kid_ljwv3pFm*+zM^Xw1nA*!16}G2iM73nU^iU^!y0n5?!F2!a zH#M!x!0wlVqApMvaFO)B*UqhOt%L=w<$lHKM(LXlOig|HZ&hq-HTINOS|HTVEQ{B1 z{p&%hJ0Z8GJ%8x-J%Ji;Q2mGp?4gkRAgM_#l{=R5Y|L_2UFJ~mzHV)PqV|4AVSB!a zdl%XH=TsK$B0D4koiY$39t?68#V-iN&?n25t6!J4<~vkHBVqsH_ZdxZm6!W;CsTj^ z;h^-tzz~vcQPLFu^wkCdn50H|=I-L*@3p;yxe;}-&?5@ZvbMR=tKs6sWaDNI9cI~r zqBd|}@8CEStcSiq8Et0`Z$PoqUkSU4u*V@KFV2cZaamB*IqP0r+uc{K$nn1JU{xAQ z4Yk-;H*jhl>8|h=kWic~_O>veU@vM|gDQt$VQXZZonL>Lp`&LIy$o{pp&Z(1uTELd zwj&S*2`)4B-_S+egt>*9!@u9p_wT5?K+ES+TI#AgonHs1S<}<MrY7|zLu~%KIPV5+ zp6WTgFQcVeWtf*49EFo3-iJzb%sz^N3Yi`=CIJ%UmQ2RdLjvi6<jYDpVDuv562g#1 zk%;4|??|Zv?k{C!;$wexb_b=Vp1pZfLD_lPvy<Vie_s}pY<)W*VP|Z}LA^M6Vs9xP zDqX?l)IxT4Q#R!#c*0VT58%bQ6$AZOeS`dK82of3(F~4)9nWz>0{7xlny-<T7PBQ7 zY&Ro$jxJPw8cMtCvy561MKpDHf(-T|(X*Muf#i!CtK!<)M3N}M{_Y9F_;Y0?pfhk} zpfB!=K!<jIsar9rOEZ;G2Cb<#gQ4&7@p`hd9SLKvimEsEB&+I?G(0KH-R@B&H9mpf zZ`6_D%uf!op#b(~>*Rv#YZGNMPXu*v!awmJ2t813u0%6EM2+!VSJtoS3?pp0RD&BL zBJijLpENz$;XGWZ*_a~_2=b}AdqyivY%IBm-0$~1<zr$9*iA8#k_7%uR3M8V+htRA zO;mUg3V57to?+*X*0`{M@y3CrC?zvt+?|jAzG1ZgovdPU*ye<klKAkk_`HuP5%f+c ziYnY(9AI9bi-YNm{x3VVqg*a{LcUDwCY%&##Y#TZ!G<^#fJn)mf{9ZatJ{H<mJDrT z;7$7ZT^;l0)rCmPumIT%iOb8$q6}9QBQnnqutgUIJ|FMax<#OEs#8%6j0n^W{kh#a z@isdD*bzRpu49h~wXQQ#`8E=TW%wmuQOjf>bM3ipiTXDP1M>28(T98QnD2{`)0WFU z{`m^|SL-o3&<IaxwO&+M!DAiQUAV{DHn#nEmzYD{SN%*m26b5(^O8o1<B5^IdMywH z>1lK~vul1mTU@hB-d|rV|JI&jLk>VRV2GoCHDs0lc?+pKIeC5JYn~hIE7sbL=><2D zI$z%XG3q4di3NiYC^rf#Ug%d+#~Kmy^@B<7b;5@4Kn~<7+wbeU3X=qSZ6*kBVlw3J zE3Lj<-B;#cUdc7NzoMeu#bavMQUBhOUF%I#!&12%)6RF;Id!C6cm8M%+6q3F9)uh# zdS4Jgt(yrhZ_cHyEPQSd({5gp__k!n<~4iS-D?YZ$QOaRFsbDhYAP9T9MjAua$xGs z#2T8K3Mb8M(c8;q*h5vj_aBOii<ec(U;>{Pr8CRB%8OBNt(3hUcyW1o^EQm0S8&7q zdw<bMwNRj3cHMY-WVvK%DMz-P`{F!Qa(P&v*eoB+dH?qvi#3ZKzo?!NTze~{6j@oW ztH@shzdy^v1?$O>Ti{bXWTvEaJ|L{3s3$9(|G4_u2zS_e@z@HTiPy|?kz-4(=`}TT zvG=AS*ywI_;GZ<^8ms2#m0LzJhYu~ECM|w`eWvTZq>jg;(^GTmEvmp7gnrN^^yvM5 zqIh6)sU>5$jyB@CuI=MNp{iDE`||YB>CdUc<;DO%FT?I^jP{!+XKiP*tikR=9o5nm z4Z053H@1$~5W`N_avN8_t%uEx+qo2@i|qf23$Y6W@p9L5D4x);uf)!PAlY~~m#Otu z_S0L^^?k%PIDeCYJt{z2Ise}B*beBS`40~s1`}M{f4`edNlXT<PhZ^TD6kp4Hkamf z_3~ZPXQ|h922Rp-9Z$sik>CUSnZu~p>pG5Xe^^?=LByMN)+z*KPSt7Uqx3+@U!^$V z^F!I=(-H2f-!T2^dCTjMpoW9UPAOjWR|Modz$)_S$GmQ*56KXLcer|X)^|=M9hbqb z$h>YZv!oP*TCn+HYyL;7VrJH7ZM<nQmpXrD%DGgJ4T+s(CWZW|>1meeIYzhDr)g5) zrna84{CVM_SgJig0k>wb02^Y}`z!oyYi=-MSY4a6bc@OtLJ3D0Zv)~YP6{d*|0+(K z`eEnQ7IzrM1?L5@^b2cwGP+AMNoW!`??aER=kzV-J9V@pD?D5rmAabrUo~e^R4+L~ zHV&IqGX8}}q2FlZrjEyYUfL{*Ocko-aZde9mYFI%{F*W}UNE2){xqDGoIE!^7K6`I zbwWz8sy^tSx7Qd@rnJfGm3^jKn^qs^8V-5rc5b8AN|K6HF5K7tNekyw{POn?(f>#- zV!+L2&PW%31(Cy!5SQZU!oim0ph*T5n7m&Ux@{tH6cl2?Ydp2um(|0EQF9vB32<nU zS=Zizq^G)<e9PBM3xfx)!zO|mhxWutNyoa{**UL8MRG_`!d~$`rvSENkBeW|VR6Fd z=BggUhJPRK53g<vEo2BxMo=XS!35X{T!hg|OM<av!uAc^<6~}3PehHwI@)Hd%ChLZ zmQY(I&Y%uGor-zgZ!eDBOgc88cAM+-f08D~ojnA|@hqLLJZo<+{+NwrUJ=)~0W9UR z?N7-aEM}y1VtfI|mZT=UySr+nRn#q_Dd3@-lTGEaZ1G?uX?OlFblXwiwaJ;w`tkrV zDMp#qR4Ak@1!d5yYNV|%Cg{>&ePzkBR2Nr?GeXm2jAx-Z?eX)=(F&dfI_%)n?JXkJ zvid*}Wuxzib?mt@qdOw|>%aF#kG!R%B~p<mc=v3;{-;i2)1lAT?;#-}z1m4!R)iBd z(pjL)^5CvwRkZA*)N~yzw7N4*@>u>yI3?M3ePi|UOd(mNINPkPef_|0!{-j$&uRB( zO6cVDYVUC5@{x@eGt0QHNt;^RTR9(WV+s1}nx#+sk}MOIx*rSVoJ$Uh2n==ZtzIyw zycoUe>$!Tv7#=55`4)$KA<}Yib3~AKep0Nq5JlA6n_q#ou_(MdO0avdmrAp0&Db?N z^Tot|4lmx@a4xP@`ggyM*JM|{{E4`9b8@j4OyQ+6BO+E<-<CTNboNIOu?kox<1x1{ z7MRFy8a|_BVj>4F%!NjW3pox#^cA(T@X5*F9jY~Mkg*TX9!&;ZQts#CO=HL))Nx|_ z#gc15{^X`{W`tIyk{8v(XDD&jT}Rg;o#oSak_kW99r1$(z9qpZ=S6szhi1Hklg%bd z7nmuOruc?<%{Di?;kxNMf)$R|$g1Y+@10e;%d*}(SiV=KC>MC|@W{trP00{uYsC~< z>DbVjGZWBYqvLNe(|t=7MV6o679IBu!V)Dtqb)h)Fk+DS8g_z2tfrPIsB@=|%SflU zQ3^Y@DtJ8AnNIWZE@-0&)Sp41?E0*GZm#*IE0Cdo-whWvpgT&4rre7U_LqJzJpAgC zQ&Y{4k~^x^oUfsLhwSmKS9{<U+^e7-w7q4QWv?rtTNIOzZIOe0$%LtMbAc8XSmg~J zadFuwL?X5wulpa*Xvak&XllK^JiRQU>)k(XY#iT*-rVCezX3~cyRik^o<W~T&@)l= z7g)9^C?6Qhp-G+N4IHTU?~yj0*u1LWR4RCP-G=^-g{7uMu5689Njoy@?Q%0$c8-4S z;xRnm-wZG3t@6CGL2=*Mwtyoa<Am4faj`2q(-9)UF}6xX4l>hIu--nJ@!1dvU(bU; zGNGLlU5?#B<NARWJqwG;1n10n<>-Trc2`!^{ET&LizC63LFDTMWC&;1a6cns>yi5! zdQ@P4zb!5v%}XmvPR?Up8`0*9TThlgRumZmUf)A4wrGYCp-}&Y@O5Uy*CbOByUlEo z7R>x=YB3b{onO^dFnLc1veR6dc}JFe(`1|a7K}1ZuUFAsH)NMLhU>Df=39}Ji!}TC z;|f%D%4}p=!oZ0Vy9JG$llo$4V=^+xe3}ZXrw?2HiWnJ1+b`HACoogaPX-o9Vm@?9 zn%=Erb7?s#H7?&EGwbd)35B(k+{{2Y2EAz?n!jWh<C!=QGxyhXt@a*aT3L6W+_K5b zixKhRjkNk98r@w`)q0blmAr8|TzWZO=w};i`YvROxDzS36eYxR*#U#9)(8?b@g>ia zs5rBoBuOAXt!QmWKJiCBc5z|*;NaU*d)&?!QIUm=6im;h2K1o;=s&%VxkDx=XSuHm z3fLBwxVC)G2wn$q$F=UT*g5S+7Ff(&4OuZ@bVesjWGihNW;Y9xQ&t>Aa3jXW>E-;< zbLSU^d!8vR{Zf)^;xW-rwGD&w(Zg>a{a&znXmhv31PTYb!_-jE@AXJkLDC4p{n-c= zFGwA-%!E`THUzA4^eUK&_B^mUes!=f)CBt)yep%B7|$B`^*bV03~eW9JgkSQB}1lX z)+8h;7eqF*A>2Lb45&wF_#ZB)Z<T{wT>wD)3+c%Tpr(LkK`vV;4fxn0`y-!?gS7DG z*SaQZ(EY0TNPmivwovnI_YPNYu?!u3q>?b*Ro*cf>5fZjp!6u?{c&`C&Y~q@I~3WP zi;JM!^}<=13h8xiJr3r){P*n(3@cOJiJFqG7X4Sljr_#TXRgjJwT&-K?11u&%F%d9 zy1gdTmXs2Pi!zUH<+}H?_j1XDMfq(=L2aU`6;nYFDy^b+B!neFOo>xOqCYac|F1;q zt5+{)N@(R(f(tC(eEOrYb_-RnY(|rUklI$<c}qnFuLPm;AS2n~;ljjZtvGYDp2JEP zxv~7jUP2hc#N2ozCmsE%`TS#kOQ)FLU176>f;<<O-nGHpACQu8@#cC2n5LMU2nS4; zA69Jgd=8tg@GJXMUml?mN}bw!EcK1XGu75RQ`gv#wd3-^(`GrH^PJe1-ANx0_T>rr zHkd?lZ4p{YRvW=|%JCm_!;Zn*0Y?rqznG@7iTLoB!STf*x^4naaY@aHjj}R-D<LyO zhni+ME>c(2ae{$Nj@cN+zZDnfjDQ#lip=t2iW4Oaz0;JDlY<;ismBfyO_ytGP5UY7 zh0}Ff%ef<Zp{7-er~dBXi)HO$ohH%vU!EfGXfZ@=hS1C<#Y9BZA|aVQoJdmO#$|(x z?MyBU&p((-(uovEkSnv!8k@C<6{U5JE9VRImHsd@LGId2eQCS7QSCP2rqT`_u)|wl z<GnEj$w>cOfbh-^n}9X2fF;t=1@_N3i!W2mPYPGQcQ$al<<ivpzLxZ9?1S%DH{OHd zMQnDb_Bh<ylT$P8DSDoyG?EMt%Uc_t;G|@U1E(3-_Hst+&Qu^cJPOzlBn@E;3p>Lr zghGwr1`n5oCXap9HwYkSVOo{iI0gf$#Lxtje$H;NX2F~9VMMSaIvSH@&HU91d{Bof zFIN6U*SnG<jc8Cwy>n@BGafoQIo@c9I5e=2lJhq=!+0uh?3rpbtMWwTHFZ`*1dseU z)@JHczEV>Zt8Mfjoh}0Crjr1flouIk^`i(lYMSELI;7<1fpWqH7Oe6L21Z&$Y!ef! z_nM3Ku-;j(7e9!Th}GtV@10-kOfHAR&R4df2_G08*fq6f_RqGDA3zQu-Zs-s#z(^z zwPqf>d7atzw(WdZjDWq9*@_SaYpI?SuhpS5KvMd23%0Yg=>3cWj~_xp1OAS&B_q@0 zpv`47DX`kQOY9sgzxesY+gdZoaHA$)0E==xkEWbofrZM`2?DgQK+^8c1e)}1>B{rx z!yidoLnADDsIiTPa!}T<R<!m%IT&VjG>XcwgXsucC(h_(^#uX<&Vg>4u*qpXp0wk^ zuDlk+4g+|_p-IJYSyIWJ-st0Hl1$Z)d^`j!ZD~m#^BS>4l|?>n8s=rc9P!P{OW|5< z4iceIg|QB0_{iLtVec_sPjU=~OJzD;z`Y&&8uC@1cgfTXE@#9WgZ%tz4bgfYCH@PD z8k${QJoXOQq{F6|`2}4`I=Vum(J>K82OUVS_QU5=Q?F8MimYm{^d)>wVy<q3E|+MX zu56R>SaPiA9YKHGK!ySYs|B&j=Jc}|SsH^A!*Cpyv2Kyn>ubcezR_uRu={NB-t-JO zVxt<kHWqpBG|Sn_3unVAPAdsVdZOKUZ@J<5To7dJJF5*cEE9zYe11A8A-!$5`2}FS z?dM}s$d9kv)2eDS{O!<c%;I-F+z*OUQ3*SbcW)SQs0bP8@be3522#AQjZS_D@9uyX zJ!h9IM)iA8zeAL4^~^|DEuO?tBH|UT!zqHwJOMM4L*~9rZ6mRXw_vpOB0`*Hn>iXr zenA*~<=~m)CyjyC`>gZx*adrwcKjg*<rR|mF9!~3<u$@gTAvN75=?>kM;GuKb9g|y zH#Hor-`;#gD}6(%Wo3RJn#}afXAX&p%rEPm<<bhG5frs`fnsqasg*B^{Hvl7bch9h zBv<Y3$;bWC0023Xk`nH5+{jnpFf%Egl!XX?shLDYPR>(Cg73-#v#6ls?3%SnyCGZO z;n~El-u8EvJxghZ<fDo#)Qbf>sP{24;ZODibyaEahCOpDrnVt!;d}285yV0*$?ol3 zg@;@r%oFY|I1*j>^oX;{w9QmU+&9?8d2egI;ew#JI$QJy{yy9C&*&d6xY=`4WtX{g zpW+Ec6{oNODIaovH5a)9yV2;|8=o`1yZdGd=EpiAr_EW%Qei_6$IS;9Lrc*hbO!wP z!M--6E4C)O+S@bgT5G20`u7snjnP&<R|btf**S!w%3RM5mb{LL1zI1xZ|?z+aehe) z_gp#Sz28ywKE4dt&I`4eDp91_C?uaww;1%-raov3!ixTYhmj9L>soAh14HsS=(qjy zDhMi_X9yWyAOUQ`0isOh4`CTeZzwA!g>)ofq;km1mnGjX08m&q*y#BQS_7R)sDH2d z>YFej5$lAPFcHxnueKI*!<~f^Zgeu?g4fL+PHOngy`s=%qgLkJb~rp)mb5oY39Yg@ zU&P)3bJo8lkF{kp26Me{d%Gf)`IwZPOk9UX)RCzRfo_5U)YRD#gkKiRjV?OKx3?7q z?l}&$n~tOtePNFJIj(kw##s49)L_>n{ggOGx~;7anVf+g&7qUl*5j?|H1cSV<Nl%{ zlzvySNFlEhRq!^$^j#o?5BiWA_=$%dVz<6Ac6QvO$p28|`k1#Yd-|P)RUq9}V`x>j z59E})us7JMEod$o&BA{R5Ul4z8boEm^Nen6UFx|jgxuWooSy8-H<ZCEd@|Co!*wEe zI5B*o<1L<7h|;m&W^PVZ>dbU`Zz($E*Ysy4J46gVudpD*Q%M!oBJsGBrS?8&xAq{1 z?Buj(Nmprc`1C)9CAMW|A=sx?<u$dH>S%aXyV*x;cjXz#Ko7DsjJ}t)(kewOh*c;m zGvgu9s^tOqAiXJ65y~C(L@06aFhho#X4SK+UyB;!<qUk`!1<n_R(R7R6rw!y(`R5P z(V9E@=KY`|ALVd#f+STuZ{5bUhS^o={))nYr+M^uBw{x=LmU@!RdsWdk3ith$(=im zx@O<28`GyJ^+>&`*>iidYcg!OpIw1asQ#@Y4;kS2PexEylm<(~+RPUWgnwp`AG2)x zuMyR_VSgp~n>-A7(l7?_I3~tzjZLus=KXTJwg=noRjbDy8^>U>QG%1SWS9}#JOwK1 zitS2%K}U4TX8@2~E)RI@?N_Pwi*#Fu8_n}_tv4ByH;22_R82E7ii`po7}yrAKS3F6 z4X;=mNgEiAei3x6ZPdzTg}e?>h1u#~PpQT$EowmWJUomWo2pDJ$iRfH=y~<zma7*a z9{nz7e_=7bx+5=a>wswdju<@^iw`gI%rSFlsF0W|brY8XAufJ(dokGd3-9l7c@Vje zABqna5v`V_Y}Z5xmpwB4q1JGvBU)A@);jMa_bflf#UVP#9I*6l2wmn56Q`iXhge1p zFFZy@TJfaucy6n<{Yc~GU3n*EgXCn>9O|;dCTy_ryXOApIhWSG72s~qa2{_|4AZ^1 zVDsuyQScKf{uQ+Yk!~2$F-O(xw_cy&o<ihcUzf*V8Ar(#ap~5C^!8W)NZiMRHYOm! zCYv`%*-3Ne^hoA8GDLzz`D6C0ELaf}ZBk?P_ha2bt{BDCJOueQ5dN$O<Ab_eYlL9C zbwli;znxQ649f2eABhlVH_Uc-5ml5|2Ztg|tVPYuSC>nsPsiguAC2kBJi-B5xqw4q zY7=h}x@bm(aN_Frq?W~h!;Cn1=K?jn1V<4gzqks{?-)gr&taU;l=b&F<WNPGwcbIh zQg>95!td#@W8GQ-S9ntC%Cb-~aKi5zT}Nxa><)^9<$lR+LsM&nd{C_Qy!UW^YWTtO zyy7`{6E25>7@;e@eQhDHNKk8t!1Fv%OXhp-mASfY*Vimjc-`e6hr2wRF6vO5{5FZ% zBj>u62Jjw&iZa%GC4oxR!LfCanXjI%YZDMh0zZN1NppB}_?7QmDLJ08EXw9>Z~f`; z)}{gc{*{`Cc$+w8G};rByOuCb94N_2?I0<M{W)#I`uWDN^gg12_pmYJSg+_sECu+$ zOK6;mAN-YekeNrRAwq#GXeOm(LN$>=1KTUr%?;n0yE!y>?O-BBEY1tUt*ISZ@XNO{ zrn?hz9U_ciO;<HgZ+uXDywv_UXJV*j&lUuYfE~|LV`=o)SNEq{x^8Jz->qy07V`V< zY^7(d$7`6~9ewsdtG@FjuB!_i7+{l%5tA+=`C4Gn8ok|tB)Z4;iJWirM~Y-^`A<^^ zNZU{fLh-V1uB;7T>D;VuQhX#OB<8D`S>sdVF<Np3T6wi^6{Ws8vTr^YtYlO2rQ}2j zQW$lHxautD=gL1GG+YebR61ss@zNGN+%x_@-(}Nc{#0h!E2hN+jsmu~HU~!M_9>>B z>93tW+Wdz@2S7T+__nF~$*viGTR~YB#zPe24Q|-?cz0h6IrGjc1M%vEZ4a?6E^cB{ zQs6*8SRzbKi-ZD8%!NjROu0;Np~yi?3Z*#bzB$rG#5il}T4$#8hkJl!X9;qP{NIiR ziAZHU<@h1pC-}#If79JxAHTX&PRTQ8A71l#;bN%c_N8(0><@NPNsp8`wNs~^b1SXY zBRuWK(fYw0oJxW|K%qG^VcX~W&(Cd!-WpAc-F^(~m&lZk2$ZPl42bb1VJxhI+`b-6 zksLNk(5uyQ#`|rCHLo4HT~>h@u*<!2u!uY&cfVg~-$K>_YhA2C2Txj>e2=dU(rbQE z4dhpWh3(b&-rzxF<Lr6f@Gv7WFP5k~VRR74rA+9y!bF67@c79o`%?eHQTW7kv;qn& z*x*z=BmG|Ggi<<7hbSrm4I|X#uxhYqduROH=rjqs@yljazXA=FPk)RM+r$T!17Xr# z=9LiIwVrpJai$8`%2ZexJ`h4=nPdV2;T;RR_4U=ArL>zQ$eicmd7wn~%E1)2iClCO z*__(bL$(|~?K69rz>Vq7l6MM_C5!L)8v|Zb4<gRF4~s*XhK4^aR))svb*y=%*3~Hr z-CBAw_iVB#V_BJZCS{1u=Z*0=*xTa1Q8?-#o4-Fj1(Zd0zE&a6Yuo7Aj&_Df|0p>C zq+(hEktk$~4>v0OUbm}2myuVJ2Auo}d*6Nu_&7K#a4_B0*P2{){4397WsIZwwAhRB zUK*n+&vm`znC&9oAJ9LNUx5GFuUF)GpR#E))(3Bw2=#l_Jo+9kd$af?-OyZKdZmeK zv)Blv{SV4|8{mtiNQO-t;XvKJmc1_Jw6#fFqL(nx))?t2H03@PnJwe(-vkHSdY}Gv zT`4r*R|n|1*4;5{Z$ssoX=;nF(^k60a_VqztNr^j|Bw9x15a17K=1<F5C~H}NA981 z+$&M{aeIRUf9fn#ydVqPfj|<8iv##z?rIl4<n;^1yM07?AA4@2mK)CK6Z^k@uXDpd z2=6W3a&`b<rLb(EJ_m)M{eq<>`{AB9(JWt8Fhd|%&kIgO0%=Ic)2~KHh(cQWqS0b| zTUcHm!HTIPI!@fpjdv>kOLqCVpmN(=SieN_g7s~Vg8}8k-@mT5<?atJ<bzNm$uv6F z$i41d&GA^eVW)bpUc}zrs`WqKnfU+FDC4(Iu8D&UGWgo!n^+fnIY2q~S3WpEhM3=s z1-&lR_0<(eEcSo#{h%o!M@eV=>fsjO%#6c|Da=HMOHo;m6CPw)L2Xtt27JJG5zvCu z$m{>$WR?1gSuq`uE*`Ty@(Yp~fnRAMD-<wVz0WZ-xw<p|3bH8L-?iKd0&{Eflxj{W zIJJN}2ZBSu9>K{8M%F|9)OB9B&8wqKe5@_Tdo;;_4UW))g}R@2s;!@I`yM}%ULcB2 z_=bhXsP~6!L&p~7{OE^K4m(2=Z01D?Kmo$41v`T0cTZ+b1nazfnyjyfX=)BjW;W7l zAB%jti*NQ0oHEQNOb;fA+VxPPf=^ED$9vNJedgHj05ZYB!JudQV>gvh+i)486Yz|< z*)f@6|B#XS%|;n}p|S!c56KhIkZ)A9p`)(#7C2aH%6F+l0JtBN1}G^5j60|rz4*px zgpAFRB2$SoA83f@cma<um7hRRQGpE(WzFefF+)W*vZ7#(`^v1+Ae}v4>^s{o>B(MU z6;(m#0?wW8j#XOPVW)C7UqS(L1%K1nm>L^RNl<&G@Ttt=Q}*BQV%BImBf(RXfk0o% z`2(Y8&dF2~@u+PkRnfzQomdGkrU#Z68~@eHtjwRf42#793b!f@;kO7M<o*1tSm%Cs zbhMdC+<Rg}9eXw?sjKhiiIwxS5)JNf<}VlLtdubywgENOdRCf>hLRgosUY+Fq3JS2 zQ3cjJ{M&5+uf0ra2E4Y+bEm}S@T+TkmqVEis12<qH%LOUkLQ@xvS~;k)<ntlz*XY} zf%I$IxS^p$GqZJV57dpaw|04s$lX`Riu}hf0hNdd!;AJlQEgY6^5iwcg8E$YwO3Us z*0?9;%<YqFDw&x$*Cel1v*C2Bsp9XhMZ)vkLu=Lst0fWO8=SM;_6Y|o9nB>r*%TC9 ztvV5^iz)~FD#AuCir?|jQH(#Q-=(JzZGJbkF}03LA|khoNIm2kgvyX(?txqMu<!;G zeCBKz2h1JJ#_GfMHA=uOM(vZ+)BT@bPELlnxG;Lgw_tO9Z1Lv1x!e^6@4Z~-?nTeZ z2G8kfAJ4sGW`^gB4?~X+qTQXL&ULM4j>Ot5%B*7Z$(;BsEuVDv)j^#5nUN8-?Tl?@ zNhQGj<{5x0lam-`rmetSLdy~b#D|BC0W<ea0z#p?AF+OLbcDP=M>nMt2?%g-aHD5h z$Y9@*H0S03Y%q3zZ~QhSDLx1nDH=0$ly%E%T$Ug>w{#TERaptvKSEim2bZ1|SzZxG zNC;FJF}hybMk^v?5t{4kYn-!xez>7O5~ADs^*RtOXFtdsE+q<*Mc=q<!b-KKIcec5 zDsfyg1QC0<F6S)}STuc;l0v75-`*^FxZa$R%Qusl)T3AYMm%H_o!I^M*cDX)Dh&Xv zDZl-&>H9oTLK4x6j{3Y4o7HO@{8EA*GFjb@*TiZBJSiz`UIh5sEcs~g%B;Sy3s&d$ zmxUjE#k>O2tduk)O)cp11>9GAt09HuIZ~k`w}~VX`n8&%8e#W^lBc|U`#Qs9+i67L zNjkmKr=}AnBN@SCZ`W(cHk3xazIIL$1vD6f^CBV4)QJ;7bxo~?)xrKwIjx9-Fp@%3 zUcut_PY5q<t75GNN1}%EXT&6wa|8}elyKF`-iq#8p>NE9mt$28f&<g?-1^1+`TG{^ z%a-$zS)~ktrs3T&I0l?<DRFXe|Mm<K`v{Fxc<k3l*9I5bMkj``pIGHAEvb{(B0V*n zUV_BZ(#O0~r(o-_7e5%I)Iih8xTtY6CO+!ky92_bz+;L5I0MBLXRW=%krN$-yaI9= zR>iX*Xu!54rTUC7pHP&kmH-g5JYRi#IbGBhols*yHa=l@b)U#Y;Log5I9LE4bTh}s z8yk=o-o*y&BAd?Wl!`SMmj>~^0cy?ah!auLtiy~)%c$rif)U~2x>b9M5?KQvna@-I z$r_vOpoy!6K=$Ct+Vwp6N)iA_ASlx%@`VU29$+Ks2km(S*2bTd1PJgGsoa$pzRA!1 z>C%DfSa+^W40a$Xdj6t^t}A~cfnedzj%$)yZco65?aJT~_5Ky+)f0u1L0g*r%-T8p z&8tWv>an@lTB~fjklH9wi=IzNh^&KS538;${Jyom3Mbt`#`4hRVGvMdM3q<t)|;1} zxoO=wyUm{uHWGRUV1%d<s=qOm6|i3kcy!kc?ac*<8Q}u#N*6A`|9td5*=FK0V*8mP z$&`>bJJiy&6%$zoFV*!0j7b9!jvs^(`Z+oF&_i!g*qCTfkNDEa;{T(1eTPTScHUV| zY;I%rdVw*^AJC(-(9ibSWAwc--4ldQ%PqR5a+#XGxmVE|xC=5iCyWda50v-m?7vrw zMgSP`ms#5<01~o^U5Fzq727pxu$HPLG8+!tU3OlE#GO?5fAs(JN0I-oREv-$KGY1< zVd<uDJc=Qr+N6L^H>Bo{1XJ>bi8-ORRqX<i38(`EEo1xJ6Wrbg%Sj0!%yctT?jFzI z{<A5UtlZqh$}a?DiE}$QGAcm|RYhfuk&#MWA)vs+h3}o5N-(7WiAz+vFyYP`_f2S= zGpg0%_YKxiOK1=!_e?rj@o%=@g%+jRFJ%jKnLqTewBg)e_0%>vQ4=Cys5Z?rlW55K zbtHVu{!MC<uC-KpK7y>GsQY}$;5F8j=c{<5G2ol+z24-0ZhN^S?mB=6^xcbQlPl*~ zCoAjf0j>WPY*0~o%GpB|XF9jMI27br9qd^btdmuW+FL9M+E9r=$!YHtW8kkjjDF|S zg#RnURK7Vh8D;2Pe$fD-h(7mLQ4UQ5hq1JDBS#kO7)!H-)P#{|uHClI77vH2lGk%v zI60YBLH-zx&@e$`FOU}iccUBjw}f+YA{8nu?hmIK&w#Fjt=fRru4muuhU><?P-@U{ z=15UiC#O;Ql2$q@SS(HJgmZorV<eTMQF|~J=MyzGh%UBQ>><;N2AvY}aEaD6_s>2U zzzr|(Gx}ghF7OYckio2=$DO3=zl_Mt&20^h=Y?7}8h$2yo7#&SY4`_fx?J2KGl$tA zgZw*DX~;&`LyA4p=xAuz30G`p(DU;=BFr?IJ0a+D3n(UQg9DW68WxY%5fR6SHL%e8 z1G5XK#91dnP$=NQD@9gO!OkzL+DaYl4H*(m3Ee*b=`{8wJBmp3k@pY|oU!K}t<lLM z9QfhzyR0PmXt(o+;9ahqj_m)ebaO*A($bKaueQZ=BG*(4&GmV7)#wjd>$|_0x)Rbr z`_NH1SF2GZyV={{c>-_iM3*^GazG0pA(Hi@9zPF(m1*a9k$ox667FU#NizqRWs=7x z@l8-d-K4(gAc@}DxjNiEn2Rx0Ft8jR3v#_a@%q1HD_qx}had1XMX+Io*O0sQP$~Wm zp4U-z5k|TEtt7bzR|Y!5;PYPPKTce9ep~YQ_Mid1bvV`1vT_SgQo192@ycc>Da|MW zo@vg%qILL!m7ml+w*_P?U1Q_%{pglXXwe7X`tc&yNK)ShjhZW-oE|tC?nr*1CfM?@ zPD~(z?cT8!w#<X(c}*SJ$PXl(&Whbst*|u$N!+R`d}b3ygw1wak5G<VyKJxyL)4W< z$bOv8i0Yy;ky=P)^+=-1GW=KOIoUvl2BNPm9xj$@8J1`~3C|O{Uu@v^i%5Brsmx4E zE2y5N%$+rdGG6;~M4RPi1zW7QYrqUe%=wG~|Ly#w;i0GzuCX%>W{VJMwkcq3<Nyl- ztJ&qhEVBoD&I9X<!=?7c3R>9y6M_f<yrH)j)R;??;f~9TA<JIqKvP$@83}#^dit3y z@sHEWP#Mj#jz^ODHOSid?@m|1eo6wu4@XQu5IDfF`g|B~IFlkg7N?xKwiV5mgWJHZ z3DCig?M@{{;mW!>H2djky`1?+vRE!>#^{riD_%>vqYmi5i_*0FsrIw$*27$a0W=BW zPl$fM?u}&s;P7RF(&v;*bp_Cv52MORnjH&GIbe`^ij`AL)h0rf%Y(iG+w5GZU)`Cq z17rQ7aLPSC9i8y*9xwW5Bclr^R_6#n0<jlLpNlHTYgt$2aFMS#PPSiPfq~k2Eq&fc z<oNAL873n>YFZHuE{7ySEKEaaKe}INUvyxegBTKWlj3%e-?DaOH2bms1BR%zjHiZv z%V$?8*Fuwf7j!UoGB6mCeV7OCu&f7*nWZKm=G8T*z9E1y<Aj8u+_-Wvi~i$kpFQum zY<zrgyu|NWbPmmQh6kzB#B!^YWEG?p?jvy$-;0nUwXF=<DB6tDt!_(_XI#=DafGr2 zT;VI-(x4gx%qm#<dEu89eW^CE-Xm(_27q;utQ+F?23UHM(jp!wWI;^BBBc>GzG1h$ z+(j<4P(0vVem&7?TgR%&T$%|AA>`Y7#G*3Hzkg!!3%Cq&Ck;-3jdZ?CPRE1z!(pff z*bu1XXMp}P|NF4;|7W!)ak}deSh^Ww>Lt6+Lm$(E{S28KZ0$?qb=U;mxDFt{6cqL$ z^`IR5d@uYLpcv}(!|m-?jp{{7bosUJ7uo-4U0??m%SX}#?6KXlf^B^NW;>g$xyN*W z;4pl*X*YB9ISIXb-?2ths?S^8p6RMF{|_4>A#RSq4R92oW*2HlG>E$Rr%0@xMjEAh zzuztk{sk}%+xP^lmNh#~n)v)bx#PMS;yT`!+zGRPK0gO4BW#vGzF9ox-$jqm2Sy%( zCzVB(*62w01rgZYrEoz2VFB#$8<hx@PuXny^!X|v%F|VUh#Ap>wUoK=!X=Ge7gYV; zf~pmtMqUn~iZ!XoyO5-$xY3!Ul+UJ6XOxmR9UJ8k&I+ts@Q75J8UY2ret`1a#1=G~ zjsQW|onPwxrDj8+#b>z4RLz|w*MP}2(Vy-Mw%>hDi2y_+mR)Y<V9|*LuA5Tp`^Z9R zA8ZlE0^C-Y`Iqi3XZm+d6I&gi0)$QhH#w3j-hTvBZF?3usmKSVckU3{UoUgUQ)iqg z_y)2qf7yr}GM@qC2lYsjSYG$*leC*XbPxJJvtV8eS5b3C+8@ZJPfNHJzH8(T*+{A- zlg;|OyMg$zjf55{ZKIKqf6H>yaq%dJA0UyjihQPtN#c2xI3ukj)I3^US_la?JxU94 zsn&~#Gc)@*_?#2tWyx?LO7z~%&p7jUe$|O;7>RtA0<wL<Z}N0<)7nLhh}HfP+WCdS z8QQeaBt0F2%-<Nps@uDGIV_9JWAhfGi1HH_@PrybV!-_Su7+%~cZ7C)R!m**Ie6KG zn}g(sK}4(zq?vx3fxGcZ@e-9~hz$6FVlNpmN+q3gb5?r?JCVNa4Nh_4ob89XtbAZB z3|z6g2~-d#5+L-Ag>@j<K!YF+5rciIo1S5fMApAXEK0hUYaaHlWHQ9=Q_+t|ofI33 zn3^YOsKUpRw@>wqjpqL}ySR%{r2y=cpCv+FS+m*O=O-5U)hyquDN=v~?yD`-s`h&W zmQ`VonE3vvi*ij2NFN`Jw7#tOzJU#hGOzCV#KHF26JuzljZcztSt~V?AAaBf8pqp8 z>UAdf^aU+_i2sjgW@j)QrO^0R#Oc7LSQ0^G|KED+)Sr+&hT>MD6d?wq*{?4Onmau# z^=-@l6k1e*S{7v)BM_vq=GEhE0|Yb`q*>#6w+Dx5G_|Bpccxr#F9D^};NN9Fwb02r zqIK!1amdcr<xRtRSZ8J*7DQ&iudMiHZ;xoj1V&W-`=7p*UH@7(Lp!_sMXIs+_q69p z@x~@ZRt#Y#oX^49J{1&t`-5hiP$v>(Dx390)n*16`R`r4ViwL^L$2<fuY2|wGdZiA zk7i(<(T<kHyuckbu;%v$C@?{MYzS-g^zBG5_Xov&D$;njkM&<Am%SLmCq0bxHEq&* zUws@SD@Ky$nzgu?i$1hF4cned8O<5uK}H6k`%rP3Q%$l?*=1QUuqI)m(UW)SV*mi7 ze6G>yBH7K%q^W1X6q7N_Z{?wX<0%|4l(?kz=ou|o(p0T5&GuoZcWwK=W$U;aiMblY zJl2T7k$9N10Vh15o=-Kfa&|-;X!=)~DJ4y*j#~#YGMDdZdQ0>SwcnD`MK~~8qoc)- zOAg>CDoe1Xr2&A6zyUpSjz2WPoUwuMD=LGg?BHPe&<8wdLc9#4Afm`?r2OCw9e7pr z!r)otpp*yN&>4q^%<|?lV`nZPt%FKbcq#*Pk7L6cx<e)F#5gGVK}#kk_JdjV3C@ps zxtjRkziCJk@qQmX9SLgzbvEa6=0*(tp7HO2ZLrp)6w%sp|F33r1wm0_?+WT^&1lob z?!#-2_Q-ka_>8}&p%Uij&*eK70N!g_Aw;UUhzm?pAgnY`z)?LDF-IEfripXH#pF%= zUuB)<TUQ;&6t^CA2^QF!(QupHL^gY)CrXp`g$1|>dyW%LRk7p&;zHN!+12F2f9a1& z9i%=rz?}77edbV(T@#Z<l6g<8tA^P2%EX%#X0>tQX#os&5)xu0{P-#W?3-JxI>=Nj zYimcsE-DpKUUszF@~|y1gTO3Yov_9z0ou~3D8a&wHl8Qun>p7_sdB|ZXcIzO=meV~ z+)+mtR*2NMz&L8q)(2i%?u^4@Xo;+`Ytw~hxS5$V-Q<mXs$1RqaC+PVu89mYsM!sw zzODS1&_eY%t?{!V`aHsB)=2jAN2v^(-16cQsT4f)dP3$mps))hM{)cPCB?w0*^tXw z14Jduo~bGeaGxuNAfHYcH6YdievIc5`!2&v1W*y@ZIKDTB=ZqyO~c4|F|Y-`ejV|9 zxTv*Cs6XsL!Xz@Hzy3hk&8;qNtQt9JAnk{dY3+hDEB_F@-!o$wG+2LsAp4|<IlVH+ zCt%P}g#WA>fy(!4oOl~l*1mq~Q-BDh#p->=_D<h+rj4cJTCfI&UBEcOCf{rnWO`uj zX$8)Zs(EyMAzF2v42;yXvmLXMZD_rYGEH={`Jf}&@SSJo@3%vsKDuMh@3nt25!7QK zG&uI22e@@AtEY!wN{NRWm8taH0(>Ko9+6(Sv0yAE7<`vvBcn~?G6_%i!*2fNZL*H` z$J73}>@?QoW}9X|Tr^sjD2w|!aU#C>ui|vY2cbPCHu%i6!{JgCPF2D&!?`d=_M<Rd zK9Wa6ATF9|S0R}cJPKB_Hql)y#N<CITK1z)HDlsy6nT*}(L(~4qnKQivXu%J)jE44 zOSP_>?;lQHKVb!m;6R`P{vNf4lhE?MXDDZBVEjFF<j!l}=Gh4MnyR{oop!NpR0dS^ z--SbbM2)e^q~gTBeAD9Mr2Q{YoSg2J2f=JplITDZU)OeFQqy^KZyd7aY2(;`tK)=Q zoT<8LSg2@uvY;C@gB&f!uaJL~?$OJCDisp3Ebk7;q|22jz-OTT+JL%R1#(THuRu)- zC1j#mFYUmhqVo?#h^!!=j`U89_af0X-rPdV+nEJ8Fv$s#U;r7PxrV+@UNh2SX*`qn zK$FWrcNrly)NwXD!FZM(MezA1e=T%+YVBaEVyL{h58#A^8Oa^H4zn9aHsE6uCt#n| z-m;xlGc0S}Z)Qzp9@mIl+C#A-xxN1b=@Bu~a<PzIBVsoBbS>Sn-~HVyI1|QNyr6lj z7oz+z-#^7BXPNQ#qrd-BQwRsgL9Ci(PVQ%_)UPL#0LV2x+%5-t*Df5xqldg=pyZt5 zu|H*%m*;`a8n_r**T{Wio?ovi;XS5h|MhQ6DEG<_9_uD4DM_`;DRF!ISbkDXz#St$ zzY8~|qk6+d_T6rBviV5c?zujX77y}C$mCSdt>f)PhV8*B{^9m)4J!mfu3Y|JUQK)@ zEY3BOAf!MtA<!X)(d{lv@Zm=xGP9T|lqhJzOo$O6N?Mbx6@8CvG$M18=^ETrsbf%~ z>6Vh-2B{R3F`wkl2!xbefuV3G9rk^fnv?y3=C&_yv~V<-VbxpHnBq%Md`);AL;q@= zEpsewli30t!o&nK<}LD%VKPF}2zw33<AAj#@36UnU7X(@ZJpqRsua6M;)-(M?R6}j z96MT51tKi1)nMY4#{dVLG`5K~+SpBy>t;3p0Erh1KY|8u4{d5S5!Jw?+~HOzea9#$ zAl3eTPY&rm`vaxMh7x!}1gtY3o*CDJF?gKUY+hFI%bHqYz*-YL*X`-vCzXK?d?7ix zhrOvNF9BWTdkg%a(djZ58wpS4CmI{H4>dhxlwNzP<K5wH&=Me_eiuk^a`I^90RI~l zo8)hAEDXK(EiNQFT49ohUv04x;Nr5QWni{`2BNh+%`)FuE7;#+wM8e$W;Z{-WM)4Z ztmNS9SeWSkjF=M&Te7n<i!q~lNsC&OA|}lQG&`x1ne+nA{7zE~fOSSseMV@x4?Cli z#A}-c(=oj#8|!!)9LeXulCeZvx$3ug5E*HKqICzXw1PQ>kWJz8xS^2<gqrq^4UQ7c zxlK6yr;K}hwp@VMq~n&fy38Mf>!E6>lO0Jcz7|Zj*1L2KBk0)eGQV)Snxz9WH~2Kb zejU1`n;e^D9M8!N=xbjueb^(Q{%<YOn3y&;r4ry%Zx2h9fdd8UHG-njAxBB()IxYt zEaLXy2v8>8u<Q~R<#z!8h3n15pWV+bvj3o&MOe{v0r0S$xhJ=tT#Jz4R<=v4901`9 zbdX6~UbcB8j>=f4A)suiB>W&)JG$PJ4{qpVw;DQfU8Qy)QBxC6f#dOP=DJ*-s9|aQ ziG?D2YhC|l!5uQ3N-PBwNC$^Ts@)8eX6cnv+y+#~%ISNXs5JtP5ZgJf)UK|EAzgN2 znNMXWVQ$<@A1;0FAa-8v@8g%#TO2bI(Fk{Te`;J7R7c)Fj3*gnl@~Wu<sPF>Jj-&j z9sh=lv^qHa`>02#9o+AqnyehKPv6+sxFGf~BDFPz5&6&;XJ)Q%zRWSx@7hdx*{at~ zmI#ioYJ=mp%&Anh@r|b|lx-vvc<oI;QySkywyIjOCLT2qSaU1$usMu_g{}N8c+o0? zBPxPt{QXTq9q*Ef%7x=z%v?+Em(!CC*PrZ%(DItKn&AJ`dQ4N?(j}q;L9fzJZCoV@ z#u8xU5X4wQBDlF?e+kmEJkscPn#k?Ke7ZFRHB)PFwmPACT2gye3*+<242PjuaWLS| z{@|*I!u%|@<jI~#OrzdEL}2|UalaY0UX&>*##jN{czoz$iKR*GQj|>G6r4`Xe4AF- z>0Ddihf|qTRT@d=Q~1%-q+D?lP9#xd8sOh5P|9F#x#GPSN{ks@wtdg$f{8FVGSU;B zAX=HvW;fhd=}3Wk?i#gpit429A5&Jh2n;EzuodQk`eeb3G|oAC-*P^;866uF3HL@- zzfIT8b*;<gD3j4LRd1gYng&DnCdcdZl7GjY%Rg19dz+5k>pd?Uo*AZk;VnH}5Ia9x zB=d-!)aw9X@ivt=$!nW>J&Gt}p;4#GY40*&n3yQeX|YHkBEw}u+A!75{jN!Co+BLO z-Qk*MT;$nrc0e1noS}HqmDjpV*FHvCN8K4EK&x0ahdT$wLv+ZbOA?mgBFh6ZNY;A? z+fTUXHjEAI8=NQ!5mv1GQaMmO9+s8W4uMOj9m>GkM5@`fctkvvF^MhHSr_I;qXC^L zvyqI-&7j$WsvL5d7;9VryF4quw!FrWPh$=HFfY8xUShSedy_ES$HB=-G%pkArOpe` zygYe-$jDWs_L%gr&7+a~q69uGqidei;wSf0@Qv<Jy*h2NT|?K&I-afIeT-!k^jc9r z@W>^vOZm@tNj{|XBdVcx-x72P0P;$}M__?E9`|op>mBGgfo`0GOGsyrS6N(JNee_; z2anXn=>jn+*hw-dGs9{uOhA)X9U4Ns)xQ}>v{_7MZCN--B#jafG6FJRTUl6nu`dY% z!ndC(E(2%oA=UJ|NMG*;bbflQN%v{FFgTp>)?V5Uj?3^zSH{T7SO?9%7nLbaW2=lx zig{JDM3~VbZ|KwCyeAKQ0bR>P%x?la@c%!~-UF<Ot?M7Pf+$5qsuUFgk={G8AjqMK zD2VhLl-@g05s)rLdQoX22m;be=%GhIdWVqE0|W>m3AqzI?>X=H{qJ+{bMJm0!Z0&T z_N=}3+N=EbT4my$CBhF8CZtS#qm91p8nH>-_TBO?W`wuO!=|y&>M#0)BfF3`m2cnF zIh5)~nDCu(A76rXtLqNZ3JU>9mZJMm`Rh@`jMox;VUM(=LSX>Ovu>e7*H@2MxN~E< zl7Bfvc4*lj4SY1<mEn5s#GGI2{-d@rBIt-=*Le~rZ||dboh1rVbueNYI7D6WMxiaT z7uB-tzO?K6=+am`y&&IrR{`6Ox<gCJXME1W<Y^TaeS1n7ml9EdMxn8DectFp2|5U0 zERL(#9PPwI9)$Po?1034q8jxHo<5vlfUZdD>$VFFtp6)g9)k&&rrfAyq2acOftgI` zr9y$_cN~*poqyUf5s~9brPkYO_pu+bjl19|!sm(Dp(1*BZ2MfdhHu)+vL8ST3+tyL z27vv2_j;{w^#-mV@S``PoA554Xzk8i4ns@)aLEBjv!+%!IAW`4CK?LzKpq0lg*)qY zM*a#-t6o+QTT@K&_)Q=pPD%n)@s5wl$yRkHc*nn<3S5a!HWg|hh7qbWC&v9P^K;D~ z=A`f|a9;lE@aiTiLcmMWjy~G*mQAmMn;Wo4qn*oT{F=Z2238*&?JS=uDOC+>YiR7d zTB=k4e)S3vPX5dpnrQ^qPw*vgm%a+n5<-Nl1HUnHu-i3}t1QZ1;qcJSo6OX5g3l$T z54-Q&X+IvG$^E3EthFEA&GC@D_|U3z@XJ&y0NByolAr<{uXhJ|Tf@Z#JGJW-9mlsZ zU>5U@oA&uOga&jVmrg0i#5>!%SO7lol3T56t<hdp<J2vt;%h%#P6GnlWD9as<LX06 ztLZc=G`!h4Q=z8lUS2U^A8E3wAjJBDgIasbi9q};0Ymqdt+t~bA_1r!fVvB0nG;@O zYjFU383hF?%bNViZcWg?6~#SroRypDcF}tV0&z<Yw5`dY;xW1u5y{_xFFEuVU<=8u zW#Rz5Vry%njs9F2(^FQ^YI*wr`0LZwRaOJNjW#}d8&_ue0raN8Ynw`9i==jabRs|2 zQu8RTky??a2)5&sU3acxBNDOoN1DHX0(~Vd0;JOwX*#@8Dl!=gA%>M<MRpe>MI<no zN#Y*#gg<YFQ3C4dtFO-9t9q7s7dEevC}X(!D8WIdZtiaz(w#Ij+{Kk>ysMo6(3<)R zK-)GTTEHt)&5tkdUD+*ayz~U{V7>%kD|Xk-;fB7KQws|Z6oX#k^+%r}?ut!sJrA|O zzfE|pG-oYY>p92rS@frbXk9h+Fn!U?WL4r)XafFw5yNB#U`Vd7iz#l_>vK@~DFVsx zgd0R_Yuoy+qD{{?dE1n}P4MSI@J%j1f5NFm$^AIHLH}gDUALw=tsMiRp~?hNIuJpW z^qeLChZ|FD`z(mCZRYE>1;kiMf8G=SOs%JXGiJe+q0qT~GV)r5T7PCFpkH+N*Z&0d z5EzMj1$&1uP<*<D%u+p&&H}#o61Zd|tLeg%lrl4Ni0}DhX3`6+Po{cRqk(l*<t9f@ z#`Me~{sA~<F4bx{d~Sj%vz7!*AiQW3;GIy(p|VN$E&#w3rXo#`#wa0~4X?62i0f@0 zI2?QljYZXN?g9c)*-MiUxLdY!u&y?Xg(m;9t(lp3G2i&|dw=UzEEMVqOi8gS0510M zCS_Hzea#IO;t^Y#1{;;b&am;&d&a0M(YI#e?{J<o2{XUSK~r*dx|F~*Yv2UKOq#G9 zPqsIm@WTbSU+X=5Da2!Z1GLvhn$(aFa%7Gmdkg60YUH0dIe7!{!J@*`-d@_f--!7Y zJ%q~f(xr4-O&v=YH)sr9O`XRLzpsg&o8~TV-b-k@Ot~O%j22%I*oce|M~-i_9r~xs zrJjHf+Om-4j(i5LVgnf*V_igFCy4>MYhVitLZE+abZT0aj*b14!g14D-;RQnL)&`D zIJk%#<q3>2e?M)6hSJrKHMgfXK7DNu5wM$o&)fenb&A2gnP2uOs@28UHO~epz~KT9 zj7WrL#x9hqZ-|iJ@1(i0*rmF=>G0@5#Wl~ijnwkkXFd!$Fpj0HEiPKve``~zFwgDw zgGD%5xk$b5sfY?zS(aZxLX)9)uuN?Pdq;LvQY&Eg>JyW#LrXRa)uL`SZ`*rg_kMX^ z*4Ng#p96i^vvlzU9(^LUH@bnkQwQt2&xYdM-0Q7?)pP9?m8T`r8l1Rj?+A%;W}&!s zo)3#UJXP{V7>F*1!iHa>Dm$_cW=8Tf!p<oB1L;uZ-3fri&?XF2t@IHAF)}f>Lvwc0 zu+t;EbM8{6uhUdLI#lMo0GqngY|cRpwDjcuDbaq~%(2Fc+Fns_bZbw;`zT!!zc)*f z%(^*F6marK?#I^FR$^ViM~~d;>8+pE+O`}c$8xs-+530rPTM{?Wetg;8#nw`CYU)O zUn+F)6HS~Aq*N<%`{)l?s@_jec-s9!##GD-&@<SMiAkjE&x&(9O;J!8dCYW`_ncNW zr9e5hrTaf!W2--ufwl~nnuQIlzqzEHzuY{cV`WTGySe0aMq{<&Kf`p>%|{Gy1Jmr+ z)Ol){?tlEf+=PF`1yZi{g}Nb-Tc7>1-``r7vDXhfv#ORBRRO=X*)G=IUrr~^n?3xQ z+Ktu@*ir&CT7hSA7vTD17~+syQ<<v(v-5OMf8H{oIzMaekz{Q>d6c?t<Z&+}y<jf& z;nKK5oz3y+iJ8^DCjlF%9SPp-;EGSzKLbNWH{aJ20o^LbOj<(F{^f1H<WXrOOnV{6 z*-tNdBWoSeO(;`u4mktkr0E8=O%8||c~Z(rb10VjGiFeSwmtnlraLlz_n98|vuK)k zIrId3rpL7bw4+D93Q3;s7W<UHjFT0k$US0j6`Y?)^J{8y6`(U1{qd<VRqM0pwFeeR zDJe`r1e@^q^B%~nHC-WU^2}Uy2(`E+DD+~^!*PAT5j#6&>#t@uhD!&O*sC<G<-N)r zfiq7cM98Q!<>^l6jhXZkIuh&abf>z)er5c+r+xj}aNOAU&2KttrqxwN%J?IB5D3~2 z2*tVzppuUz35x|Q<MtPngEVk(0FSa$S81}p+O<CFHB!J`YBcpMJ1}r2HQV=KQDKV7 zYN0h`^wYiID{S9$<BO7PbYHya*|pJN75BIu^E}Y`_1;6$%?3vfsme-nxyn=Sn1YlR zim2ieuYx7vQ)4lF;WzC;HxT_dWREF#fTTXW%|QNIG3sFT1YVwEW_r2jwtXorD}y-< zlgR$`g7w7r>{ll1R4Y@Y?3sX+x#3U<iHK#D_qZLW?=JkjS)}@zSYwmeY?T7aCf5~w zkM{c|!H_nKCr_RL&};7$ahr=3VEF8^ayXgf!oU+@F9E~{Q1~$wxTII0ZL`=O-aT`w z>($3)9(=Y1i^7bC;)hprKEdBXO$j;4LRzLg0K0DfFi1_{EKSasRur!&Uy5A%$#q#C ziwX$(&3KNFlrfLUW{^7&{1VvNywbaw_sskcUz(6gO2B@B+}dr|=QblmpzCw#;Fwh% z=2(SU+cTvjQoD0$M+gft3#-u9#U!Rrap;ha5hmU<oE7)wfruzllnYAMGX|!;X)!wr z?hdpV_o-AX_j6Hmsi>+7EYXD%O5QShA~MO7$_;UcPR*zM8`JADLsrG0r_P+{xpe40 zx*yTtpxx6m-+kQZ(*T`O9=9Oz<5Zq~M}8tlFybC)Yp}Ku`=_8F-#L<L1GOa>nCNnS zFf=d`zDQs*+XDXgJlNa_1ZAA)JM+GqKj(96SA4&e5~Eg%u;z_kB7+9#8%Jx6DrR_A z<XaN2HyQ307rYUDq<W@o_c{96*luM=Z;CitZy+1XKPK{`M@QMDGk1bZ)MmCoGZo9P z!3Km-kH2;pZ3><h_>ZtKbIiPwL7nMCqg4&>fDB(dgyNaBWExqGW<RZVu1X$nGrYAb z(U{ddq2?EyRzDS*rj%Jii39M)VuR_kFqGZ5x9+Rj@&b4^)t;CkqI*IWBYAGgjRUJ* ziIRMUu_-vF-$MC#A;6UU@?;Xg9f4EyqCw!SsexJSA9+BVMV7e~XHVY|=qdbGJpNLB ze%CT@dCO~1@dSt;mgKnbh_J6)$Ui;){k8=zDAp1g#nOj|(JUfMLOd`&i^Sgh3&374 zGF2Yj1C)_UHE>ez`U%NF8E}Cx99g7<;c7R5Q)fESeeP2e_#oL>vS!hOncSMsg`?V* zcgo$C?=%76G=Zk)-OOb+dg}Zp^`07k{Aje?UiS=)uCwLkSH-OLe0#@pHRf`R>ep}I zI?c)&`yEeoWHO<=$O_dGEEe^fih%{PR+!<pRu~m4RFLI&2gd2|@V7&Nh2KSfu~bHy z^3XYufwWJ#)C)~J6J=79$N+AFgNj~#-LvV$GuLJ8jGYWt*js>??PCW7lg9vNO^Job zW*huJ^Ka$MA0MGydGufVybahCUT^H$KuRAqb@Qp4`N4MD!ZAPuzKJjQmeUD8xc%_V zoi_IOu&r$%3+Mns8?M1Eg-js#l<X<s6t_8HK(RWr5gms4TRdOXCZn=1oI)KwalJ-y zios1hRl@S}n5Ph;@C`9VX@kX<4kT^CimW^v&!697$Qs`A7kPllEv|};=>*!TtFoB^ z3Vdf@W52zU!w2IU^s1sMlL7}=ouM#Rbijun0d<}Nr^b-h@k`^nS56dDGLfwfu4bIf zvznrE3EAOf)vI6k{BQ?r(S)3Dp^xsJj@!t1*U>kCbTGS<Y=esrJNeR8$s`*d86HvU z2a!xdFMiq$x}8cs*|!C}MSE(qQi$C2hxG6%QBh5Xw)FUEnplhNnQ6hG7b(57B&s{) z-VXT+_D(Jh%?9Di?KU!*qZ=__%Dhb_4+bJTXMG396-2^X$Ne?_5MJH<%v{gFe4eRE zjj~L_0zYS6U51Cd9BbU-Lg%!m>BdBeKt<q1%@bfd(19*fGOi71lZj{-7f&yWSTCXZ zyet!+GBES;WaVpTTkr?;Z}t=10J$sW*gq6Fc{BP6orAmv6aSYRXNx4TMpj(UGi&GA z@Xc#|#L;oe7&0i~zna_Kzls0PIm&nc$1OjB4G$MXo&!ZM*GIow5s&s2gaE%=_lau* z=q}LM-DqLB+FVEZWHs8%Uhc4g<+z-R0h{_@U_*BFAu)(tL9D-D>-o^|FyqN!{pl)s z^k-gqyIg6O)M@~-kyk5NxYin<de>&rMA+5P|Ner}45;Gx_mGkQC64yuxij5bj#Ve? z&0hz1WG9l$MY}?2t^uGP@WIAJA5i)Xhe1`Cx13=TeBRubDq&b=dES1sSl25L=x5gr zK;w2N_xKSCKNyQf1k-_{prrXWIvntq<_b4J2Dh)PE-vL|WpP0931IF03n(K4Xb0XF z9TALz&wsr3Tp#^A`WJi)*lXHb4ycJF_1k3nQMNoYFzJ3kM|^|I^3NjwgmE67og*Nh zb<dE8la?R9sr{RZFQYj{%!&o5Fd`=>hd>}6KYiLhUS`EAVM`61P`Me0=qKNexZd5> zW!{@4v~w!2ZDHJ5!-%e!{Muc|p3~b4gdI9MG0(N9`P!L1T%_&GZDBMTTf7Qo?^VD2 zeD>g$adk-LdiC&CEmQ6=NrAs^UEyV~O70RKC}ls|<50ZvT*WAmt1a$=d}i1U;OgY) zN6GsSCgevQ9Y1l?L&@?t_}<#unw^6~l!z7($PEMv)UYTA$hL*ip~kIZqe0;ykCn$1 zG;E2#3{KuG3n-%kRGn_^jJ{@A<-n?uEIcF9i^_%!9BfV{Kr+Y__jsG7<iFd_09gv> zJ644Q9xek7`(wHq(#Fzidiq;|^^5tun(&D}aBM*Iy*4=NsEAM0?l;yqu*j)^OZd!i zDes)YBe-ef%19A&BgI^2vALUw+|N}7pWGkcvXI7Rybp!uV9Et9q%SURGIA;*$;Tni z8IrGCC1qZMm0GGsce=Ozj{WytsZ%{@#<G;&eKsION`2N}$F`cD=R5sna3$uwx9l`h z@nMnvcT0ek6oi}`_nAgUM!ILn0v&OEb*z*NAOLu}#ue|mI#unw8+#H3CT=W*ky?Rb z>)W`1!vN(fhl$oUIucK9`cIer#bO20zy=o5-(AxFY>)<m8Z~=(IEcrj?$6#gm0jl! z+O9B^<n>B;kb>F+ZTqTI@$m3CnC_@)d-GvGJV<Q{R%7DETV@%8AzT{LLG3zfvI+HF zH+lr+L(m`sZzQJzmrg5NWKS|0LDDxHxOQo7IrF?TCUdC%aPZPHKC!ULphbOH(p5fF z;p673NI1%>>%)zmJhfQPclU1q6%f9kBF~DG_K0#BfpozLRks(JPY3i0A&|?w-U&<t zTkPJukNvFc9%a01{&LhPV<<^j&zKuI*Fa4?vKF87P3XX<(BGsq{prNv4(?wJw#hrh zE^F7as~pjCy54+Nd}Pj40m8lAeJAKC_d7M@fvm3zmz$#M5Jcc?z;37iUWVIgwc1l) zt|qU05M`ew?lgv@N;ohg*ihIKfY1gt0W;)7YO1;<o6U01$3J61W;qpW5o52_ylIy< znrTn0P7R(9v<yV!5knfn>RY`2S8djj-w%P@6-r)wql0-0A<I08cSPNui?XNgU4ZmR zz!keigjok(SCE<u!YkssZ)nZ6a7RXFEWS|oS$oM@k1>wn@Sq|Ye`oL=ulUA4u~_ic z$W`!%-IHIH?;ou)-NAl7<6dx{&**2L*6O~W+*S?X%I(!S@d^DArT#!B8Qv@}HaY^Z zE$XnjRL-&W95uHXe4$97Il|z$3mt@22*Uo->*JpaQz&q=izo(nnnB<vr%7Y1#j&sP z#h{A$;ITuv1bpXU(YvN_D`@K&J{ovO>h?_zD}?cYM0QheFZ?)?dDf_}7bSv%fgr)5 zh#0q&Nsz&)HjTDwj;=C^fH}N!;Wp%Cnx2pi!UjklvijkMG01q+w%M`1zqs$`vUwo< zRXusj#BRJiBy?P9?9r-i&&4|33`v<h_A}HB$<@o#b)pGNJ6Sohz8<tZ>s6Q4U+{$8 z38aiQR#wdt&*<vhf4agN*OnfqRb5i(AT+^NU!^)>TFwY|m2vaN&y81Yj_@wHq#%*V zcQ)Rqf$|4HC3Lj_*IEyre;0!Rq;0dD%yuI>Fcv-IA;-tGu_X<p<SqnDSngbEcyi@D zK`>~?bB!;f!?iBccSX!!d?5|Jdvd#}#G9=Ahy7KXJ96;iwOHSm`a)`StHIna_2ixc zLgE&cfn!d2UWC21z_8iT`=9rM`6p*=p3|P?)K>IoPdD`qe|GPBLsGJ-X@563`<+a! zy~4%_tYy<H0pL9^FRy?dT)?Ts#Ka#jhk4V|y)^?_qg8?8r7<E4E;S=|e}?>I4R~~@ z7v%cHAVO`rA68kqy_xlJuVy<t(a`*WAPr=NL{=}wpnfN)x$I2wVG8{D;?opE+27t5 ztb<Sk6<96yQsSsteB`pD{NK%)raW+alE+>L2<#`%f5Ypd7nJZ4gmy9ZF=v))$J!{q zt;`=frv>G<zpQgDWNba$tF@5dN6)o<5T23U^cHw;{=vVc6u0@B<TCKyHHu3t9O{ji zqBBl}>Wsbk*T@tSD6=iLG5r1e_YcP@=@|L7ukSp8!pjW+pcjx4?6j0HE{Nha8K>N; zsw7S&zgv4eOznLG1ITv_+K=p<*TH9ilB~>aqA8LupS1b`c8E=96l)ZxlKf}K*#_S_ z?eMM}pTFBbjWn#V6|?C{L?E>#$g7rSYU{>Cg?FtEnPy>;z8IwI<jaB%QfI2X=N$$< zZOtu;yZZY2ZVBwXt@}0rtd4&pORcAA+VNv>`<Gfj0h^I~PcGK!rIciJw|xYpWauM3 z9;51!%lnMOLLxTkas=Wsb6#P9#PXnG9drIBrgmm*bJ5MsO?JJwf<@6sl-bnh22kIt zb$$PdfdR1br`P+%t5>fi#j5`!4gr-Wqv@vK{^Q4pZL9fy;e3N^(~Fv%NMJC;WuLgO zj@FAPT}@FulbVaf=7K5DBy7aaTN|mya`rDLn`Qkl_L{KS;gPdHQR7a;75O7305G!1 zy6V48y~?1a+eKCr&@%S-_o+0jtgPG&{=Ezw#hu%v)%I&N&CuopD$V8n{3&Ts`0d+} z%G|$92OO0f0Ui=|QS(!3T!E5jDX7O^@(T-V|1nqo`Tkoae_I0od_i2y<3FnAKljjH zIM4Tw0Yg5EcrD5#Y-~rvCVBhwV0m$)-<<x`u^-5L%b2>&d?;6)YW<-KZ4#ipi2CiV zysH9+a#fz^X4t!`5?vv3q1r@#z4&y6{=a<!|2OUeCek(V+V4Wm3|X;1;j)c4WEIrE z@cT6qU{`c~{sJ)2r9Zton3+At2L_&+tDf*)HK)5MHz6gzJBn4JYhXb8#Fr4pLca6h ziIL1PplZfFcxW{CmFbUpvY~LEj}A!c(M`{-dYLv1&_DQqm9f~UItHlZzEZ<=OP-Qa zt=E-H%u;3d4*g5Yez_C7<b=*@=fc`PFP{>T-=c&J%E`(`z9&EJA3_~Sw2A&?pC|uK zOZVs7{^6vq)1QHa5P!F>prnkEf;<e_XqQv`Z{^$V`9(2QNy6dL()#;brSWa=2dtKg z#w0eTL>@cxl+wp>>jLU@5HuSgu$c3fF%q6$JzVa!If>BvXY6uwS|e+n_gtr?L=qcp zp%G32?<DX6VKQgC?I#ybZ7u~d8n$tx=#X{E_HvR-H|V7mU2i-P4vOd>Y?spS&@h%E zXa+&qk20|jN;uNTj;}RRnxuq4*<rdw3itj?%im)H-#w$t?tR^)=Dv`S{^;l<-KX*6 z{Y{OzAfoJA$`XtB0v!&v_+a0Ch@O6wupdCdE|p~_e1W%^YM|lc0t1)1tL$evUE<WV zR{(^<jL1GE@6)RIKzJEuK+Wgrt^RAFL(!#EC1`(j%j+BQ=C$nk)+J}K*J7#gP0G9V zr1WPdCjAFUaYgQFpIGd?((E<-Snwd+ax+cpzig2J8=hp2nVBp6nH{C2vLSC~cDn`E zy2bc1`lVt;c<oqN2DUOV5D=0uJCIp51-*3FE&a{C^Q77u%A74D&08-`hNom)e>Zc9 zD)@XlDBE1_LVSYB>9LgWO67mI&(vYInd%#R{)=claBbzw;k#1z(K1$cQ?-`nv78Sh zrSMP1JYN})Gsfn&hjYTX3!T*rRc`uU)0gZzoLmw#tBhFAZs^K93qpBUEBCdw-9DHV zjuY|O+^@{Vzw%ih!5t=yp_3l&E0k_$eSBlzQq)kHXEmq}M(-Glf9A?UFy3@iIWd=9 z*lHviY63WomAyC2=(ea$#Q))e1NEPYU?@b2<QkX`2F<jO?gP>_4((=nPw<fyLSpwz zq}*qhQm5rjkSZt2So}?dfvNeu`}#IQ6<Lr=Xy0TPx5<06FxrZ*M{^_8jYx|ue0NBO zqK7CqZ(uT5Sp<xesCL;3f4~wzkefd4q1edye%om7m~l=XEXW;7ZM&k5+HHgieah#d zV4CRJpe!*bxVFg#5kjW-`yLo8?Xj7@TD|-nzK4f)u;zq{`mCsDK-MJ$zt73Nw)K)r z;OCavIa)9BO2kJwEqpgf{zYo&-t)Zm@oXiV;m-7ov3$_EU`jevVkD$hz&`DCWLn{v zJ3&h1vCZi?M#9d<Y3kZl&$UxGHGJly)D>$G&5VruQHsfW)mo_ND+*s3jR|bd;H);e zKp<ZZx4r2iELm$YcZov6=djz@2L>@5{9P{n*Kz}2&Hj3UsO9$M7==}b5(x6rO(E27 zI^8xRwq%|lp|f-Z*03|iT*MknXVC{!N?1-moW>ED+rwT(t~M{Y%nxj|ttMyP!$yc0 z>Y4Pz=*-}_B{gx6?aQiKb)j>O)k0oQZ~KlGE;Joiz-rNHk%yCpORSKVnTDp9FtO;w zMmU$VY*<1ljcwOTMa{8D_T!1N6w|PGNew+e9r;|>O~98^<vzx;#rtoBR%TWg1Zi%C zU|nVgdwo5Rj`Xt!H~V~7rZm}<GA!EETw330_#6(4UbY?H!`E#5j-%!ZV&~RQYu|?l zsNX6qE_zn~p0CMUn2$pyY5^8)Jv|oG?O%BhISmnjJ5KjuWVGfJ^?0|5%)Rd^l6K%| zv#xi#ZNLJ0jzPFS_T{w~U%Kk$_!f8w%So`q1}6${ZN(5h?ZybcCPkNQNL*=M<B|PB zSKvkU|F9?GdU&zL1hbQN?S{DO)%->6{=BjG-NxQ6j};<s6Zk>bq!dlXN4^n0%mrAT zYmD$0b=jys#5hCMp;QoSt#cRpmj^6h?rqLn3+3udaxYh|Yafj!2*&2AJk(d})dF+C zb!Q@PZ+KBNIQc}_L{s?>Qv?^QCyN)ZKFcEcs5yOnCKrqXFT1sL<ZR#C<nFik!42?7 ztqg~>F6PKCr@@{-1>f_b$HvIV)T5?|Yo>Maiy69v0QGU&%gT5fzrZDs*Qw3x7yA8! z8Tm+WQnQ2l=J-DD{)#r(-9Cu)*(G)~V1HdmQr-s7MstV=1d1Avc083$%iqcAm_EXQ zj$=XnbmMP&nbAlXdVhIVhWUqiCztF_#ml~E@C?py8-J|^vahaqI9ecxLzo#mD)#q7 zads&4)VSXE(#-Y)8B;66;&>ZtqKB!G+&g}hhfZCsy{^Q%X$hn_hCj9u7SDs;>6)-n z^yuXlq+_*?VtF{nh<QFuJs6>5IQ=^$gAs!hyf7$q3HQ_Dc23OfoMB}B0%xah!Psu+ zPfry)+hcq5kj?IdhjZg4Ra(9Pl5>NUGixMRslEFe1Ri_b6o29J48hC^KZ}tq35dWZ z3ECW|LzWd_HZX}t!IzYC32&j>Jx1tlgv_18UT-w2mmvt=$D`qcS{UZX5xsGn)0r`c z17AD^v-ib}#Qlc2+nT4aXM*;jashQ7!tlAojy;8-j;P5bI){{HF2{x6bBZtl=cev9 zt7KOa7kK!>Wy21Jx%yx_JRv0+C1TUkTdk+K<h7M)>iVIl<0uu|lm0uyM>qj4pG-C2 zoq80cRgdMVv!N&z-e@&MW%k#iXf5~cONXyaMGE>ym^BTCaA}!!#dly*iG7)x8?Wxq zpFQ4<)REizJR$gkz>k>?$UtYMq$loQvlu3E&S#H~G>CdrMKTX8K(J<a&0^E_wvNvx z?`;fp#5S~L$f38lLmsBc@+%XCkBM71lY}xlbtnbrXZ?@WUMjBCN4hVvcVdry&cbXp z7so1)qNo{g&DPhmhd5?j#1xR2#ikNFWNm*zYS(7-)#&f<9b6Ojxi0_F)#BQoxlIht z2$#Ic5IvJm0?g~wqtn@rCEOX)Fiytc7x{C(H1J#^7rJDs9V}wnl2j=1)p1`UycjhD zk6mtAMPs_ZjMbDAf`X0$SXn4SQ(-j<X66fZ;#Gn;g@RJNoQx8o)}*A8N96;dg61rD zpklJNbjmRl`%;{m`fN`D2%fRU?6%|Ly{OC<q>RJy5Dp`E6zj|-jK(xk^_^D6foOlp zS_&~QYi@VYtjg~TWqV6`2rrBT#FRCO-g*$Gu_|+*Qr;(hU_sY=JkK6LHI_ZgQQ8KZ zujm}EERjhl<$CaW>fTm3*!2roN<ic0YxNy<lz0h5nsfLbQY_hZ|D^?!$h2nrH)L=% zlh}MjI*Y+d>$V4K109fgEaV#79AN4v)Pt)INMDfCW-kns!`3s$V`iz7Hl9lVzHU#r z+9}h}VIO(s?z@rU{4xu~RbED(naRpmzSt1MtENE;%p99-3tiT~mStS>NgTE%G3HFM z^EFX<g3nnyp*}Zwa!Qut7xVhe81kJ4&x~?NM0}?Fc{eM;iZ@&Ruz$?(8J@m0=vT5k zA0zMd53fC?kNkWGx7uvx`#8EQ4Pq>NzwkUYqL*&mzt|f((`ACfwxL8_Y!7VPKYcko zD7nGxw%jGCd7Xf}*6<8MArlBbCr3+}`k(~qk5Wk$a}-nHa62WqmOt0ooulSX*k-8R z&AVDc7{SU8rgyl4br#3pUS+qv)5vGmR*UO>Uh|D-X`ovdWipUrO!=X;Sq!#h(iq=Q z|6UOCF}XSlRX+zxy;&Vzuzs!y(xDq5ZZ$h_Z}sfw9q#;rJqaKYo^^iA;`H$Fq05@X zohimM?|)bvJx$t|4|9+4(hcae4t31xEE1ykNWKQv<1f;8`oxR4{(b5(1yh=NjZ3Ph zgK1fW&^~=eY9q@KNQVEB#k@=H1t+t9=JlSJ(ob$HB3bJE8RR$T<w7L}6k--7DMJe` zEtTLY&MKQV?;eKF?8^amBp3*tY>r%hg@}W5p^oHaT+wf{F~c~}(vjTUa&}SHjmtC1 ztd;*L;4zO?PcthWQ$W(LS|ZWTh>eBD70+pz8p!A<hs_luNk~_b1g3^?5V?|IIlm?z z$7QOJ_AY=c=Y98BU?!(<^GM`Qfd_cMeB|9Jm@e3@yGGf%j>Z_rw-dY$`{BAp@Up&> z?=r-r_sD<U*LL*9Wub);Qol{JjId>abv=>}hb4V6-c3M@$-_gqH*X6c4Sqxn_(Y$- zM+b}L=$wpI{w)79G?tmseT1%4cXu#=?S3|9kRYio``LdH?S3jXb;7!OTFldbI~Vz3 z<jPgCX&+;Yw>LI$2TaNxvBIGA9ji{4UH$@B{Q5IVDXDuu(;{B+oqss7lU`~YM1Q_a zM&F8cYOTj-xvD~zxHl|E{=pof#@VQT)eKWn4t0ty|GeM~m5<Heb~A<KL?z^Bs5-eR zO24=_ad4`L<VurZxs(+&%F!@#HNUpy3~VrpZL+I1WZkf7{?bvVXm~<QWVz2EQ<Cs= z?b0~zE=|sg1UbA8(gAKnz?X`Yng6QQ?9*y6;owhiYm+hS%hl@?JwWKmuA{hqP5*v3 zSN?TeKOD$HBJNcNx7F7s7^@cD`Pwg(-!)P`dM~*IC;3!=^QP>}d4)|=(^TcmYS8oc zMJ%a<W9gFEcU64?8f+Z6RT#zL4y07{6C#<;y@u8<U$XwNr7;ypwc@rweV*!c+^%@l z$N;hlV~IlUNz@z;KJ&RxBgwu!RKg^MZtSTa^%+o-JA0Onn^)(i|JGC6cD~ay(Ot<6 z2WxkZG6R{2?B-0F1Bj(+Os9S1g;OzBB}>)Sdlud3rj9~x*lr~k;Uiu3!{)#%)x_01 zL*U~m=O~WuLyfKZ>}+1JeVRu-f|=mpK@~ga!<(Zc8-`XqWV#kimFacCX+E0LdH!uU zpM>oOe-x=R+i-NFfIrC6J5XB%F+Wi>Z~ec3MvvUpxhvO;mY6>{YE9vwIzjD}Mxa}- zHfuhF<XFrKr*@cNg8q77=Nw@`&M1A-*iGXrjt+jNG+EWmm%x1Xa~Km713D|1M=^&Z zAVgkIQel$i#GB}kPtRRk9qnM98ogC-&-{djJ89=aD0il2HY?ZErt1~z5K-#jN2`LI zHAmE{>=LhYC^_4{lKjJv`MhcG9qZEru~7~0E?u(4OdCB@k=9-g>1eAtTn}{Z97T`A zz9)_*?PlAni3J?Gkjtp=Fq4AgA4$;YCKNMt4nexZ`b1J;4M^RLqe@rm7svFG(tS2g z{f|0n!)+|Lmfh}#FmG>f!Y?-+>dqd{b1SDvq=)6V_vocfAZ)`XO!c*TX9n$jS*NU= zqkaeM1~k?X2CGx#-18gz{IYeFk7)|3Q#q1azw(0@Q<Xk?gM6Z8Ucn@6jP;-JYc}`s zfZ)9!(8|42LQ4YyVRXvAkqT;Zr|H^MIogh5%`B1ef-xZBu+urA<u+UH4cNlu1sK=6 zPd{>)!8!vABM@Qhc3eUHN0;ilI77PGf%MwB<<(TK-33Z_pY_=tpR!ZI4Xws&)efJd z3+0zy#Kfg0sM*@^+w8o5`mTJ)ZOGmIJxm~hWma={ceks1yE9h9x*t@#{`rbFakHp_ zG)UR!i$w=i#O9dfJ?@`AvwLX(SgVClw!9K^_>@>KXv$gTXGPDtiw$NAN}PDTv!v4i zx2eQIKJz%ztn2q``cn3k36+rl$CvhRi-Q*3wAqx>2Kh32otdQd4o06MrB8>(T0wX8 zIJ1vVUz+uQ8`%nXgJpww->GkP71ffmhjG>|)SU8piDBrV2*&PvzRqR?wL}Y3A8%zY zC2xk>iY-J-^{X=Kvu7hYC>49Ek|CW+kueJe0As`|XSDf?%=SIz`+l^M7C2HqIs8oJ zprWyEBTrJ{w($Prr;A@)DuTaUNha0}1=9=QkH%4u9Qnr#bGFul7eWzqG0?fmr=1{u zB?id9;4%f4!WmY`Fk{rk5(FkX+<P;6PjPp8YW&IQkdv-n9V4WEt3*bW$Tzn0*Kw>* z;LaWW?}WD@P!KoM#!E`nb>XHO87_kN9j=D$GXmN*@AzlDn;PwM8K0yK#;zaNzvt0N zYENP;HX+KQ@?Yn`sG<(~!AKDDN6;Y)#c~v~{mc0VT%Uh2yLeI@e>XSh+b=<BX~V0N z)t3r+ReENTkc!^TPcd=*-3c*P%N4QWV518HKT>5#2Um)Wv{SL?gcW6)F?7lut(*6* z-yg0LNs$2a(A3K^ZY`iB<nSDvHCWG9h5}JurCLgJYq5nddK24NGYphb>Rs6dnZ$C3 zQNCijvn+t(u3pMRTF#raV4v%M<KOk@NQ6Kql1yi{cNe_-p7OPN^(C(PIXEF$p_7mJ zME`w$r>LP4{sUU<`j41oQv!?st|+C_0D<iR6KEi~wDj|hSM()Q%>~)Xm8{R*Y2_o; zS0#Km(2<4VDqoF`bvRRL!5K;c$t~T|Qc{apronoD3feEf`-oi5#o-^tXU?MLF}N24 zMucOy`|Ta0%Z~Z4`uQ5_e}3r?+|nE@uTGH{3De+8ZAl-_7jvAH%-70pfjX_hm`k;+ z9Nm71-h2J9wCNshMZtIV`*_uG{?6!6N;wJf$U?5)42B9}tCwVkFH?a1XmPBZnqg;) zT+gHX2vLq&^e*_WUM-ko8c;*QP#i6!Y-pg-<@O=o<Zk|0y9W!4b^K<Ljk|gv;Txl! zU2EU^L%0L;^XP!%)*?ZB@Qd8II4#w$iSe8D#E^%%3>$>8HYZsvhHROTr^yNy-H+7I zo4a;gY5HoI`lDYexCA+LnwjrsV7a64`q~)ZPjZ~~qy_MVfKYQF|M$tr?-oW6-UGRx zY>7BlWFEE6^Xyz>X*A0Ks4)XVI(|4RW%RDccIQ_D#?HW}{o>I0<(mcGkcb8f$x`GT z$xj4ePdZAXNJGj!cSx_6P6?Qhhk8<@cf|R@?V>?Y8yp1LWmXoxbjpIQI;gYHuy<2X zX3V@ZrWjevH<vRv9+xXy=Q?Buf-B>w8ap%YY8zQ`zMAIS$>gG0Y~#x4$1$6=j6exd zPB72#83!r;rj?+ez}@6&f8<V-;*!2Hn}>9cF|FqCsVA&Nh|YGxX-qAOpi9ju9zR@i z$SM*z@nc=I%<4KSb1GrerchHJa@7&$Oyf3icpg&EAGs=%-QpS?=GvNTf7l-tEeZ3J zt>c2f*90a`9Q)=uZmV-SeiRpIIJ<vUQEqyu`ssvby9kDK>)z*%R0q|hPBWJ*Zd?*x zj#ww%-+yh9+o8;5i`Bpp+n9gt{gz=>@VK2b&=3w4n$%qod4rM-+TM;`Q9?0kUz3h< zl^OW7ouqaMW!S_|ZZ5L~Fp^|kg+L&0ab^=QMv$LE<N`6lJAgUkZ0*7zC2RH04PjP^ zcQ?2@clH&sY}NbU&}ylUOFG`sz#F%JT&nv36kag8$Qm?Z!wy~bG{sxWwAAJ6q#Sv@ zrZO<@di^%Z5z~$Kl{UyoAIK;~Kc1;cGk^riEvZu5jDIcN30uS9MzGq=jNdILDnN^G z%i37w9jKFuV{MhtnzT3S$+gY-hJ@p^@F;fas3pFcj)+0%e2j#6^I(E|Qy@hiowoV- zkGKFl$i|~_Te`&VSb#Yz@J6x;?rfG6rMrWIPI#Qu8)ws3J6MdGs6+c0t{159dvnMz zD&!LLi(m?xzwCY%w`<hc7$znq?RI<#iCUQwvEaC?_bJuJW@>!4KK|vkxl{9rPFAb& zqam0h?M^NyTV$tUagho9ZF$Hk<5BdLfmK)ifT;hkut0UEElDz(uP2ee4~XI?<8J{@ zakrWj8E4LdOs^LN=Zr$V0&&;Hc7)Sqe7*fHqFZ4GJ(*`m<xD){Jl@;I3!2t*Kn2pX z9`L#L2SSl}t6kByY&Y~u5f#Dn23^K{>o=clGYE=Oao6>HVWZAcJ?i0MTd{6~1jhDA zMR`GuyGf^K*c~_F!gqP0cTQ)%xDvD+sm6Q7m~cU6di%D3qRH)^wa%1#BZ|_br^p84 zSwE+vO9|SBt>25X5e_=L+MOyIzOQ;72mLrSKE~kmGLq@-btcu)#>DrNy<JEUWlO6Z zb-!dQS=?GSW}8m?X4{Y3B-EJf5%RAs<897ruH{d@NG*2azIW|PzYW1lQ-S-^cb3qW zpD%}5q+VTJaH+pvN%<7f3*D}Cc3L=)gCY|fN&B>h+64(CMFztFs`9~Z4TN!p9oU2d z3v7Q+-(94V%W-fAfKe0TIN*lSXz45g3RBfkh2YlTXG&OnSoyprT=l+rn*C$`mkL%~ z1J4q#It#zhFw|12Tuy&3y-wxCnE;+^aOZ>tMkY<(12uPDgPDkk<mEbCG7H+3oa-vR z@xkbB2~~|YqQ&Nt)f@FwlxoE7z)@v!dYKQ(1m0sMw1jddM%uaI;Ho!ijZqqYbh=SX z)ITsbHQkFL<(z0F?!bOo(!q%_#TpgZK9$T54G2HK-ZS3xJ<(Icc4x1jFV5l=3j$() z=VK+83trc&ClR}+HvSmfp?sc~PQ67cfY9Q{cJs2Mahm|d_f3Qt1B;jFodN*r#BO<D z?;;LQXNC}AI;6f4iITkHvZ!az%-r^)>~S!Z4tiyMV(_21waO%4`PNxm!P1-5hcZnA zrJN?6D-}8|$<w;DS&z=UlRTuB)HnhBhw#%=r{II?D)*kgPbghn-InoL83-?%F9v`! z22%j8Ab3HPao_W)l=S0~-*%*_@w*Qjl}>N2ywyz!RkAku5pxm3(;s*0_(wKyu-`&) zN-;ld!S_LeDmh?t(&WThLI+=70^I6|-Gx0t;e2>awyxWOm12O647=kV@s3bfVj@G$ zW(W59;c9{4@t&0_1W}*y!T<ec4$z5v<p3l@?XQcgN`CX}6AWg(P$mEPC(ke3b$!8{ zzo#r>k&cGCUjh*i!BmdPSZJcAx9$CZkyab2?&JLpRSpb!M%7QMT*dSta;cnmm@nRy zWb2T`t|b+0a1Tp{tLD_qIB{TuRZ#Quc5+)UU%n)>TjsxFL^G>+s$B3d4Glx$@*Qo( zmzu5euS1XIk#MtS)&ySqh|oh=57-CXTi-nc7zOVBS#2GGB5!kX%~MCIr`%Bk9RRig z*cAN3R0Uz43RFSMQA4LZU^f4MkN74SoFKQ7v=ugg9?r@B2O(^7{lI$+(VdWxo|mAN zE*%X7njb%Y{ONlC>C4fo6HS2%Nj4TNp)vS-pWIzsezIc|6R*~Jqq7=bs7zWwDfx^9 zzd!FRj`tq_{eyK_bai>XJ9P&B31SNx?||E_Hv-W_x34ePJE12BcI#{-i{|G}Vs|kr z{ui}_j#dkzSSv6}lB>pCfqV48rg%wd>7nuQl!g}v6+paoXlQ6<woxHn#(C5gbisp` zHf9uNqH>@G;6J9=tjuNw0Q_QDT9p&w<RF3^_@wo4DX*%Mt|dFZ5$^%~O6}A<VzSac zT;(P;hx}E`k@j5opVJSF>pb{r!-4_u6t6eHTyYPg{?EuKIdsk=LnhlJ%8fg+>VkI- zjf^ya5dH3*2{;ha?&|A%N=8H@M9Y9sG8|;o`Kcw?+i$Yyb5o3z{h0SFAi#@w93QX* z0fvVP4FqfR5kNq`uC5NjOJ?ZR*HKYXe-0;ty(szC*Vhey+R^JvzN$VgbmPILE;yWw z`O+HCuM7+%hkdnW7v8<|{2$S0x5Jm-z<w3<)T=2o^#4Nm$%&_Q)BJsRrXv7uubJ7R zg)*JYrMR|8@xOzph}ZU1!W6+Rw2l8amo8BR@621Onf@_(yA~e)!Bw6-gZv?P{l5{A zz=^oC_y7Og^6w1!DQI6hTRl<*orPyABr|Bs-msYYe7kN(msiKQhb{@!nVN;D{2w$3 zi-joTWbMaFb(~_>r|M<q>JE+&NF^t47D~Q!Lj@uoVGS-K4)&$;RAp+6&2DF`p6#Yt zs+-r`n(h9dy^rH=0c8hdIGNOo?-X};7cJU0%0<Tu8C^M(xH+*UDzwgK(FQF+ZlK}3 zsPtG-dmM#yfO0ylX(lqSv{CJ$WG(b>?e)*EpRmdOb%rxh6|;al8hz{<kh+hQ<js=u zEuijB+EfmLNP`;jFsk(+KWr@SkT|hPr+q{WB4ha*YTZ*o&a>LR0OuyitSUyMxAA8E zR)->_{@~>3e6ZI={?r*3uUSXMoqCPik}cni+8Jattsj><d8~UY>TRX<)SY_$umdWb z3p)>5Dh1WN9)`u*j_)MYf|1f2DYozTO9}7YW7l;`O&eDgTqKi~cFxnkUhzT_j_-7G z&ICItQMfGTK`jqP9}NvmwB}VD?lW4kj#miGP-e6*Lo*-LzRmydF>p)qB>_;*4kBH9 zG8WjTR;%$=W-g1W?6oyex;4Px79X4d;Q1V!h1(=rqp?18vrCO-5G59(;An|qLW6n% zRp7BQ*GQ~wk70-c=}hPwixF{5iSzE`{tiX#1n($>;2+vwAMH$9mAGH#)Kbg!*nI@# zi*KxLAkFJ)k_Nd_na`!oEqjBq;9XE5>zUB~Vgdp*9puJIp<AWwEitB;-YVo=Y>7#h zs4X(TGgrI%Qks{NqfOwjR|eXvK!glzh{#m<jVgHr5>=1UA2&CQFaNv#ktNBm;dn81 z!DiX@{+Hb*lY5bPuJ=%<%zHTCU|g;W*fluZoVn1kjG5o9wIcbsfZ4~@nR29_{q}M1 z){uxdm^j0Q*^QDECJv5J@21vV>~zKVGu-ywmuk8&Wn!Eoj7p<t1q`bgR``!J#^SG0 zZx>oOzuGL7Gdg^`wA8cK>#Bybdhx8!5669E;?K;yr{1!CV7_Z2BW}IW+jm<lN;@>U zsTm@jJwTcfdt(_JUX8!CRpWJ?tKs-YG?mgnzFKlHkXFk-U2NjT`YD@rEU+V0(u<y2 zvAM69y*y2z(9S`DZt$B(!I#>Ut&SL<^lE!=w{Ja57~Qm0*25P;9Bt9P^fy_~DK6El zqsJD~k0BXyUqNl~W8v8T($)xlUDNX&GZBlF{astyW555ZGT^1)<DRN|tdC*xj=I+I zRW}Dv*(AZBpJ%*(yg5P$YWyQc$bzFyW!E^qK7P7%nFweLLPeYA^KX#yUhGx@7~jqB zRXw>cSegRdl#C{f>#UT!kVE}XQHX?U*xdLnQu{UBk_K0~+rA=a_VZR}XWw@=gATjy zf`3&5C_yTHPpUkv+N%g&+E+|hb)S2jhTzPVF(_CPkHFy~$Y9VW7IczTkxU(OL;U(3 z|FBk}JI~mt+WW7seHVZBZH%iAX)jkPsFkl27`UJ?m&TtCYr4-cB{dvh9wTnc^%(Q* zRI2YQlJJn7hYu2e9nkr%z|p^!r`=gsG&u$1Mz&cc@<nXz_0B1>B2YM&R9a2$<l!di zP$?Z^=$N#$)%m}CFfFj>@|G9DSNS+q$9_4xsL$FHc3UPKcFA`CVy|37qn*FvkAHzN z!2EN&eNDzokSs)YY^KM{0M7InWi5D6)NI`g1!uY*&7S9Lqq(s*HulSS=#hD3HZoon z*jHI-V&(`IeZlk@+J8&Y(PB3rpPDdhKulPLD1O|9Lc;VY4|3tIC>IR0M|S566+%ut z)q^w~0NOV*_Hm%|%RW5I#ECUJ4(h#Z-2H$jQh#SvZ_aA5tZ`)!!!kfD2t$KBxPvoz zJCcvXp(an;oZ+$&PDEapxg>X=jX38)0o?663RevDxTk#|>wX|MvpNgD4W8bUVbVuu zp#InUtpf6V*eozL9IU0C;_kL+n6MN`7RpVH{?)ZJ>Py;F{PnxcSWq)?*!H}}<+GIC zuTSqjb}t(V^?v#JGZD_zhf3L+ah3JzTfXpkY`nR%=Y=-zN5pm!#+5|4l3@nA@ma^n zstQE}HfzZ(ylXG}!vlYR=3)q#ZkS<xP@tQ;@!V`9ZnSa?$VK8>4<NOJ%It1%A022s zr<@lly>ZlRWL;cJ(d@gmlhVe(okwML^u#4Ys$qXk8p8X(a7pZ9@|+pd#?ihckEqT4 z@XdOQy*tgAqnL2fi4M5R|6D%fxK(!@!tr-8xBs(A;bd*;%JNine*&a&`|s|O?Hbuy zk6Gg*W@f82UKWb>BdJ4T;;6LfR@<G{(g7F|qu~;yB=%{1G-cD5tWk)Ii(eW2$LB(R za@PVm{?nT*WYhKQvn+eeyM3t<ppa~JmO41&-b(kxhlEhfTjI40#ns$|E2IB-!vFlM zO(`;C&!-WAK*pth%=`f$nE?}pqGX+SF(V*g_kXMyH+LDU0j=pkT(RVj3iOXGz(uSl z{tMeWdD}<g|AqJ>zcJ$VIN-n+z5J>COUAdJh|E8l%YPmbHv=d|LnzF`u8(1@8>3l3 zSv;dzF(Pujyf8PhWTuYC`M=k$n>Vk31&wQd0qESv_j7Cv{r8)`R}uGvwx(;Xt*u># z)cJUd(H~aug!%qqpBnx%uLahXnY0?hT2$TC<TB3nmV90h(@7ZeX0i{9g?*e}aLI!g zo%H(82m6i5OgZ02;Z1E?!|XnwfV8#I&C#1%SqrV0tp~+ZazS;$u9C@gL<N%UmI5_M zG4_;-8R}ah?|_WcQjXnjPoM$x<wbrGmK2e?N12n+R&(|7W{D+va<xla8<?h$Ll<@D z3=wM=T+-d$p3)NHzHfA(^T8qU@_&c{{9e7qLFLJ=s7iN~EB{_P`N^n!m*q2E`lv<i zRrSHG@}8*ss@{0sxiweu8SgQ)K<_PyCCz*U_S5Gz!!6?BQ>WWPYCFZjD%l4A^-Q_@ z?D;L-mVO0(;nL2Z1;rEA&AjKc_U)VAKYh$8&ab^0nts7%iVHC`(byF<@!)73=7x+X z?S`1JR&d-*bR^LjGz^DjBsW?&D8JT2f?B{r^mSc-9oJi5IcuiTfpJqlJ4;fA|CT;O zum7Dr8oOVXfj1R#Gv$KODc5IM<>%`jZozT4hQtq)x6&(P!e;l)8$38k7Y$X|NX_HP z)KSb&YHMyKIo9+B+KVKVbYOS-QevM=u8Bw7UcilrJhnVNdgr)ug*sFV4#UQ$|2FWK z@Y{06UAL>WniKq1O^UcQ$9i|?_tR++n_o7atkVrRjkn$Pzw)m~jv5afvd(k|P6XqZ z17iHJFOKzxKl~D4^9l1u?%iBkb~x&<jjT?aN^hzyMX|pRYIk&&b#3sI9}|*~b1KdK zu#dcY{B-#0lx*`iEgAPCqmW!E;>PC47PTLVukT_dVdDi;Nn?!OY}bwDJde7DKw)nu z!?A&-Gw%R*s0OcVpZ%(j=|KM2Mla40=QW8>|L-ZtejyC(az#dIsLt}7#>CK%MEG0X z)_siOcunSCy}3p&WWIPpQEy|n5Dy`cCeID$+9HiRm@(rH-`?3gC5yVpo6f1bgRwZB z@97DCB(CZM#gM(p+JKj*e~Y=V${AN41-_jabM?<2R1qNcRD&8)SMMprGtxLT_u<)s zxw&?`ctOku>@m<?{;X13`mL@e*7F&GeW1g!t|^vvQBfuE?r<Dw(JUu>5ieKbwP}QB zMKEUes?%N=4eCKLnL8p9de~yN4jyo_@5qACi&i+KLhVtc&V^0aIl))<pm}$cPl>_- zTv2R;mx6L`VIib?7mYmFF!~@OfMn>ejaLXGMytgrhuDqi1waPPp0my=_Ke2Ee8%un z!UO6yOI4J((ekmc>g->&IFwMQ27jGNQYcv-Bf{oi1w{Kd`DC&+UnC??F)Q`4FHvuC z?Q<O~BbWyEC<-eCo4+^=duo~zyqOeuw`Wcph>IRF(G4iY`rnz-dt4nc#+=<zJ=)h{ zatI;V{@Q21=JSRN;&C2g|J3KdfylHRVJ}^V?#2G(lr0t?bvElu`?)|Zog`WvAn-AF zP)RB>?^?Fyz46{cHBgUIV98>B3lvfQG}1FYdpTIC)Be8T^r1IXXk*kh0#hjs={%Ok z_pJ=C^1xMw3-HB4t@W~@k|i`BF&rP(*bc%Ugyf@qUm0a8y>q2T?GdF53gldDOq%-} zweu($9WI?Soc<iBfm&(pt@#4;@k=+Cr4%oOF&YmpUFpnE+nlOyw6Kj|75&lb`P=BV zTqq@9-*W9|Zx=_bvkOsd%<V0!h5LR%qM`q|jAn#CDVC=|aR7c~()~~g(oR>;WTl$) z<CAdK{hDiq8UBPTvs}KQ>VqSS<O7mevW+a&h_Iz$QL&y*i-@nyZ!RCpKCYT(N8P4P zA*QXJnyoN*T9%mbY4H`dk`)LmH_au;Fh!N&YsOo4_au#5s(ysco*&z8UYT=wGj*!R z$FptSK_+w;!lwvBQz-TPUJ~YkAH6M*3HSlqP#2KR<kR@;`u?3Di4EJP3A`Es_tmxL zJ{p4-y5?oA!}jtpgEv$n*yCf^$)4Fi0xm9iUX(_g&AMR!X5<xQVqhpYO2Ihp*}&U! z9sYuAN_yr+(5MSRw!&LF1HT>0%@h)#(yH%6|Kg|F<kt}SD-|N3oAdfcs);xIt+w#9 z?<q9+BcIDYiTzSaHJ@KvDx>{25hq~Pa-CsVRE(xs)Rl#om;U~sIVIK+JNbW6_Lfm` zE={{I2?>N?A-IQNA-FpvkU;R@?(Xgm!6CTIB*ER?T?QE3Ver9iutCr4ea_j*e!u5A zYkl`0daZkyX{qk6s;jQ5dRtEl4JqrME<2M|_BRW6te7LhS!LyJCv6$Bed*j#S)7tk zfFR_Wv$AN@g{C!CYDkJMr!}rS)sh>#^6r}Q@VYgdIOP-;gyzAB4w5R&kt6M8wh&QE z0_2$iFOlYVy$7G$UFHI2{c($ac|>;~M>}E!r}~4QbvtdaA<&E9u(Twfc8t;Uj(Px) z@w0#^wm9P(%jE3Y^G_{_b4T<UvM~`SG7)le$v?YNO3FAAJ|ub12bt-iYG&ib_O-L@ z)>>8NZ;#oYGCckC4w_s^X`}h2vj1aIedzEvtUpy1jL2>d9+dA>E9ZLj<SHeGdZUDq zgLK=_Gt7b?@EO*^aYJP}WwjqmZ{dGfCI!-A+9lB^ahZ6W=)FSc9!q)E!bW$Fr?0W7 zuG8!+{s9#J>WQ=~emDtIY~FN9#M5tTs_j`UHsLLeo;(F6x0lw@@Ib1LUl(PrR^T{w zC7blVek?mvvi?f3P&pNC5OW<vx4IqqqaaLsMR+$PlI5_C|1$f~yE^R=ND2_@%-9z4 z^6XJEiSi8*c4h4N_RXhxLdk_040AxT6wrlW(zcFxZUDB^oJ=QX@HnH03y@ye8hJb7 zbSH{ll3`k!W;yyf1z&lmxyKjJ`)reB?RqlQ;$qr^`ldfciZr>A63lqCSyhOJ$)Fe0 zRZ2eqT5mC;e_7n}JY+6gxlE$wjKzH@n27KT4Ogqsx5dHwG}T}BBcL_nM&Kq~yD$J( z1UCoeS3ts;r`($lFLGjHn&vaFqCb4Wi$j-@_XX^yp}LNy&a+=-q`Hl?LZk~Q;dwcl z3x2d~cx8vNp?L)y84pt%-zX*n2=T!QaZa>)Q)@>U^lD2j^p}SJx?S$fTOdlK@+$33 zJ!)Dw4cTV68X<UV))kE}JGg`SxO5kKmOj&4GPNJy`AHzFRx?2{w~rqDIu{>*T$}wG znh4GNsG`*fKD`MB5hR}DvR65>RNDJk>1t@ArnFyL*r?yXFE96uA@=d{qqFININZ#H z^$y&}J@^WYq88ic9$y}=y3%`R2MTKJ4XV`Exf_0ZWnI5M3K;CyY%_A2;KAE$l&iKD zZ=A2bqP}6+lU}6OjhD1OGP5JDMQ3@Jn#IXbfk-N15tCjS%9z#7N^g-aUsbDL`WblQ z!ck#ks6P`X=7?8i)!!{papxar+?$OCde0=|aWj`bMp1&I|2#r1PSr$cHd`~lwTBc4 z*sAPBlz11g7rSf*sm%wBIAY+)ZHIx6)`CiP*{{Y{D38->^y=qWLf3;EEDLSQ)|aUT z-8_~>muk*5F$kh|NEZpg*|+d@FlY~Mw*0&yBoKxf?_&b{$w@_)(l>w(ij9GYn<ul) zo=vCqyE{$F9TZD)sr|8sHqoGIRlKI^28H_-dTN?uOg+KAYT{{{9eemv)`(uBAuL;6 z+zq|9^t!fQ;r{!Nz#T-wDOCRG)$DnqY+lSd0+D*Z?&10KH&+bA9s7mmDSnJjEb+`< zQHz0&sqKf#I*VMH-u~91+z28&GiTyrGwrV|Zy+tL-dIYWe$31_G5cPvrufBET(*%e zOW+#e%)5z{DmYV4-Gv-r#3R>iO}#|I#}O}K&VPz|JSdg9eX2h40?o?F>Kp|$W7e^9 zs5<U;S=*xdN=6%`qx5kR?KTt5dO7-X#$A9dpMo?A)I;>jf7;OToq^?^oe=oceXz=# z#}T9XB-$rcZr}B1-%r&>I}=L}sxA3`u%jjFc<s&j=?QnFq*T7iW_+ZXJ>pNYTG>sj zEXT+%7HTul`#jp6<_7LS1vYc6TipkI{E+9UoCd*A!{WA@cUj#PBiZT@$LE23(pwjM zxf?X}yXCP<6D~B_d#*p;SrdRteS&A}WK05U(XD}f{lj{boq$w8>Vb2S+8<hRY<1@s zX=#phPD>S=T=OJym90Z)*i2?2C<0zxi-#vgHj^)r{vSZ&uYZhf#|N?g4|~M)bE3HH zHUv^_GD5`DSs>weVlf>W9nF02^~*bB$TaHTOeUCV0X)8CcvyPkr9x%>Meq3N_w3A# zfp(Y38=A#>Yv|G+G6QesC?&?nBLqkL+g2cI#*k{p9LM?|UL!3E7XQn@3{7x!7?kKf z(fTV*$nQsinl>@x+>7}iTFw8q&y+Kj9L|&oLNGka{?54cf2SnY_h-DMEFQT_Ts3<{ zK!VoGt4+n2IH`}4Od&2N3gan~x7?zY_i3w*8vp9#gR$&;-d$C_+-)8HaXPMFE}CJo zm5Fz*O_?vjV!I9ok9*1o;C57-WYfYwEUnPcJ1K&&urL$&ybYC}d)4QdryVReCr1IX z&53o}omvk+uzfF;vd6=Z_qb-c*e9pwZ^8uR3hPVAApK}?H+^~JNj!;V*LBP@4(Wv# zr6nPe&WDq{6aUn(LkGY>b86cAnMcW;$mpTzi$3jQAy~9eC_O{d(hasZt>oYN82;(i zo#EZ?poHqi<>n)#z2QD!s8o2|b)A~m98Y$A{IhNKu=d&fx+mqM>zdvId1^`ByF>Rf zE$-w1%I3=`w?uWuvK~x70~M>rpb*#Nd?QEVQljsWNxpGv#i_JK!o~xewgEb(`MClq zFtq>lLrm>vb@EyD0+;QUX|46j5Xfe+B@r-E=T0wNYz<ZMNwdcOzY7EZ3uDhvvFK8- zrU+?TmeZK^RGU9id3o%!+t90>KVEr*4;ES30O;KyCoh8N9FI*6`(7uJXji$!DCf;F zEDTMY8*TwH$T#OSnPsXRRjX>8ZgZ{Py<1fa=ZH=am5M&(H$-oa0MdMIO#n>))r0iE zdf>9SU3yniH=+qsw@$A=o3#85u)$pqfVCVk*)pA~6eLbdgG#jyment<-7wg};7B%{ zfVWlm#LnxSK&aR^_vF$aM|-B)sQG2v#wP$h@gH=tzeLrSoR-sJVh<v&Cyn;8vho?} zJvSF#d%-(UQUCRGg_9kYaHeDBw3L7G0b_jua7kSt#po(lrlsO2SyCwVxS%}l<=4?a zhS1sg#6m3om^=9FCG!?;ZWgi}`eYUVOLjMPcS>k~^V9x*_toJ~E8x?o2L|{qVtCI$ zb-((AZ32_*H~H~z!BNT^8XWxb<BgRIaypl_$wr@y)m%eZlz5UhooAtPa~<UGe5SuQ zWo~3o&!=iQTD7H;mglYjkgGY8_SR`}W9{thbb=H7v>N}B$G;kPtxE2jIiX5H=}%4h zkRz(-c!WZHXBxHCbMW)xH!c}q&9{~t?|q+VI{q`_Sl_qQv|GpBtueHw*Ls-_nCzp| zo9U@t_^6hzSr3tdA&>J>3?>(Sqo3qTW!eSZvx1bjrOChCqu_}o$>xq#pOiaD+H>+& zKrKi%4xJXNGK*}KjUh_D0s{kJ5(1P%!Zbzcz3=pPk=!hO!~`4njg(s%yz$Del8}}Z zV@qPg;?)%G5S@IPuJMNJSJh|u8Ci+HCw;TzCY^?M^4iB9X9h)nsqq$pI?y7cWO)vw z-%U5IRNLi<N_ms2ajvBhv2BA?s};J_h+8N<-;)8XKB>8{9bBM9nL)7^aQRVW&Jh?B znty$Eht;B%Etbpet~&a4f%baBWdmu{Yjac(?{VKfcllkLl^fQ_tf1cuaF$<i(0IYi z5T`jx{KXUagvR<VCeelkmG-o6CXt7<{#3HtWloSAzU2s51r~B&L6cwt2al$@Izlz( zbr=w9m~_F$vHJDZWpdxeaX<5p<Wcy3w=+ej?`-;=Ixi%+^!c*k?F4Pn6PNC4rQZX8 zKr`JAJJ#)>y%ui4!w;dq#a{U`-y3di%ThSj`8-NzQ>^((g9QHxhM>=P3XaZ?1Lx32 z!wt{@J8$Ps%Ucs_F@wyn=^+#00_{alnG_~heqObBe3Nr}B~Xfm&wL+OOY;E>Sby;g zSi+~2Zr1N=@C+RS2I8xSNYxD!O5Q$0ylrU{X!=1$fgKpCeZqzsUc@CkmMNTQ>LU!e zE~MajP4ewwE{%9*<V~&<bZ7x7W^m&0YTVg`>IsVfr{SFeYfZdZ#iql>^K0Jk6=5z< z^EtPQl)+V%PHM^&>8^r(xa`?4q${vlaxq5m1VBsKflb3WdF9PnNs|GUwAa{trL6d+ z(t5VI7^UxOg|V=`%vxONWM8JH5`-DI_#bDe0&7TD-#}-y#g?dqMSPoLF{{4I>hF~v z;yUJG=J<$sH!)esjnFyowt2jo9eMHA?xxl&K^rZ_D6e&}6iOuTSS8$s(m9plOdWl= zA|erOe+C>P@cJ&Bn`%c#zD1fIel`Valvo%oKH={y=;)ey_(ZZ>9Yp84s>>IZPhNk- z#9nH-d!DVzq6d3ECB$TNo7((fK_q)hYv!SvB_jh(d0P9+ve3f1IOf(hD@C8uYFFvy zP#JeUbVY#w@;RWQzl5PoJpUx}hpz=iLo%yT9tb6GpTpiH`q$OLi#ytx9~(o3%6ri~ z{r26T5W()pmCGE1vTZ+&il)8+VGQjD7^7akCE<4mvFGWU@f~5)=9QaLGpf$plat0a z>!potYBbvYJ6&-+IHp44lPGvy_|de${aS@>kLxXY9o>bjh4=#=n%S+jskh~`ueVM5 znA+o1CMjP?p7i=kYV$GpB!h>vrD%9lj~yq6S?*|i$J~3btjaCC!e`lSl(|RKi9)>% z2<(Ng)|U~pX21PDfijBPtsPzm>?~~ZHo=V8oR=@o7n?9tR|Q*C%CS^BoUaX!w0Kg; zF~se?yJ;KdV|%_ib2}_1Md5fJ?cwlXwgRJ2k)b0Lx_r~#;j{+KG$&&QbtDq9HoOfu zuGiXV<`>Ta9Bl-yeP77bAF$Gg1cY5ps2v(E_XWsFN3&{vwzOEfCc;Z!p(dSr`Y@JR zpYQ={ypvZRny>8@g|ik_<8(?|tZm|4F1Pm*yVW->WRJxH8@QX0nkQ!CtVQfE9~<1) zUeRoF|FE5Ob*~E+ma4y4yWxZmJ|FI~C9Js<_2DerjJgD~{OaA%+IshPk%713ZVG>= z-W(~U3!wigWc*HdL$kovBwqL7mFxhm5dxr&yt~<X{j^goq6xrKcdsVK-5kbeEXJEU z+9*9}(^oovibI|?6hWLH8+29YX-rc+3*jrf0Qa9;3(GSexvZmZvv`2;v{Fd;&WZQE zn^=DAvb0%UycvnuKGk2xj-+RKLN8+=tS5c@xKZ|o93+^`2XnM}g|`&Ix9!43=3>C- zT20|ef2+-OX<|#UXeL>#M_hLzPB5>JRz6!2HSLHm-jE4YGi^<-C(;UKyi!|oxD=EE zL{-n}n*$GP4X(ZWU8$0H^Ko^h(q9ybEWS4~7Xj*#J2-Mx0vX;Mo_KI=8n1EHSDsd+ zr%{ZAalDTxPV{hIF_ylSBYb6nm`zq+PtZMgX?XpnP9l{Dr`qCJ%WAxSqSM8XdJzDr z7FBLQRb$>9bTK6KUYY(xgyb^~&{Mjtj1=^Jkqjf-k1;J3eyaCM>E2$*`j$&DU?@Y~ z5tW=)XgFoq%HWr$L!~1cfV6-LOY2F*hDDYol#qF<K>b1(Ner>9e3}HX{&`r)jlizb z@KLKSt<$O0nU_MRJkc-%S&U`Ioi|X^cd$ZiIjnyDUV|+jMkyH4SBre+vIugo6??Vs zg838NCp<)zgPPiU&u=x}y0gyH@#_%Ljfb}vSc??XS(B(b>AGm(m7TSoX>v7LV<!-Z zf4Lo@b*%Y^PU))bL*~s?b-mnMe37m{s6Dc<{;JHJEk();LCb1EFdUre!eq^rIz9q6 z*bEYFoJa%4<=6^{t!2KX4I8BV!r)>j0Zo;*z9%ZLxsD@D_8pDFL-1{?*X#{|f>*;D z7I(+>SOf#T?Z`An)7Y}}tky73BwMoth+I+pajNOLb0v?xp(s9S>dA5@Y8%Kq>JT!W zGBB<$dthSfBHiT-mm{(8L5e8Si2F?!;JRfV*fMSM+Slno4m~?1agb77<zRK94{&DC zDkLy>=j?HlelT~>+1~i1I`l2}QZMqnu2sH`k#DezTS$5|mF3dW+l)L3pK%`yLe5<R z=<Do-bIP`titjY;_#7;ynVUjXx;sQhEb1rd>$n9iIcRINdVy|j_m8JG`{Ipb262Go z9-r!$)>lKa`wMbo%^o-^i_g!^+-UKy(@5U&_z|OW?mu)CMF>N-Zd~m(57^O4l(8c$ zae-BtenAB%={vZN*oP#zx+?h&qt=~_JRpaZQr<zUIUm$gliH0+Z*{AY`S4wEfJqw? z-s9*J;beTVs7S%Pso)C-GTRxz3c80wn>~k(tjZBUDs2~}Jc3QIVu2H%uI-=gR6JCk zEAw$>QKj-#T2Rl&Bbqv1Q`Qs6c8vy4B&U1&+`;);%NX>ekfRJ~TBLcB{ZfUGk3ml< z+j&Ii{QF_A%$mHhjSb#j-#vM^CfY_KUu|Vt^Oqqgo^yvnvXp_xBzqIeM?c0NsDcKb zll<FkL<u7ZfZ7MOF0832ALrwDynU3zU9jQN;r`dxZz%aOHnL?Y-QIMt3#|~=B`tlu zBC|n5FRcKRfFw84W*xKaL!TGIBS#cr?vF&_*2xZvN@jz#n!B|MCUPI6SuO*(-FeC| zuQ&<&u(8@!%Bg`tEz8cV;99RV&;6y*d&shsctpf<D*YG6*81DAs&Q_w#XU-zy4DcB zK7Ajl`(;aoIfk^+lLVZT<8J;^vW=rA5KGA#^;`xjK|O8Z%R!lcR7<SW?Pqd6kFs9o zldG&u)qd0Ev~oRDd=4L&6rfidY+VK91pd!iyokrfY&x|Y>W2{z6t`$NeaUSo<M1fN z+p$@^B*iQn<5OxMRMKS7JF-^gRyQwOlD2v{po5O&w+<1EDQ^(bBGA*H*i^rdZj)iF z7CQmJ?7zv@YzVW)gi>SkL`t+3BTQ;84l7;aG_aP)n3Eo8HmOFe1wO~WJyW!g1!W|n zzW|Vk%}o_w^UMY<HYT^qVt0?n|71M=71iihkKH_JFUG+NMP}b02rcj<Vm_6)k2nF{ zd=tmh?s1>Am~eq%Qf0afN3)h-eYz$fQ1K-}(rdC){du^eUV)&}{WSPFstN-V&xnEa z*<1!&sEx34H*;sSpTwG0tv5FlJHSg-`BHm5VYE?>UE^6--2pDc;G9T9H$Zt;xSEL; zThmS|P3iPK7enVW^^S^b1Nx}+^x-asB{3@Wr`;?pFEA~>7@6k{0c(u}GwWbuEH!j4 z5WJbg$H2rSv!X2~L-lQ>y4T`B$=9W{{gTe&&s5OvN-)rtGJ5Esdj}W&;f)b&1JAsk z62G>6!f;_uVizDEY#PRSjZ}tNS0QZ8MgJ1QPM;m>7n<HMG3yuKpi=VWqEOSEoHwgk z59^rGTD(-kg#;TB<zbg~yRp-0D>;>HPO`P5N$m;PFSv(@X7m?YRqMB9?S>F<8*J4h zai?@5vAIpVz48nx3b+g?wm!ss_^tD{@DKKPLCCuCq<=gKmXnys|Cabp97lyc{xAgd zE8D6qu_o%W+5u-6TZcgcNz>%vvy4p~$i`NqGa=qDl5w?Rjv3MgS1XRF-LB`Gxoth( znkJPaKB&j8X(P<qePhC7$g=Ci?~QD>s}tqenJA;V(ECp|s8LfUOXz*5gLD>yu|CU$ zJfCchoi-L@P0d5aMveXch2fdKdo>^hZ2VBUwf<Afn%(b%Mt`*apmS=D_65CeFZb41 z=an0)yXD{mBl_<64Zh1t%;+VskG-L3uqYFBCNBoVQcPrxjKen1QfeuhxKuPY!1Dr5 z(zk8S26!w@y0AGm4;!kLeqk`(E>RgZ`vBBKo}b@H&6xJ{B+?rC8EKmeKs^09^5VS2 zSApT%yl7=gY7SmPj?2rJ3WE%S@0e%fw$2yuUM&UOSgqAB``WRrW8EN^n(Q4p8)>AC zpM6sF$clL$@o~_dkDj(W;7JN?Ewp-`ymOscmSB}>uHOfnWpYl{&Fk0VtO4@UCLSbn z-p7JtBRCD6^=zBX8G`2H3bU6ewNVO*Z&8sn&~%o4nDY`YKU5Et+obpM9QVR=BKo3< zO6H1&KiJr8_hht%^neT9s%`BV`8`_%B0r6LZ{ybM?|5LdUucMcAD)Dc5~+?eTc&-z z+_^R4O$ut65B#W;-0?alo_`!0N49_r0akjMy(Jl1fXH@fbE@ZzP=9L#5<74U1haRY z=&E>)`zlaaR^{L!rc#2L-Rf~rpr!u5x||UZyAjCY^w@8l6eW6CQblZ0Mu`M!Xe=+N zm`W&1pGvEcXo>5aHzwB+qBk%eDTs_rx3uo?k?B10F_$%Ej!KDDfNI8RwwW~49bw)O zWNE&JH0M-b7S}6ew3P?sUZk%AskA=LA^3GZBTJ&5(Jht}0m}y62;mqlU#_S@C*T~y zk^$hav1cc}I&p$UPf@22u;%Ql-ohA#7I@RjFUx3v)eH7TW0#Zq1k~9`rL|^+E8mf3 ztQm$Sg_G`_txa6c%*1G;P0js@hn13YBK4gn)Jz~sTT$tW_I5gEqQk?4!>s&v>chD; z0_WJ(sH7a|=6;y!B`deM+3{@#3qKj8wW!Dm`gd|zBl#<UK&1pO4RLL;9Q#mmZjALw zZSvFWU~{A7B+urgmfBK>nT{lm+B|ko@XNH%=c_{&Lc`0+q5KukWlEK!iiKk@-!L4> zP+1Z7g~GoM^yR`~N!hek99utSlayqXcu|~{&z&p1RcF++UYO`os*!E@<LOTjVaq9f zpOsrU2*dpWp(CUrrtg_TPx)fj_I+kHVYMfPXOT~K@i$CHOBdP|tr6Pv{CM-mP~vP# zsn<~}Ww^F28PK>^%@?Q#A3|b?Hcc1|fcE^%CR^J=OVyWj9%TfwRfJz41*6YM=q^w! zB;f>^?KW3}Dr>6jc-qRAv7QRu?&aEF_T*VTArivXcVk4aF{KSRgCSoAp!701O=o?q ztH}`!JF}|S7Y)b115RRx?nL9`_0T<1j+wjyH4!h_?18>8igGS)&dh;t!PMEh0hVZM zwHg=p`IsB2hlCt2QTYq?=0uR$VO_Hgf;`EvMV+l$>&bcixnMWMyKLR<$s6qg`yFMb zjQKP&3HPZ}=G(ZYNj;9u2Nhd;%P&ua8Ehmsbb~8KRjvjG245%EqBBfIJO=MF-a53! z4unRPpRF8?D4|-5{CLv#Q#8e4jd*FjKCzrzsJG+d(fHgSZ7(QOm2GbzG$+_t5Nzua z&=%pz{*F2xukvxr*WR9*4iT*JZBu6Bp7UzL@Kh8H6t&TpM}Df7QqM6hkF-{c1Qi*9 zR+#t<Z-m`9xZdNqs8ak~uRYA~tN;&=&D@*WX7*D$5>4pCq)VP)Q7djeH5vC>kvI@< zHx9h!%O@C?iPZGQyiY=3T}BL%eS7NtR%I`kgL;6W3vVXX#Rq?kw?ig&JT!>{gT<BI z_`daAa|V!nb<`OY-*b31X{#<wHkTD@Iy9vC^*lY&!if;8(U73VgG9`TdoLkOb!#>* z84eBcMkjTugb(vD6{w_hP4lnX@uQ%bOSH&OH}LH&oNykYp&DwQy+LBw2X$=9m|DG* zmHNP}W9G(tp$&Dj{Oo%}-PV2g_Sp2?>QX#1SYXbDpj9+uc=4LR)~If^>BMl7gB(`@ zYP=F*DfM;K42k-3BMX;O?XY!Mc^%t>av2e=DwB7v7(Bpv85elwQtGA%;{|1lX3M$N zi6LIvw1@Xqmv1cx>|jfyTSA6Bxb4h9b|#xa6KyN`UIePm=VZ30&F~PC<sNs2t?tD8 z-Fhn);msz$FE-}<@$wh^UlX_@Au7V%mWwpioeRNrrh8=ny8^^t4yiL{Qz{yow2?GU z`uYjS8<9zlK@bR@w~JGW!`8s9)}p7sKiNlUTu62cy51Xsf`O3-rvhvZ{VR@a^LVS_ zlm-`$DNvQZ!S&SCB{@9cS>XMCXW3t1TjjmT1^S)&>hGIbQkj<*Memy68VP;^%vU~# zk-=ua+g2=B7yUN-;jJ&cw8<G9vR9wYf4k29>awk~!k`4`O61=FgwnJGH7&gX9m89P z>G$u_Tb!CJN3+m-dyW4MR1CCF!9N#)$v-%s`WX%^1bLoGJuGKQ+{pwsoYc;qcwbD% zJ<DB;y8jt+(!7O7@(9ChSk7wxA23BK-1&Qht5(=JE9(><Rj{n`OVMgdJx=UGSmmjn z=asgXt_RAkD5gF!HwFTLPLX9|Qt<Lz&LpmB<0Z)kdgLimpPTQ|7rOJ3zxY}IJZI&O z@R5;61ic9%f8YX7^ybS`PUv`GO|l?Vv|f=38TKbxt=h%FL#I=)u(n*CXc{1=tI;!* zC>@3o#tL#Y_qm9i=pt{k)`3v*6N4xsT713V7a$xv@~vQx;|Dgbzf2Oovx6n7(8Gl9 z{NUB>&h|kp-3#CL*U8s^-iRl8s4A3G$=xKMqBg}fuiw~de>q7-srYkg2826O2QwR& zKb7d}`eXuwF6zOOD<9qQ2xq?E<xh)yO*I+8DvWhCh-hxF&M901f;wQwmGe%O-kPcb z{kLB&PhAgKJO88WulJeh&4)eOsr>z}%c%^7<fCF_`{l?tPxEzw;`6<FN2{$cm&k7z z=bGMvGI`fnEVZ1it|c^}YJb|zx15L89(N?-bD#MAC(|6Ji)`n2-fQ+#LG9j3O(a(^ z3AbDM|7#H7iCtRSWt+DlZ88Tf?$m%omx_dgnX6^jQ}4st>a-sm+7Z`oTZnLc_X(NW z19_I@iXUoVfd)B?K--hgySC7~OOTt*#?v#zn-leY{sLpaW<A1o$n5$8QaMy&(RKH* zJ%XJ3Vx!TUSKK9ISO>7*Fyl);S%3ejwqY@hIi-6?Q1jggMH6;v)_e-BCdRe`P@_$q z*AKG_XiOkiz;o-n)MEDn`;2(3ez#dbvm21Rcw={;2HQ-UdB0wdo^0RQ64AhK4yio; z7cv1$=PTSalDB6?cB~p45R?|vVIph{8Pu&$`msAH^`3_WM>^%h+CXgo>x9Q!axo1J z7-{CmJWF<V7q3wWzYqjUs>`z7aYPx`!ct}?l=hKgo~p#_8+ka<3BcvpKC{(mR28tA zpXv-V3g-0j%W^(i+q%&{<z`n)ZOk-4IH)PRf7V(ou3xMDAv)OA!M}XaKL9bIZDPW# z$1lm2?ak5ihw_h}UQ5NPiFH?MFcjQsHg_suIH}gcwW3bRYzT6CyR4jVJZW?LcKs0d z?|Tz2$goBD$a1DZ(H$uS0S1OBd}rlyvt<XKclKIsZSYa~?N3P2wOy#Z6pKXA)qN>+ zi^l$b$WhfavbUam(w3FgmYvnsF?ObmxJ?|@d%;o8ivJ+x`WaZ_aqnkB4$XhD^!(!N zv+x-FrYrpPI|Fbdp2${Tf8o{pBtNPDgy9qHvwp9PiGE)4W=@1RtgvCgbaV*mn;ZtE z)t<6f#(vk~5>N*+-n!V>c2BWXk6YO?=&mMs`Okj;t8wP~*Pd_g{^(Y__w8G7qUI7J zV6(r{(B64hL8Jb9Mw7S2mb_QcBVn;0P{;#eCtJEk#sgc-VYK#(YR)RW(EE?J2SUF> zH10b^n<JyiwYNV~4tW>p`b1I$Yd8wp@c370>UqkCRq)=D#;UzoKQj?#Z3o^N0((Up z7gXYep2tUK^fCxEgerSL{sr6KA!aB!RI%BRlY^93HTi;1OXwa)2a&HqMX@DpPp&K; znyp?4<JWKQM)<7HR~X=x9`_Ryy8HR}A_RU|@8X+y-(l3-=}a94jMqOh`Lxa`(6T4% zVXGbjoQMQcT9Bd?VcNsl2RWg-^@1a}{Nn5;S0a}wT>q~q5u3QTKH#~ih;7%O?JNHV z^&SyS8F*o;fAtUq^MYu(q=mo?y>)dYK>0eYk7q{LFoBgbVGcIclhG=CwXaKlx0<cJ zr4-NaDjMjbd<nbwG?ytUY2^ZPv9EfApqgh+E^3+++0!qwUhr}~vHUWU?9N=q_>ni8 zFkvp*QzcTb7UjPxPvUmw|Hkt+0lj~s{(yxk4w=iNW#9~BdgG7DpsgVU42V&+(=J=t z!Az;sa@eK)djLMOj<lT}OC~()s_H{Bo9oF6vkXCsJr+QRJp}nKLH=Jy!09#|7{$ZI zi}N`_AlyZc*8FV`|J8c0xV35Y_3JCH=0G@yuiActhRbTHr;id?me4v?q`m0)C+rKq zHWZYzW@@WIv>L8?LV)<mrhnbL0}{n&1AkXG{pYHQo%{*M3;%rX=o0=Ngb*tn6c-Oc z`0K2ft9VuA^gih5xd7iXvSEuq>q>{~XmN?)11`W<ZX07I-M0TrLk8%Kp8p;9V!czB z&`KvRzd~Wj_Izw#POh`vuuqclQPqBgTJ29xpUI=u+W?2>Z%t<!y~ufz7hOp3)482H zTw4N*UCDUvJ;NMHxTQ;mSWQo-MT8^2akcmiY^nd96aMc_c~+jcx!KrfCS9IHNie-F zr15BM3VB26>!?RnV`?@ke9+nCN#sqVd6Ifcg-SobyiMvBpYLky=-w@Erg}tjJ;CPl zMzxuS&8=GiBbkwpGJ`=wo4mgSqQ0ilx0>ogRPunBZ(3WuPVO}dGRD2=cU%|x>MxvY zZOT)4jj3?d&+sQo=!<B2I9`?UmNFcp_BhXW`12I20O}(n!&KB`SnKRD1qD;MFgKbx z+-e%ZSX4eQ#PwcsCB7uyQDjfh9z2GMb`r{_rdX!NrimQxSeiLp)0%9HIVz8E%?a!e z3WNX8{EWU>`;I|JvLh7j->Cu;`Mrj|wZ8TaXRpE*k?l?+?e1PbEo5!x7ri|AF;Kk_ z)=(`0l%v>cFvh&iR3?Pf0UGzq^VV>D1M*zA=BGH`6ZE)BE<G1!-JEq3p$&fZxUWZc z%lHEL?FLPn*<4fpNGVHqE^Q&6gokE2@8TCej1`1}Q*C8!XthDP1JHPJWQ>-&8_2p6 zl9Jf2WdBT8d0k^5FQ?g@a~jZLZoOM=i0&>frEt{Y+v4wR@NPPPW<4qAeoIV7dFhfe zd=`39WN9YE_@ckZ&H&;B37Wc3$yFTE0jcGO(O-G<(GvV`z<BPOvf7L(exm9Wy*-Yp z4%=AgX(LY&_V@MY(vpI1!D3E_kO*B;0_=q|F&B!(dacmMgJiYCm0t1oPh*yHxP9V{ z_-C7F<P7oUTZQP{lLke?m)|UEG}{x_B{#P3Gd#af4b3}K`fOO&EK~#=AiPX%;&=x9 z*0j`U^GbE3<hyQwuzb7EfC|)1UC>5rJWxgP{uD3~Cp4%TZDko3597Uu%;qnA(mjZO z8=CIO_&D;8t~4%u6lR}&9G;R$5aujmO(w}dLD||fqUqji|NL+0nP3ibu{Hku;zcUK zr-OiG^{+-rsp}1A4{EXNCCTQzodIBG@;IxfDF<>*Ngby`9BQovFRv;^xQ;y{=}pA2 zQuJu`BuUd4-Le{Ulj9<$YU+1S9ZB@D51+|e4k;J685=4iPve!FE*05iaC5%8?O|E> zIqGdj9$JC0sW;sVHH}76y`hK+B_wUM2EKLh`vnI%rB8mIF68pi8JQSRB{@v?tE_NM zHl|!Xn0?&rL9n>HBkzM`ebRkuXT83tyllocO@7<+f{4-WTRFy7Qn5i=b4pDWHYe@# zSFHOcE4(T0n>wqT$%(Ajk@c%7N|~YN+Av+0`5(qrPPeUEXNt~u*ms2wiugzeUpBv{ z5(PCXy6ekp?nz&E+d43&-QT=}+eP1H==hHX>(XiF2f0@XY?buWtbR+qBe0!=*F3Jt z5@EKKq*KyTmCV8kUnbn->~ekIowc>2`piDO`muj&a{ntt97O$HimQ|_&Z$ssw9Rz4 z+8&Re!Md?k1+D$~`sho*n)H{A=0w-i(FZ}L=$3S1Z&Nmp$2CI<j#-hc$9t}oCEpa6 z3-J13Fup><4N^Tb(a`()|Aus-tn@!Bv6dZu_Dao=g``*(Xtu=J)89fnW09}_2H)1` zAMhs;0EU_g1vQ5V$f+&s?~hjaLJ*&DL*23;?F_%-0jn-I*xoj7x5!5dK1%RuqBC3; zyRF?-Mjo=niFZXu$uNwncM>HBX>`iGpub(tMGFW_e{G0U!RHt_>!{87)5-Ei5HM{W zFyg|?>_Re#_>=4D+pM)_S@4-rZ9D=0ZpL7;=UqeYuBq4fo_x~{%q?tjHw(%(Y(#UQ z_Q`5V(`)6D@u*bger`aKJ+(K4_{0e6X?~;woV5fS`V+I%pUw}76DH!0k}~$6IxliJ zw0pdA?^TwWRdpB@ELPe6WDix*G1mfGr6mrmEtEsOoOnDZg3r#%mK%!a$m!RyCnB1= zyy>LLK{*24c76Z_A8L@<Fe&Td>BUk<p!zjqV3O}Zd0%47_ye(6jax=B$!DW<YS-}f zgGYO47lrhI?FVq)@tGC6Z<5V^_l4!QqL7U1TS93~cTVqm#y;*nx)pO5VHwnZb~k<7 zwgG3v|AzSn$PFL}Sqlfd?)Pj2M&UUN>s!ImM;jMxXEa-D$0{d9-7E=pIs22SCBml6 zHHnqu!G0rl(~H{k`6j<#6;IHLW}mp;^e;hg4W*g+T;g4fqmA8U*^dgQao9~?gP1%I z2WnbW(t3P4QZ50|4=E6Lr)v5_%-Ir>UZh*bmbo)rj~i=~sqiC#6bGZdg>|soW&NU? z;jwJdXTgEVi{qTq#<<)@rV5>b_`^Q7o0j4*4z#->;m(3fLqgAoS4>dBaZI}3`ogHp z<HV-Xd&RiCSd*H~!tdZyunB;zQ3kUpotQBGJbhMPe8x}5%V~`x&-qe|2CA+l%8Wuv zOMeBT9yx~;ZKI&sa)u9%ly$7BA1dKKcI8Z=p*?!S&I0uB%DY|BFa$4ST2?#0^ljo` z>p+!-Y?h*%iQ7O>PEoqyo3!I<EhW@LS<sy3?oNfDeAEo5=Qw{IK6j9~^3Q7cb`WDg zT#((&Rso+nXXB|YTc#w!U+SG64`;HrHc*t@*n?Hw7b93v^H~LqF|WbEhKPQanq6YA zu~Y6mZi{eCe~#~a62~b_Q?-6;lizGuTX#tvX*2Jmz2kR>-=Ly?tXth^dwkbT`%SM~ zMn!&xknnWRg&zgoA}m*ryY3{tp|~k?Sb*Nz^75yq6ZZn&dyBzSX(@4?20aGm-mA5v z>twfl9pZ5MsJ}Ks)zgN&EgT_B0Y4%8=u@#tvMJ#-cGh2wh2zlkFwf9*IO2*=6Mw+* zgjTj5#e@qv{3QxTQ<}JjcYj3e%7i8Ldtr#O>#v5y<%dsOiTxL9e8YGT2<21zgW2}U zufDK0J1E*IR|=~PghIa0MVvS?8+T=8;^2?IS^K~w^iyz$P$P(vJK`N%r?ywjeXq-& z*rlmih-<_AEJC<?ssKEE8H36Cj*fX|zdLY5H$T69@cXhZG(B0?7Ei|1P4eaS)mo-X zw7u)HDZ$LiYpc=ck&E%)7MJ=k`L|;}I%c(<&<fdJvf0+A_K=g_Dt048=!)A!?S8%* zvmj6_P(M`h=)KG{joSX^VVQ1;>UeqlV{Rggg0y}8zAm0nC4a$wl3lgHjfv9rum_Ex zBUG0BM6CFkSbx9h%2nhNKwD#^VtMG%`6l2B1Q;mBa)EO%Q!=&D)Iwjjhv`(-JNg6q zb)T|_q41l;+th5Y&DfrOI6%;`a2IBbx|f#ClE91c)q7@$fsd`SkG-vPBCKP6Dcq-Z zhAK+w)%l;nQl$rR@qaeKW`;sg{%XIGv2iQ_aNO85^jC(sp`kOadkFhgb^Q;5$pZ20 zjyPo46MytV!-m24UwRj@h-UVt&@H4luo*56FqkpBmW}XC*0|o9zaj|s|LFEr^esKO zU})*{E$=E<B@)N4w&yH+6Fg&AU(%&9AjcaqyENXeau$DCk`9a>N249qc~$wVIelrQ z<wf?K2IjBK5WNbB)$qxe;9u(@aqe#0+-%2uD~%2KF~h+e52z$k_I0qmeuf<?p<{0o zq*#|$*1egA<X`uJ8PfD#%WBzy5KD2-0o>NTdFUI8Bz(Dk`|GKX_HqVP<#C-;T_;Ju zRO;Sgknz}_-!SsUI-&@DsKlF2E>yj46IKM*K^Rw>oi0$dk(VX2aQ|k^+J+&Py=?99 z{NUw=?o28VB!k6fi&R(VqCvx|^BJL@n$;YdU3%ixc~RxpW*73Z3fxKtYX96@nyMdj z$(O9I6W2YoKS=%~L|WYOOzQwB*ZWz>QHAS`mji*mV)^=p7QPKc=aP?JnEj|r@W3&> z!9n=f;uK34O^BlJmex!A*fc;mP}*3|pSXJ=VWzV`ZVazG|D|tCOHJv!!1K4<!JJva z4=Npin~$tIJ}eHA&1TGnOxVS~qU($ZZ9T}-y&-QEpp#O^@_6kxJ+}yAR2PV%ECW=n z13-7qtHg8ED+iq{&CH5HeI>x{OZp|6(SX*RRGN91C$E)87^=0r$z~lc;C+VTZ^fb= z^%xWotp*RWWH%YsgQsUYSgZ$C&lL-LUb1-KIKfN&jKGUq2u3_=iQ#aPsGvE*9YV=e zSZ5fv)V(#Y_CotW)omf`2bc{mCWu6Ln~faXLnGqgZdEK){mZWmCNzc5sTDKvaB|{y zVJ%>T{_p<H*DQ@$#t11!n+zsvou5nI$FtPU6=B)1+HD=a8GJUZZ3U#~i`!v+;q(d1 zOszoPlfbcQ*wknDj8e3SR0c<_f`A%qZ<N$uRA`|!vV1T=kEC@lv>b#A|2-Dw%yG{} z#!I44gh;(1vlVT_5_YM^*mg*L<A(Irm+t@_+Z>e*Uk2wTzniXM!Fbc>jTg*bPh97S zK{8VkQ&Qw$h0`OS)YluEml=ej3Ij)uWrZ4z$WYK1)_Hl2wiw9l&&ld14&MtvR2ck# zhdoge->Zi?I=4uc`v+MH$XHWQRF7zjZ~3<Cb|o_JQd_E6{R6X<<vJF5>j|jG?V2+E z;xpFo!WWMki%39cMSauhL$`*;S5LZEGKDyc<TH2!Lh9~@^({?3rpxxXc)q{PalRu+ z(n^+CP;Ng{_EN+k^@_%iuV3#H$)S9W`cZ4;AfK(D69B`<+}g`NHYojJ{U`J|-*7kF zaGiHeAV1}##<EPTp6PwyU75H09v?BAiiIrpbb<?PR|L~w(Y}>nd@oUxhf8vD)*WKV z(8d{BN7QguSJjQaY9u}?8-7Z?AYaN+cNCCG)r>G9F*MRg6=~6?^Vas0e7F7+APjAf zqg-ndQnUM!wENARd>}&i=d+*AB)5dosH%;Qww(yW8_Y_7h}?5#IYp@kEhd+PxhH;$ zhug`zK5Na#ZS?hC@Y11MN#s7)KbNZP*19G_3i(|Qt|Q1x#Oy_vYL&QEPmkir1X_<M zY&2ku$dO|3c$0$*Z|fO9GOsc7*YV#qUtjao`6tWs{Rha8B%S5tg%o8PlDhqtPyar# zkfG9q>hQoQ9W<pa6wK|i@e8KC1E_({-ClS#jS0Se=6aNTXS(ayQgg=?Y(gT1!1MNI zjJ{*&VG0Cu0xQgrX>@i?*|)TMaO{_gvr9dES_rIY;Et^@CZLS#V-cdPeTjKpOrXl1 zx(4(-n_6gFYIVo$P1@GNQlGRmJ)d!bFZx66FILC))iUtW7A%UH-E22ktG#i!nIh`N zuS1n37(2`jm>elf)F04dC~h)W{=<_K`8hmP;^dq9wijMLBNfO)XgS-`&Dv4<8dm@7 zXY9u$IdPkk$(Ner9}m`MC)v+lGrf3OtVd-q?H-{S77l8h7XHqM_l}1r_;K;#dHI2w zlR`Exy)g~@`%^Kpr4u?~lBHoERf(}uJn(yJA9`Vk%CDyeC;fxr%j9fayT-wXAb$JT zCpb!sWjb!V(TQMWkzG7bY|dfE621gEJtJnDGNW@--rjik^?FY?{r%Zt!J4aqW*Wvh zMlLj~ny|(Ql^HD`FziV@MwyBBHu>=K{gc4@$B(DuqQyU~=gQZPG{ze+<<`4%0O~$w z=wZlttPb6dRGTn;g8zn8m!EH{6_`YK1jpkJ+MbS&j(gR*a;mQ^n3#9q#$KG*KlXVR zgCYB*pp&JtgrauessB#Lk}6L9j7@Oezadb6hoK`)-?Q$^tNP4yw^B^d=KG;YL1Ub4 zolk$c`o3DG5Fl((*J$Sf&Fe|~K-)P+MO^IJo8=_5?F;n4#;bZDfy2q1;F3i&O&7}` zKTigCU9^GInH85R4B<CC_28lG5ocYifr5z%=fezAC)@Rtx+*m-`P?3EC5^%}2HB94 zk?HWg-!9kxDK>29V>O+O*Xu}7=gzV3Ri^hfq_9P2d9gu)#VV??W;<$04d~dI1q`51 zn>kDQvBOO`y~Fm_p`XR<f+upoX6kflz-%;-F?ft|mBo=ua6k}<bmC!=cGVLuAK$zX zxqceDcd!6`(p|0TAbRluEi%pprZu#P?+uE1C!BQb7VBTEyZ-3Hn9Y;pJ;+gk!1Mpb z9+llXbbA{#n10xj@>jdkRCG>6@@sexZgkSh?k1r|%+`t9IW7VS<l9jxc)@3vH?9Qn zYogGYP(#vXv;KRT+sQ%ZD7yV4NS5){sYL1~qZp~jRC{8<FLD?kC-mBlAHrf|OEhgE zBy#NcURy}{Ye#tG^s5PfuD<t4Mvc7X8k$c9i!<Ms+h<QW+MMopN<}p*0C^+0XMI9! z&C=sZM$}O#{mjHEBI0${VyRv2u9^U>#b8kXhz%Wksj)F!hwbDHKG7(>X_yQ-9lk^( z3UVj@>G`?{N0qtdvVZ6p@ky+AgJ6dTmApG*Y=2!z29^Xm(4!4}{>&Ty%H*pg4Wq#$ z@Ns>;0^z@VTTjL#s=DevJ4h|2Miznnf7R#<)ZY-o*=echGh8(n^-uBkdVRakle~Gs zUyOSCRNZZ_Op1cIC@RhaxL=fWrr=v-g>XU*$>a|DTle!T7SCtkR7GyW!Svcadpi(R zpv{_`)RIFm?14z6K1rCZ>LEyNQW$c081Z8P(aU{2L<{11V6%z66tVI|iXgEi@>hqY z`^6ppj@CFY^YXAr>$Pp_coBINYW~S+8ZBYfE~?4)XFH!SMiTAkjS2P4H%X=zQzqb* zD>vf}{5yrE6cwL-7aNqFUQ~4E{5DH6+tMAm_8!+1U8ki?$v;$7<3C_rrEK#w96UTW z$8G5}4)cI=+d+Z`KR*PE*|Ml!hl9@D&Ol@d35iaddc}GhZFuD{1Ufo85*|ChQqB5_ zTFco9ZxZKU$D0FARsRq|l!iI9Q^W?9GGh8pzy^)XhXOjy26Q0hm}dg@IMp8BnhVx* z()G|QR>q@qam*|nM_S#xmG86}f$BcHipDEz5R==PvKo!!Zp~!S`dUZ3D8m-{$WqUk zJEI%Z6~^l_GGLT4sB3WE=x8locmH&(ldEO%&=qM{hvFZwM4{+cC7go0csO_HB0Xs| zU8D>jVilb7MkAM{rD1xwP<wX=1;JmQL7{}gJ_73M)V8A<wHCN|5xGvn4s|I;hfNV& z?O;$$lr3~&h~M4amqO){$%%KCJf@k8o!^}!+qI>)xS4B}&A^<9<Qzgn^CYqfZKozI ziuCp?F#BE6D8Y=jU=T9sLTyMmy%CU0XL#*464(OR&C?n7c2YDrV}^`sb~NOSqk+#D z0J;2?b7^Bea#t^ZU&&QP85s=p92^NMr5g6r%Brz(aRG~mc?AWbZ~~cQH=L@RBZ0k8 zV=fBk@u*c9g+aC*R0ywcrm1&MaD-M)1j>)JB6Kf2uPZjBocMC9y(6I=hCMPYEPVj8 zN(IN>rAZI`pXwX{*Vnh>wlLtGnp%hy(Oq<ZS4&I(Ap<;|u;*GFONoiyf?^Cyszh*g ziisqay;lpgqkMHTFk^fz-ZpRo<=gNUvEW_IAOzTft9+K~w~1YD>L6JvActIsKWfr$ zDY<K?`lYg)D!^q3u3>z<y*!kVmEG>}M_h8-i2932_c;R3e!sLn$tF27Q$|GODZC)< z2E0gJ4xH6UMNK^pm$aAd-O%bhXTgvLh50zo80_|y;f`%$anW`^Vc#5h62{-p9b?7> zLPbUfiObQ_;CE7fvxS;M)5<$V^=xy3rAQMBT8*@cFJb?}AqsowsA(xFDI0fwMKo+B zX<px7fd_%W?n9Rimu7XiV8E-*>cb-)O0*i|3JTtZM??s^{uZ~t<nECzKOsY42n+_m zldM%cY)LveIu>d-b8)4kr;h|rTToL`J?mysYjP@t{EuWc%#IU-gJWY~)3|MQZW`ee z@kv}9@f9APn3@^^1qH>opdc(9oKJ8-M_yk3+4JXX$H%%Rat;aX-fu2w)n2IcC5l`< zCCfa5`@lO0Y*+aq$}?Fzq|w`AD;fKqIa!%yiwbt0GlhQYJQ>BWB`<BMYSu19nLzIy zWa&)i7y9P<ZXLxXf12v^_7Z}|%;4~QFLq(ewy>zYh3{LM|HFv-gOBvqVYCpQpb#>e zNy6t8I+D(<m@O7HanaV+_E-2vv8IZP3m5#r*xcT(G6v$oYXr~3(<zy9@(%q5N>tYl z)b5YA_vvR@Xt<irjmU(qG3rNbC8NSr7&b_q<c4yrd?rs?qt;Z*wn99dE0ffHw|UfS znuNZqgQ~k~BRkm-In?g^0SN+p|8TsrbM{lS8_3F2rWbGRU>SVR<SO*2v^sn->AC(n z72dv0EEKsxU9#bZ7vSyQa)9rst`hZXwKgyJMq_ZBH@weDi=!Y=G`#F9yapb&h^Qzl zTA;;rQEWm&54`3ra5|AP@*Uq)TY4KSzI^`)gTNChp309=1%^=GsxGR>6N4l?<$U$8 z&aw@tl;0LUMukBy1nptFY_n{XoIwlYvtyela>K(>+eK;C749?f?4z^?)Ja;tew!|{ z`d17I?8Cif!{B*q>mhd^<)*|xptHMu<=wC*eF8Ox{vy6iS@@|1WbEzjP1z3HCTCo; z<0*g(TB$~D7yOh~Q@h5eeTNy_;EjL}deP5J5kpkn%x(n22p1^M4CPO+xx-QTu6bDj zR!=<j{~x@e;<JR36~a$FGE|L=UP2L35VN5(P$hub$5~I>3`jg5WCeDhc&OGjsP)7r zzkmI)TyTY!$axDb*E_)fK3Uw|+uYMau4*GiD>+0_YE=3^VK?d~dy_A2^6>&Z2}MnA z^dg1%w(=uJ()m{TS30NpG4&LBN_xJOU|T@HF2q(J!5xq6UKP@9N%>q$(h-FZbJ#`W zHunnQbVhp<uNbiR>^H*6YSQ+i9}|+!B~~O^5#XF5z@)E_cah9_uMk~81Mln^I5JM* zxM+f0#(@nC$xGG0mJ9z04L_du$=OJO0qora{8=gdD(J9!XdcvTG-ks$Tt1z8wCOmb zkK{jJOCgXw$T(_=X(FGr)M`C_&3(mjBVD)3z9E6v)R}qftCgUqr+b3pIUMJ>oidYp z)ZT+7boiP~docn^gZzr~QTgE=`<HQTo@jjEC`va2f(u{oq}1o)<pt77Htoq$K1JVs z1B9o2_qzN@!${sQS5!G3MP(krgG(CWxfThErka1BYG0I<czNd=9Zli#92yq3wjRNp z2Zv<0lF~RWv!?i|ySuw3<m71KpQ+xF)BFDgOPr-m4a{FLcyo;!gyb^T&xWsEk%D8j z>~*eesS<2t+9B0VG8OYoklyc<?r)~VKJ>7A&F*Sum8e`i`ws1R(Z|PZYPZi!I8(rX zs?t##1MzK-;=Ur!)4s2FYhDY&$!+UAj0mn8vd-1XbS0d8P(=E+&{5ET$k+#`BoPRO zT01yQ&hnX_ZIKDvnBNfU)_5e8`4}s-n6O1)a<2|<Urj8vCY8^&^*`m-v)QOljAnaJ zpTV#3ePh4Q*3S3h%~^PHoJ*O7FN4wL<#EO5t6vct2oZIdt81Hau2Dp7$*h}j<if^- zlv5z2TZM?*FHl;?9@o`2v)kV<-MwYpw}JItgt7Xqy?yYyhWt`dhjz-h+#4AV*ZWc0 z=Cel5I!@RwB}@ovW-&F=mH<jQZV2P=x|dja<no@Crbgv%j=QlN8IrfE0Cz<&>i*0J zn~0U}j0Vyn56L)d?ehLX$&Y2vlN^-r+u1QIYgm8D=Xw;m?Bjtgrc$gDwX~!qA|k@$ zbzNb43V4%9Co%bjUE@rt|M=RrS}t`d4|#edDpKNRWPeA(@&mI_lO53{pC?m1jG^pj z^0%n?#9K(5$&I5j^jUB{QSYXS>gq|!CHLn4%L84sv|NEC*foc`vbokEv@~l(AouB7 z!A_6L&><Y99QK}^`>1~z9Snh`{lqcx9=TFyDhhJRH$5nIa#HIk5Zg~{h3A=wNbkxn zS{Z*bIT4G`L;#dJ^={yQpk67Q-JW})M46UOBq#@H2x;J*Lw40?8<fSiTX#y=GjaS; z5VQKD*ga?3wS{0;(+BduD0|DWHn+8H7mBroLW?_X@#5}Kg;K0Qad+3?TD%l@4Ji)A zo#5^e+&zI5cL};P*LuG>JHNH&yZ8Q=gI^rU^Nca>dz|-qF@Bl4`}J;6a^=vbC@OjO zoO+uy1i^OZ>WEtWq@FcTpg9XdTd-T&F0=UkpF8wDDWO(D4n+^3qNNe7AuJDyXW!aw zR@BRcu06lTjxrJ0iz(wNyuJ2vU%Ou1wQ|(Im&MnSmYwBFbIRt!tMiG&GQ>Jm8oai! z*fn!JmaQD{`j89P{`1uQ{{2YuD>(5;PG8^0tgI~LdwIxu1xUW0)A}54F`2EXFa7xC z^YRzYI070Ng)q<Q3w`w>Wq|^&2!-;=DiP$NY77bg5F;l`F#QZjNdvL?=qisR?lAw~ z+N)byiF`lAod?h4<2n)7g2oNfD@$?nah(s-w8JtQdF;~)cbS=Zdf^t_#m<EXdSkiI zK9&zZm@U`9Y184RFB=QI)@&IV_S=%xnF+B47=@-gJh96+OQOkieW|h^rMitV-Tn9y zlb3Fq(}CC|T4#&IEh_Ez?r=;Mc|!i2f;@&p5k59?r++sJ4z_BiKL&~X#n>N{exwR~ zC?L0Ok>cbL9PXv-Pgg;nLL871`B@m}Pl$IAku8B)yYBcvSIIHpFOc-*OS6I26N{#2 zAD)B|buRWNcG5qJZ0gjK=3)yJ&N@0NKFAcjMk@u*eZ`b;XO93oo{)1)G-y7o3Nhs3 zk!E8`sjT|(JV6$M9@ia7h30x>;3zgYBCTp@D87-eDnMWo3g36By5!Bn<!=>1z+&C$ zc+F*|7@aZ7-RRt(JfKoUCnvU?r0z*)KS|MRxao_wl#*himNqn4M?C%#rZ~O?v}IhS z%NK0*@5<aDWXB2Eeio2ozu{BaP-bMCmND56>Sv)K5d5VvrJQh`9R^#}sYfwe#&t=< zM0W4|S>&ueqtd!{1DHC0Tpp57Cv7#cS6O$|t=DH{&|dQa1yQR6(<mXYbW@Bs7-AlM zP9GY1AP~%!&MAXz<`S2uLw?Ag3{YNpZ6bSjKt~6Wgui`pj631tQ3`T$Cdea<^>R}R zvJ9(q-cjYZTOLB5JB935znY!3ekK&?(vfin5FM~@wNLC&ujeJKIJTL;KbReHOZzrK zJ{o{0EN3|GAoGBxm;aEvq$pxqG3l8F<$7;Kz@^iSlxT|q`CP^nYlJzuad*NsRhivo zxT3Tk7p+LXzp<tUyGveEU%=pfCpNQ)gW}LUj1d7j4sr9mzk6lvyM1$`H8$G!d@!F@ zVA>+6<k$1_!<{WM_eUh?LGEOV+d$eZyygeRy9&4I3Kwi9dznP6vQ)hbMN(DE9!>}U z(Xt~F_|JwH;D|GhEWwQy&-OB&2G`cKwTN!etmabHz+?31d9R_W?S7}26(|e-eT^>7 z&na?S_BGg>3Zk`$<LP=e^Sx*2*1yrGF$pfvGV~)i$?<mci3$E5QTG`ynRCI8T{lo7 z?3qZ*MrVXx#T}uGX7V|{E30o}FEJin=EI*-F4@2uYJpyt7n9ok0$Q!mnPTT+c@U&) zkAvIEH+W`ev60u*&f^<aqC|f(D`T>VwEF#Xyka-Mz(pQ`*x$UrFc2)9p3!QiRBoZx z#$xIx5%P!3L!SM4%|}tvh9$kcMCDR>Ux<n>0;*cS1(9=gA}Un$GzlRFvzueZCt&|K zRC&i9&UR3S_Hw?>@l*jvBR0r}2Rk<IS!y8mcb_=L2zJ_+t~ddzQJvp*H@UuJbEcl? zhrMvZ792{K!*hgGqBdouss<USrcH+1Aq;y-ywWnhW0Uk-WFx$KlVpd6gl~<Nav!V5 zRFJ<F9_>-@j%5{qt60hWFso7C05IF>or=B7x>0X|e!wjC3B6ya315#spXAu<$8F&E ziV*4Sm`xP@hB|n~!|6`I{=B~Dscw-9jq4R>#$3jm?DBFRS5#8e_acuq(oY{pv4R5{ zXKuqaZhgdUU9b%@oTHSd?#%y_USGK8a*NPH7pS`peRkIPH1>qeuFN-ti%gssFO;e3 z;5*bqGu(7>=JbW|tTJiqKE3I6hJtb#7OelRQ;Cn0=*^St@$o`31RbsB;%lZqIy-~m zs<-Caf<dm+qW#fwdYn8Q{wMEVHunxw@Pw&&w!luPvXP0D4*(KjuHNl%krorh_POTq z-?oIi(%<wL)F=EN*Irr9c^0v0X@j*k3k68C2)Hu)`}gm&b#^q!vzpl2Im++0p8FXd zf#XdGo4fc#P<Q!6?wP7-@61o7j&4@U_L_+Uv)YA-1@rErBn~JddZ5>HVC9|S{JY8P zGv#BW{ECYks|rum-(8#tY~UFThCCGhQ4X-HA-GhD!!YtEq*YZDW8?C3q60$eVz#+a zvHg6WAS)AbKPD7YhJGQ>J}%VGsDd`Pmp@~t;sIZXi!S6%OvViO_dJ02`wIEqVP`kf z1uaR;!GCp1k(v>0WKE}`uHJ|2iz=x5e0lvE1zDqumumM*$Gk#{rM4Gqo8nc%yYVFh z3K$Vtw^iD^J3?x|gW-L8JH-r)kS;U&zZ*^N$aquo|2p;}KmB(i(9xwH(9imbv1)cp z1G%9@4<>x@Fc229g~YaI%%7{-E3eAJ^%eOsdLeCp?L5ax%8tjBtH1d}n!ifrU+e!% z4sto-o>0T+(PnK68wR&XZO?5rumu6O$UMjV7=`RC>Evcukwn{}whDV5Zs}~yK<HZz zc;vsir5C0f9A8o~T_LL(%&J~_5(EB#t+$2I{eD0-D5+ikMB-k8_Cj~@@@&el!kVo* zMo3lp+tT#RY6Z?itxF<}j3Be2!s=l<=UyVg$i@5cqr1fzrC%CbID!eaw{pqMUKQmG z&n9g3-F&*me!FWf%lbQk__xA(9%@X??QHQdQCckJ%azx>-1u}@MU+6fd?RR%-5&1! zF$o>J=hA+E*_A&Q1)fSP4f;b=(nbq3={k9xUsG)1iESW>$l}>JTo!*X+Z1R34nZ(; zk@rIEsx}n*zc&2kJoy@1YBtm=Sh{a<nqu8<))U7nx<#q}!GY&tsM~iA2u*t!pXH6s z{p$oeUvG;>2ei^`mZd7NT`G}L6ELifVJ$Bj%wlOoWw&~LBH}yly~?rque#6v<_hCl zZ1B(54W<V@xZ1q{4Svgdx7WBu0eI&8Gxm8^AOXeXH(`DnNbD!|ANK53+}J|N{9*42 zejckZb_#3*&X=|g?a~I1&R9jw5cvBm-z4u|sEdV-e0y*=d%+|0LTzF=rtkDtgSXJ( z$&s1xrK9K|5l*9U#I0IWchG%7V+Nj0YDuTNmN>!or6=)Sw|t3>&l@#IHEo(w>__5Z zzCVzEF!MJcta^E7hFh=3ZRJZ&YIcdK-*sr7^ma&V^Q8QKF6_sj4|HGQ6^R5`^!@rd zs<tRCWozJT%c1>|XfctW{1}D5m*-osSgBpJ{i`Ai!EVrxEgg4$z7k{>5aa=EqUoEI zp{3SjkaE&zmikAyXwL%<?hAsQ-%{OGNwnsaUgKfj!U9ajYr=~=u!n|jAoZeazv9DH zElZQN$d&)MnTdapvPA6zhXU*X&|=F=g`e->L}*~=2E4?6@8nHP`<T>oexw72);bH= zW+4Z*oT{^CrD`};bEq&d((>xPcG!q)CN#y#JnE7`2$n^w>}V<bP8}pDNI&kC?2s=Q z1nyuuObu;c(q9ss?SxqK`K_OYYfVL*<Y5|uNF^5`&2AU3rCWuC&n%!dG7d_8LtP(P zP4aNq1xh%ht9B%BdKS!U44!m<HvO)sr^(ndgm$v?ELETJu$S6P`4>Bz75MT+0|ckn z&hUwFY5Kr2?NT@EO@b?N9ivMn+Df2)mT7hV#fV(5WW4*@&~*$6ac#~forsU}_L%#e z6f5(q6_TZ(6St!oL4U?z#rqkv6b*aW_dnJ*O1<!-7Ie8n`N{Mb8&U`r{5t&q=DEqc zs8=1Lvw^Ez(j%#0c?1(--Z`V;zj#cKsbs+_sWDF%^gC(?Hd!#*{rHx`ZM}0H{4^(p zb;*ZD$4nAG`sv56@W{nllV?IEmdV|rO|9k64E{%oBf9SK_WwZ785Q!#0q1Kcc_s-A zD-#=$vwA9Lj~RCp8z|1Hnw^(_DnSxg9C(W-MQiqJ9;%ej<F(Y@cN5;o-b#X9R63U0 zh=`MHx&A%EhTk(HB2G`WXBBWdi_gB1-IOhcKvK;owEFus+84^sFX6cQea9|eK&0|T zDiSfc`nIOK$1E0nV*WqS^=|Sfb350Ok<jKKdpl?&5s8vnti+V*QdiZWh!M?!Oo&{X zj3M+)^REdhW(TGI{v0}NGO~Q}0qE+RfSjDTtAVO6I_DXbQY|6>gy~Yz$zSZLgu}4C z?wJ!q4?nXFD52SX)L{Nh=15eA3}uqFrZZipaz(l~WZVqO>Y_gH=vhMQvvNe$uS+8e zVx=hA_UTJ1!5ZDHS0--5h_R8LzkUqLMT`k$J)(!QcY^u%F<;INPR6hFp{1t~q@?aJ z&@~7M#2a(6m|W`iM4$9>|8!7$tMFw>*0c=bti973wYA`rrMbA*MKWY?n!#4jWH{KK zTi<zL__2uNGUuqfo=5Vy?>K7K_(3<o-K8HOJM1v}ViT9#IKsqnxg!3}KZ{=2N=*K; zjf{+3_CYlYl&^igR@R9vwJaR~VKkS|^Qif+otqrqJkXmIBfo#e8JALS^sK_c?#O+i zuD(vw8HYQ$_So{uRx8|YQn_hj*C&-Y((JHf*(+wJ=O2_Xg_hX>8KNp-ce;g6>a}JU z(4nI&z<)5_rf(KP4{si!y4zx1x)TLay~0dqo%7;=<k2Zg+$pzg9ddDW*R-pqYt=A+ zUJ7lhJ>*}Wb^VIT72rn49nFXI8ZA|pePmwpOY>$1ajiHIxCUOwHQn1>m8NJOvwz6O z72u;7o;|^GsEC5Mt5OS~z%yOJ4r}@?LNJ;928E;dyWQy2nnT2K6W@y7sM}+2Cojyo z&4z9*4hQd+?7D(y)0%^<vzbf$ZKSq|f0w)DI$&sB(uVJH2G3Yci?@H&6Ob111e^`5 zu{!eQyJo*xq|gb_*|O?qC%DWCAV3T|pa}%dew3yd7;JR$RA3;B(FQCt^<>=B0ZTB6 zuT`4t@6>x-Nc(Bm==VyCZStw>@KqW|SX4C@<QrS54IH$G0XE{$AacH_Yg(%(O@U$F zB!`G#W^3%Njv%S)+!`M5?Jgtd5d$wvOa}Ja17P2$Iv}>;{tv&IS#=BiYgD88dm2{^ z;IBwSrRX%N&Uq63LGu2?MH#R_N0PHN^m0nY(eA$sV(izE3R+LF>oturhW6l+B0GL8 zNdkf^>cZ*~O18Kw@4deQg|5=(@?Uoq_xu?UIhNBgsTLecbGXF4L%HL|QIu1&M#E%? z6!jxmirE8F@x?Wb8%7zEPvgAf;fbPCM<RC%yUGl8TW_2Jv_`Q$C&C`%<fCCx?CCw# zBN>Cn;$c>9{#eT<LK<LSc8fd-H9iG>w<1MZTNey7@t4GgNJ>LuU&%1av%uza^HnZy ze+I;EANv=+kM;UgTc7yiwq10?1r~9Adhskz0`LoT9tkb0+R_k}^RHGWFQ0}N>$P*u zS?F9p@=%NFux$KF{p0}lKrapr1Ir$&aN$y<ZhuE1`pi{Cj2tJ=tQ>FT-Jk~4KPy~X zc39w1$*r%f<+Yxqi$@$wu@qkE|00%2a2MZyxGmY*;5s^{xUui+G4$5H`uXzWASx&f zES5(v*)D!lw9=t7wp7oWGcPS$MA62_mVc-LMMYAX;R31W&zFUOYs}26D<Q6$Vm(XF zAOrPInQ|c#PFn^1OJ~@0vaS<eNw8l~>XdD+nzfzBw7Gl%e4oYSDb+PuoTga2Sj8>b z<hn*_6^#uzp{D|J;x>e`U-T@Xd-20~OjiZcIPtyjRbSi2!uK?C?|}kLo1*w==RDu; z<aZwer>J}4YwZr@duiPG7YEuW6=eq`T$KJx&ua-KlecUvZka0y-;SBaq^jV!9_$dC zEb8B7h?T?(>Yto0JNgvHk>Y@WFPftcT69ezbxtR&A#<s5L&1A>qn4^7)C)=7)9EG2 zcWmaHp4BCP6U!uq7InAsxb~dFwxgq=*HPdI8keCL0h^-UYYJY=yC%z)JfRZ8=lPN; z1L6izCm+&WFRPDK(3OTt7vo=rKgG#$_@dy^>y%lFfdgW23fq!9NEX@hGA17zn0FC& z5J}l-dYMoYF|k`F^_P1_>`sKWWJ_tu*kE3GotFI-K-|lMWFgEnk#ciCqx}s4OZlR> zYYXtG*|PV`T2#%Sww_n@bsA{w*?PA-=9ZVEOjkbpWn-j8ED^l<j}o!n8+Qy_tPs2x z(_r8=q%kRyn52<MEqZ%-aH!cg+RCE+2ky$TZqZSAc$wN&-N<!~Q{b}?A;K4<91YKW zdQ<;$o8EIX`uJ~U7CiJp<ifa&9k`khdB6p`3y!))2dUTKjS&&FLAHZtc*u1h!2rm& z)*xeuGoEL75wh%WD4R_k@j!-J2n(G*CvuIU=y?JyL8@wBxoW=cXCrcuexaEw<vnKu zr9euMMt#Iba`a#W{ioEE(R~8~!q8$rH3zjlmU`}e7xq^oSwkK#ytjGVlrCwZ%DzVH z%T)Dy0^=gDa&|ZK+x;=h$%#2x)yoaJ+AN5T8vem~lSW9g&)8Z0nWaG7@9Ww^bntn$ z&TMzf%@=JLkC_Qt2V=-H{<Bx&BhG6s`zB>4WjppG;c#=YTynOVyEg`7b&CiiT57pL z_-KaDWZDITm3*FsB>EBR1_AXyvYDDe#>y%hg+%Ig{yF|Z&$XTs<5&~Z;4Ie5qEG<I zy}OhZ6?bRP2wmCDrS~l04)924H=1mme?gYSmYCfH5A`Q=6~A%>rwn9dE7ut!JC=H} zq8Fk0EuG(y;P!-!HnQB8v%C{WDs9-_T2eJ?kc;d3eEp0eK5YK%;X<WaIh_&q8m_Nu z?)^|hx~z3On}yPqiRw?0m*s}5X3p`UMI=(|M(Szf!k4pAc&xz+;Ix)0YH4S*VpR#R zC-!M7efzh$Bj?UO9=A1?H}&P`V%lWRXs%OC5|;Dii*d*?1fg{P3=6Wjl=v+=rb-fl zE0rw;XCfq0iR2l(%Re9Mbqg*r?E8Ocs;j1|VVHA}#i6^*?@fkdP9!LxV$JIP!lcdU z@e}{barEZw)58AkZ)Yo^yiW?E-rg_x&u8E5m}NL{*`_y+o9wEqfj9aYqr@`8qg)Mc z`upo0!<j4vi%B=-Ybn_+)Rxyua*~PPQjHPO=|wV++<mn&<NwjFkRfAKy6AN(=1o-b z)D*AV&@@)_^KpISkLPEX@4x@nhDFcDz;jL>9#XCQoUQE_!C%pAZa}F&aK(tYE0+e& zH~(_v?hKX>mDb&sS*$Z5Uf8WW^vR#Q88^YXMe|<m3;ZtLGWC#aaaSZ=R$O1$wY>S4 zd2994t#4g#pC$=hha!-Wnif0t05Zg_v=f0Y(KiFs+u)|5D4_^9Qw_6vSi!p?LFHq* zkGS}JpOb3ZZiMpucK|a5x_`_AT~AA7cp6Si0(4(QPoQUhoU{;15l0DMgIZFm#A=EQ zskU0V?_>>AHW`qx2)B0Eh-)DX_8Nx@-}ZED7D(r;nc9s+#xjcx)78R=4agNIS*fT@ zV-wQeGrV@-7QtR5t+nrH>YDOgWPLA`Rgr8_EK+?i`-@{jg?&!RL7T;Z_lHS&!0zsm z?1*KX*c0}R&pmZR5WmY&Q~J=^2?sjyJWtx9s;K6%NnRbsiBBBiv=>Kl!pBO>>zh^; zXts`FCj*m$*E5K%)0v-K56h1DC3Hmn{7fWEk_e}uNTC0SBV+KIMY4Pd2f97G|Aj+u zht>YLck|la214%jQg3Y`Y_sae#OrxYLC4^ZLer|RDMRPlB&&2=_KsW5tABrh22z5P zbYEq8ILD!)jdO*6DAs9=j*owWj`hyGAlIqCf3B0pcgS#WKIrm__$jd|J<=ExL7uj? zAP_*#w<vlNURM!nruDycqea=pBl&({(Kw}c<v<hB#UpK2O}-@j|7b_|UYaHH6)?I6 zE%b?2ry8##_i1Ge<!TSdxKyqTF6nHtMqg|M0}MW7YCUe=lf!DzI@6OxC*rj$_v`6& zV7dPXR^}6V>6ODB@H{FRGul?gCK0vP4Q18$sQpRFwB$x}li`gEAPwi%s^zrFUHjq^ z4X4{R4I#*9WIdj&)@@!meb;qnJ$8QPnGyAmwmKexsr><Z1BZOzH}2gTd)E^4#Sq3L zgK-F}M0Ic%+5{<hO$h(^CNjLT`tvZg-xEfb*p>BcU^c??z_Jph$d}TY^|QS_&VAhu zw(gwbxsGFgQSy|QhyB9OOfRq*m&o^H2h`wh`K|EsgmRUgVV!n<Ze?m{4-w>KC|1Oc zXW~OmLCfM7Q(g^&d6~tE8x3kL(dfXJ1=Mp9F1q`+%TQD3&1_3`EitF>-qd2{m5Q$3 z#dCq18x-YFJPAa-HIBF=*f!r%gaU+2vDm}F@rfZmhAx=_c`u&)j2`MYJX<a!1)dU3 z;F=h$zeKbNN-{<mEc)rxM_?`zyE12PS}yB4QQ?*O0!h@C<l*$R$O%K?;+M4k=8Z(I zce3Kk$Mo58Jr&O(d(AeVgX$4aNyd|3f4_8Im}qJR@EW;r7)QA`%z*1^fx5n8-o%#E z+nq$U52j6QdQ4g~md6;A$<N<wr=<WzQ^)$D8k(z^Jjj>Vh!n`1I488+>rGA%Wq$OR zp+{y58P4fcG>0j1fz1Bd71z~t6}Yfj(Y$&`c`y_ES3ibJmwJVUfYKVD)ZDOY&kz}N z41>WAp-~dY^HyaE(+C6{gt&x8J;K4EV_^w<@h&(zF%h$EvQYWxWI@KhT>A59iifbz zPu9tAWFt`}SL0c3xSjk_ra%Z0&NgSlOpzyrz@y+2uB7Rv7z!(Q_8EXi`2|-0n=w1? zpJOKPVUY%-+YY2LO9fDH%vd^>7EY#Co57~FN3<tWV{<lHEkQ37s+hE3#L-Q2_^2fy zBO}}M70gii`1KXXPH%IX@7hz_%JJomWs}=qtyfn3o)%5Mr-NRat=N3H%>zL^S`)O) zQNnj7O3k%a?)kSe+62-4i#9YzMNskvgoaFP>Q}p8PxG`dG3zdEHg+Nuxa@Cz$-JKj zco@K+?UJoXBuGnca@T6jkG`M-ZIDrv2Ri>yNhlMydkN0nla-u0c&#|knW1%yQ)ZJk zglR=FpV$L=-ZZVRTi{MTJrw0GT0wJB3hJ;WVD%AmD|Aq^6f!&7oIf~xViPb7rH}^( zJ#Do#&hhR5uy{C1t>3E~G{*YbfU>PrB3H&UNH}gX+Q$s6Wqp$Hl&Z|hPpFj_F4zFW z>fcJIq9Q|D4Zdg!^U;Eg--l8BJiL2*;7}EWYkC}1=HO}1ep1&wV6~7}#Zms`D0f8% zx$K(d+J02_A9`tR0JMO+q5{zt3CSYN$&`XX50V>GD(`f!*mfX;o)@bf((C8fTXn@W zc-9JCp+O!;E1b<HdLsh(WEDp$%L~mZmYH%7MU`j#$0D!O&hz8+$d#v;AYz02&^R13 zqIt=Lb>jaN_}FA@I`7xm<j?6rP&$3YTxW_SF<5FW&(^sQQY=x1vJg#ivr#^Sm`Bd? zT*+yqbyw6^Y!q#cSe4B;d*x#lV~nC&*{Gg%dLN*3Gsm`Xc%5aU<~~8MXc5)6A~%(- zo3}7t;Th`?4k@WNkJiLLd#3Lrx$y}IhE0c46SOQmnw}p2g8QNEX#<8WYpqitaSGz0 z6I(e_QPekwop^*qL`S3V@VKmJIUhWDfbvHUIP!jKqoSAE=+|f_uZ;)Q$tK_0l-kLw z8(hfWQV0IqJqA*Guxv4~ybyvJ)<T;%XGttzyKch!3)E}UP);tTsVthZJYlyc0t!iS zJ;T!WYQVCyHT=~yEeg{3ws5*pSt~tMO0vf{$LfpLEn$CMEt2w!wCiALITN~dP83s> z7adfT=FqPiC)HRCZ{Bu+JobGu5j0p%jnG;(gyuz7Yd0pc+r%a3UjHQ*NDox@c<=jb z^aa1|VjrHw&Fe5?wsLjW-R0&qBtnyjL^w68&D)XJCj&MtX5SQ}u7yjDhZBl4oIkwm z+<6b2?>~)B;z=rV#oh3$feM*7hhG~~0C_^CnGB}~&b4cInRS;=8PG`ZUZr&KWU;V8 zy4oq6!FBIm7L}@Zrn0CVn(S?RtlrhRIHj(|c$IJ7Cqo~!{>bYBg|@tO>;ca@A5uu# zxW_ZP?6)zVQeUZwNa4qQWpO1Hxbxz{EAx!2o5B0Bl1N0Tr8QpT5xD;sUg@YLzs2S4 z;UO%O$ZF6ZORw$FO_b4noL{aiR?a;9Hg${@Cc5rbBzU2hyJ)=Y8|R4+GBPwUx~e9V zT;V=AyWY|GhVzZi`QARb)HhUNT&KGDgkhzwDdQ>RXFklj>&u<6R6bct5~E9T2eqTf zyR;?AKr_A=z}shGb?5o_+ltoCi+zoI)cIRN@n<|<h6SCLKC@SkA$C`Obk`fA<F+_a z7$6aeKQqsfu@oT_snchpneT9@MU!2Z-LcY!djjyp`$A}ZJ|gdtXo)+jKQQOy=TB6c z$V``M4t0{CA6@(Rq)w~+^;{!!`t*KP2X_Yr2HI~VsBt@Qe?h{@Z>TczcB)wFZ%P6d zuZd*mRMS>?w2qHB4rNrOFgbn>+R0-><f@dv?1BaU1a1HLfM68af*F7Lf-|EHklTV6 zm9?ZwMv$YHU)dYQ+5l(MjPg}K8>EyxADxNl+#j?JYY)Npa%g~LBDR13kKV(Ii;!q! z`vVrw3(aJHw)Cqrnb;T<WEQl`-h6^jOI}cdn(d=?;KJVGBzXfLn}+VT?OHd5x7+Ef z0ut2V--+2jfYMhg$ao8qPB`dV=?i*jC?-S#584Bc(mFp7m}_l?>BR7}EG`q5T548a zsv9T}qtC9z$h2QYeUhg(hS}kU2cF{$JGc`MwEF$wvEV%fp1iUeY!#n+N36$o+WFDE zb0=hExMlsXtFW6(v){gym<i=vSWfo?{)LKg8H3FJ%y;{aGOCGT>xTA8{dJUmevCeX zN8|St66tVL+f9Yz83x{A|7Y4f%z;`ixq#;gOn(NQ!GexYRhDMqv3h2`dgN-qv2$YB zzh5SPLXvF=SlkC*+ub~6Mv?$5lJPRVF$Wo^>a>CaC=UTd2d#5ou=a9Je_oU3%6l(r z=W^R|I>k75SpNlyqg+mc-uZ1X%Z+g9>8;cgGcl<kd#MmYTqjU(n|_g5=AT<VG6q6I zGa)t(g-xr$9UAc#6PNWR(=V9htO{P>uV|ye4^MvRSWEkJv)q?``bPEA;TnZK<5{HM z+vj|yu4a81RD|xTMX!C%KVA)&NUwHnSF0b>?+nswgsHcbkm#6BWzN4BX(6CB7rfVP z=@Z8JCrQOB`XWNvee>cZ6h!V%+y3TPR0-H%2}enueU}j?dPwR(z#7Pr^3ml;VNrxF ze8JT$7IgmH+1Dp7LbtUO);3b)5Pp&Cygn$(*-D-H$mN0WZo5Db!@mUhj{OQ#M+%4e zR|-0$<+L&H;#01imOZTn<SOIr+K_ngzuYLpP{|cA;65r0A7>X^+yD~e0(J}@7jJL7 z8_aHMsTQkYL>8H)gPnyRdIvWDZisL)HsT4|+9}Q7sMg<obQdUZHS~dnV0Py$IqLtT zlR>(FA9z#AjR`s;ri}YZz*WL>Kgcd(SQ}eUrI;*|Ktf!TJ7O$x!!VOIR~B{ru5{2- zyLle6c&0XC|6StEMB}lwCHY1}6*#40uq<cl^r1h#*AYl52{&wIqwXca5LJ`FN@R?^ zm=Tbnbn#*<U0*-^0v;LvwvCQwPtF!N^DQ;*_DJqwUQaQLyY)rlD?O{<;NWA3;sy-1 zHShkE_<&V|-3DEt=D7ICj9Yq%@9U0gq<(G<3m#uX7{do1ch94<rexh!4TRe!vADcf zGFQr6*ZT{YA)HiP<TL-2QdeStj6=vuceJYBp)@qi!7LmWvq4kQU#(O&(im=W&y4og zMt>4|PHaTF;DbZc#ozw8{vV|ANy?id@(~Js&0b?iAK2^W%<(VCBzPMWAIgX}Ycg_X zZj?-xI+oTaPxaHzQJ+6NsJRYIGD;-~Pt%e1t~cFa;-9r!>rN~iov`D{R&|26$D<`r zW4l)_sY`-f`C@|o^v)Pbr+iqAAT%8&j6#+Z?#St9U=mOLSrU%bB=C|u;3-fel(O_z z7$Ox?#c0FCaWEf2(Wl_;=aXh?&vZj3=|nnw&({)kWy+5*an;VW-YjlO6xSm8OvwNB z&6)73{C%>gk8k*vR2=9lizjO*Ak{&tBrjPg&dp`cN-9sNW}NOEt*81v9jn9I#1&_G z9rN=I1?0|!!ftm-x~2fjz2Od6&8Jq$JA;u=HuGODc}xJQrrf?cW@Gi|ua|AFh03NM z8ZPa>I9<5JlBbQe8lmW(JptuZO|==eekU2B8JxwXb*Edz{70pI!Kd}#axmWCN#9k& zV37gkZc_b~w_nY+Ky3dDo%xNu%3i#R=cEE%yss~^^Ri&#A@xHhickL_O(#!!Q!~1M z8s3}`iHl7-Wv)|2(ro1EpzKCSj7;9JFx3%HF^Hh~VFvVc1N*4m4CAPp+UC~})ulHX z9!HSQ&jRN5es*qf3E;z*WomDg_6sH=ie8fA!@$x(I9Wy#MoLAD^^CO=0h*$N&Mp1_ z%sR3<gX!`F#In<#qR&2P7^SThXf|TcZkHahw|wFeSV7X%-|668U)Il=@$Ha}ttv>O zjpfYa*nE-xUwvCb?XL?ufk+!9$2{akHUpKBuHlz7pDs_x%9|r?$^H3IGS08hfa0qW zs*l1Wqe7Yv$iNbf)u{%J3HLjv7zZGU7&Y46dH|eLq>;4zDUlCBv!NaQfkadQU)-xG zihrKRU#ni<Hr}`c=cL?ePl@`il}K`d=ZFLcR4cUm7Ia8XbO!Umbt8L=zRS%{)%CML zu>TjH=pIF}Evkv224YUH)KNAhT57bPQ`L%5{<&%&uejk7pj+xoQr9is*`~=?QLkFT zx}b6XyAlhgx2hl`k9qyZ$-W<d9j<Z3_}5tfYZ{aX4=9v+?c-FUx1H&LjZ6WuZH(nF zj)>coKs~7R*UW{{UBzd0<JOia=jgr<80+9Qtc-an3K<Iv=3H?@#m{ccd?+&s_AV80 z=nVVOagAaRUI}u4_{HpakL(?Ee!JZ8wRSmJ?bOS*Xf>b@LUe-fdUq~g9vJJQSmvtg z>kI%t0cboQYp?2#3<8P>_=Uo^0eS{O3tbxJN!1gUUhdOhuO>@=T>L(1Pv1-Q8A>l+ z==<zW19aGz6((q>DL2o4@0atcdQhi2=}S`R)P0{&Z_?$DhRe_IEqy$;cnkjTQFmk) zwP%=4#FryPj>RF9?IFw3=ywGb{GtTMIF00>g>N};^hq%>*WNq{Wv$Y4ZGX9}H6N+@ zM+OKc{>_BZ5FlV{p!Zr3D$1XaleM5QbtrR4tFI)eX0sA8IK;T364drvra_;?CyXti z@<lH$Hi+%3#?D|_okp7hi-xtX6aZ-Q+eCcR1;@dms*)^rX5=sKM|G4grtGkbfY4og zYMC5$ug*tkix}6lb`MO+uOCOz|2S6CTW?{jnl)_=x)2%OOky|sMe_@7Ln(}y74vJT zhVA3wVXxX_iyjl$Sl$|`Pm?h!Ak|rHJa0mFQ(gGT8jg+`j94c*!slV9e9IUH#3olT zx$8av#6e*V0o_&C$cb-z^)^TG0O4UHpCm-?U^>58fpY3$r9O%&7>z^2jtgZXlz=m= zs?hD_LacW>q0Bpv>boGIKu*<d<q=M)ZKWl=$}4`&8y%Sji#eu>rnao=QjeOx+czi8 z)$(5CXM$vhPI;U$$!lS0@LY1B;_%GBew4pvzl{@Ye`R_3lx5Yc{-O6H3`>!=d?Wp{ z0!h*ijq3;^j81NwYR#UA$CMrJeK^q=wRmpB7Js@leoIO!bq&}O=EQE<*do$9wt6GB zZy}Nb*4gALR;5dvI2itY4;6sXTRA$;ch?sZnJRtW?OB6n>ALl!7q(glFQqW3%Jf$< z4jPX|wsP}5>we-eqqL;m-6-R6c-jzBZ?REF$w`isw(#T<1UAeZuF)jfk8#u;znQLh zr1IoCSDS3}$K@y-XZe!Ih+nkZEM$P8{u4f*_&I~qL#wyy?JpBy33P9wju^+O1G}3; z1KB!BV|as)$O`MZ%1QN~e$-Z%(!@wE7Oana8&#qp$44H56{n?duRBSly{*+Iz75dW zE84;z`>vV4KoRb-NVyR789={ceH*D)HC-X>ElyC^+BbSjmg`V6pB>66dyI<<kJ!s5 z1&XE(v$qwz)A425ztISvJz}G=z4?Boi%FFco`uFS?%mIGBVd8aa$L#8i|SR8WE{!@ z2MBrZbQ!{Yr0*rD;XzY%<F3~(hm8p>W9_+9Ls^e-ZlDesT0U4Dc|?Xst?4ZOgW*5L zVqSF(b5wFPqZJ$Hh<>c24{-PH)Zf3|;|``2oj!OKZk20Y9oZ265&BfZma;3qQGEUA z$%G)kA{%MEEQFkR)(`guU*E8L7cu0-@IT`%+nMI(%crwU+(gLL>nb>RW<UNVq(Ih3 zu0l&rUxdnBISl7-5ko#qpv)OKf!>mIoVkG3d84!}_aK`HZZdDE3lt!!^;w13vI_^^ ztLkl`C>mmrCRH^8e~jszJg_rW#0f7Ri^f{O&3643=T1QbjTj=<Ch^$?hTM&DoLJnl zPYRyCA{nuki^>s2;#RmM&Z9MJR*PiBJ+-hmIO@|Nzy36PvM1oyDXm3vr8c~<wDHTN z7sXZXvLFv~ZLo|qD^9+S8)aci=<b<?jHg|H)vKz{9Cuo#)!S0g4(6t+P3d6kEB_St zXX!Lb+?u#;_@iMY<ht_SGos6yV<4Z<1J2ey^lY*VKJRb1=Y&0Fo}qIs@QG8LbG$G+ zwztQ5M|Y{n`SZ&c!SEgjqlqXt*5X&aH2*l<%L?B5Z^OM@@nq85e753A$LAkbj%6d} zcNeay%dBtw^}bU~3?M0Omhd8y|L717gge&!XD8_NNO_xlufEm7R~V7YWwLa;ShXuI z-fwR>dthw7<5OKX0*w)RvQ_TIF#YwRXc^{jB_6_+^UvncmJnM`-M_Vs9J)=(tE>9L z$dbBL8)nzP*vZ&B4b2R&ajRQ6z<K;7RsOf4_fAZ-S0c1eWA(pGv;J+w65*=os0343 z9l8v>PCSFQ@U4_j)QMeGdnB?Xr2S^3jPWHy0-<;4=kqIZu4$py{ER{~Y@370SF@rl zp}&=KH=WFXw|Ktvef)osq%eg{7;Gg)Bxxwii8~CKfxMD+EFEvwy8H40Mo2}sloB#n z^@{_Z*OoHUo@M=57Q&4%yAlDN01%p2BFftTu2AnH;?vRFx;N#h4yg`Sw}DuP=fz#l zzntgkkZwSvomsrA_$H`z{TblzkSM54EJ8ev?Q+O1Hpmv~N)*!47J6p^(qFARWT_Oz z-l)EX9xOT9GG}~Tp`rbjArW7L6#2s;rg?|m9jWhS8~xT0z9TeOfQ|dLyP7+HfY11= zt9!`b|FeX<ynbl`X)TT(@#Qw*Js;D?HsHkz9eh?&XeZcHFB6Vw7T<mEp=%-Vor6O6 zeY9ETmz&RUZF|)P7f0#+I2Y9g_Iq(GGDI30ZKl{e0I%xWkfQd75tA!l!T)(mVp^Ax z0_?b0R%2t*jH065|KYPfaj<?COwvdRqLfYhko72kx#1^|HQO&F79g(pr2L*t51GGl zZ+FlFO>MZ7h-{55C;W_x`V1AT{$kp)rlh81+C~RClHGWrBvNguRnw^#QsdHSsdZsp zv)^n##kTMF@RjY0=*1Np98|yeZ(2*dCA?uroEM9Wlp_uOx3F}IOSXLB`ER9jICaIL zNGonsPKDM!QxdzZon7>#7t_>z2uP#S<ncysUMMM5;?djon;Wm>D&GOK`upPhH$Zrr zucO|TfHL^s1C}?8Lf$I+r{)5>zDqze(3$>@s?4-;2*0h<S~p4aua%WJ8lS_yR4*%8 zgD>ZiW=C6Rtf6zS?K2;{<@grX5Kvrj=_Caz88=`B!Dlj0GU(Gk0Y^;fO3Wr3exeT@ z(wX;H$u`HPueE8Iwvfg&HIEWagv-kU9D7pF1}K+xlmqa2#14}+{K>7bxDG7mI}Ad1 zMb5eL*dKOTHHc(Xy(?&1*C7@GmnJ*dunvzW(N%r+8eBikMU5M2k-t2(-`7)4TCb8B zv%IDdy$TV~J<;O6GUTR{%NoWZD8+6(+zuv3A7T2s;?Ey0NB|O^;J9!^3#jjmTIHIG zAdfjX8LAv7Oxcf|X)2YK7wjuA*-y@^Gc}C$+Z(taGjDh_G3oCl9wVH_=S~t=EB3xy zNVgtxm<fyRMbNP)#v975_k|`|aJO<|n0^?wT=8JfX)fUj_m*8;Oy54aJ<8aZY@f?5 zsJkOj)p){*D>RaZCb|AeTvsotT!Xq^j^q6*jq{d|8wY<I`2^Oz1$+ETMGPIj##6Gd z?mr*ZeR!vwSTMk5heF3~W@Iol@oCHiP9fU#g9#&#gwB3L?fo3p#?l*4XLUGpEWt(P z(XI!-?)T<?`hE7N?&UNWcWW|!Te|4CQ{Vj<@p9|>7YEo59Jgd@b44XqFiwgiZ&Ec! zYGr7YeH+Lw=xOK77WbQke#!Ja+B~q9s{seugLI=`0tP4CcAT<+DUNB&89QU1o>s4h z*uTQl$(<ysfki0lb6%?ssq8rIcEKXHJU7gZ#T+ZZRvfx23n_Q){HqB@hG)BJr1fp| z3mZ=&U?1=7<b=FT-3V&ey;XDSW)?}idVSva=58>F7d^L~z<yR;F2q5z0-9&QVej^p z0hz2_4%>Hn=Sk3$)W9YHWWB44uuN^LL@ixG_L;?={rHqI+b<e(i9Z211?2`P9Bdqs z@Z!o-K^In&@FC}$p|t8;ucf5(^<1J{=Jdjms*%Tam7LrtgVp$=G*-h<_ui2Tv<qeX zpDZdaw)D9~+NS$?D6A6?w#dAhtyJywTlquoigrGm${UF0d44w5eKNm$6F^`Aziv7O zT$AfwcVZ0gVr|udQRz*IfAoQD5bIu+3SnCT_q^EMGfjOHGBT@T*$;EoaA1(Yn*t)U zV`@lGfP%xlKZ<C+=i0rLH}yhmq6|t8ZZNx}jEx<G_C0x5Esl=hOp^$g&*q4tgn}Vr z`m?suiD{}2O?H_nYZZ&N#AHA!K<p@8Id0$gB4^%-fV#+MT{al<Vrp7Kp$MaeF!|a0 z+Y*3MuY#1(XKEo~5S$-V=*5gMq=qBrT8N7VmMYNKEGArVvamosA#RkAx0hJ@1*9D9 zUsZI}HC8am)!Pn-EMCPD7}aHS4P+cLqNycj_Jw!EBUS53YVJlE#3MUq%CFcj4hV4< zr_Z;4fJ7|IzzIeF-j^27(jUufmXv$Be|pU=L?(XK2b2dsHuZ4Y-%Z&X%MDY@>n%{k zD9_goP_OJFqSb5h@)&>qgIFpngp<D(CE|u<H8$0-@rF-l8b^O%<F#gzcfvWfRB~+< zTh!jlJ8o&~#f7jtMwb}v0ydrRl&}!m1tpHpFti2oWu0468eog;-r-s}t0&%cGTv6T z3;M#YKHc2_MOv$2ZlMs(G;k<NMQ_ajkA(!tN*K3*hEvQF0~%aWh}rcqu%@J+-%!*f z7VW-4^Icb~Brw4z=Guqdonn9NC%HGSk<k+`olMM9+dSUSGbpYRc~uu4JLhxCh<nx4 zS1@nnCQ<!3NEWra;F5=6r%94F>`~QqXOo)QOM;!-uCSKUHla;h??7FwX(;g}1C5$b z>Zed;vhqBU6`cwrI@!(KzB2WM)xqXWwj)ulV1&G`r(b-l=hECsJjanRt(EuS=yN+4 zYMPG+VmlullLe$=XUoet>_CEV-BRq5wGXT?lZr#Fj)`#Ea_uEr3Pmy$-VUt#v#7{K z7#J>vh8HbHK8*`#GV!8-GELx?&=<q(TT1xSTYNrnZ3rDOJN`T@`+b37QwTx@hE zhI6;_l3;T6ULF0KrkS$@gW!W_Km46hX=mz8N9WK(HWJmq=kzkP84sBQ=q;Wp8;uy~ zL-kK_YUh_Mp3bK{oY)&q%WiRE+Z6LSxDCK=xkXeg3yO2B_}N2W&Qww}37mi2>`j8# zSfbTKngaT@u8+DuQ0SZ7r$o$pdvcavxrQ_Qa-0Jsj@CEFcKKN2aS?$>&aIhx&(t^* z@|35JWQ#>II67WMALTPn^YEx|j0N)t=?Fa&@xO?oa((&K6zS-C<pSo-)yw5Tv|Itc zRIqOp^{J)A>wk6lTA`)44nJveD&-H=v-Iwp_|Oba-M#FCsew1uZQa-EwW%VPW(D=x zBzs>=;8Icy_q@F|-*Wj@C`F79*S{I!kcQKOwb#*>k>@e#{2fsaI2F$edXMp;?w;ki ziCJ5e{=pQ7ZB~XT7biTYro%ij1A?M5j0x^_w4TYUz<rD;E;~EBWg%zgm7eFG;|wmE zSKOlO)Y@f32BR5Zvi)95#?4bh_N2?`H3O4xVYkW4zL5Tq>l)#KMj&lS<4NB%jk;CQ z+Y3j#(K_{~y(9apS*Xcx&DGo~39KX(fRqw@8_}*IP_t>M@me`ZtKjK526V?q9`B%9 z!FGneJL*U8wBD?3nQU*lM;GON0+j%7m$3^-L@w?-%_w+PgP+<fse&YyD(a2<#;Vu; zBxyXYlyk<*>lWB*da_yM@#c>|77oI?La{uq$jUoM^fHw#8KP@kpE<7YL@t!RcTTfO zjueel5sDQzwKZ5YAaUujuNl?ONXyGaQrS#h0CLS(8adxC2j%w_HVd<>{rijsP7^v) z86AGo(NXF<w!5;@lOuhuO+&yq&n>3wxpx(`!fj%moZcKA%|h@YY*{KOY*5|A?zQqt zHO8^^uGk$<QQRW9?3lGjg=|FOBK!w<<1s~~tZ9h1M3_9y%Q@{Nzca=|-x|{+lW%%0 zY>(2OUJyVz=%HF(OnONNa*)dV-p1~*Xtz5OWUwwyFi{ceIgBS=-X;IbYZ}SP>*RA= zq@@MF9W8Tdi}<PhIpFhBq2jtq1Id%F_4%)*CXJ(Q!_V1Yu;0F{n#<;)`Qn?Au_1Zl zqK~?(MqF`dXt=+TxHX>`io9)1(YRH~z}e}fP+8ejbhR76a>@2ISN@dJ4pZ_AK}Hse zRbxjyPUR{-L9BH>V!A}9QS(j7$h|r-nPaGDDA6D9r_~l}j3$z1xOvxV=rIgI<ldoJ zrr53fry{5&ms>Mdel~wtiIx}Dso*#p=8x>Pd(m?^z-Kq|v62y0b%Zg!b5j-QveB{z z|E5`wviaa_i}Xsc<ol&Thpa<uq$u??(DscAlYcgHnIKWn{E{|2dwlDb1sn8IFJxKE zYk~tQcSOrxAV^JVQe=t?$?c}^BNSMCJBw3wm@Rh=Zemo_sp7RVHs+HS3#iTo6NZ!2 zy>9SENJEkVjx5sba&ArUnKl<v1+a{wQC%7n=sH(Z&v;2>y9;TAlR;MJdEs%LC@6W3 zr$y(_Za=m3!k;-iRM?prSo69(9{+jHuR4i{R+Dkbvg$%<AaZ=M)nR&9n{vo9{@vDq zs_?)7GmeJuyM+8jd9MYWB6%xkb^YY=%G6D=-GD?mNk3(yV@K$msp<Em)Q(!u){Wak zYEj~8&`dy>QLT;9L^s{@P`XCco)7EAp@hdifh0xuJwH&)hy{o99fvCxk2^vgodsRe z9x}~GsL4!rED?5i)9Yn>KU3Qc%@36u^1d0;S}p^ec?ZA9Z9G!yXAn??!`7PO!uzxN z6wncdt-JviN7CA%Y3(3Y0t0$#xGp2Hr9Ja0F?QPU`rt8Slno}mjMobC?-8o)p`jB3 zU4i?@!_{70WO}|A*iObN)e-C1I;~g;G^=nW)2U_T_(JnZ%JrK_^VdGFf_Uu{TO?bU z`5`^~vE9-M<BF;eXpPUTvebvhUl!#<0sdsf{)-4DAG)}b^y7WEn;~Gfk1fM!9aU6F zZFa5HbT)mJhzGyt?mlmcC=gWS-5I_OWcKJ>(a-dnZEV7ykIMId%SF*E=s306MH(-K zI|7%FcmwXM8ByMtOmdW9+|(&`2h36ficWazip27`iL!OTuI^c|lWGo_zt|CzR2)vJ z(9O+O0mp`@OD`F2PXTOWC|oF{P+zab?vNfdbsd5Fq4fT6XwCJpl&zJg^CUzWHmggO z_<s%*!|8Y85^m)QSs$KUor#3?S0_@5Oxv$_**+%nfB9i(D@rCwzS4H-t;?=@K$_MA zadBcVFIIGny==8I06NCp*2+rZ3RJjz{ftxWljz5jSfKfC?D_Dt<WSATtgLvTC&CC* z*7jMvvw)F8I71ILM5Bl*E*HlHTl1@bpl66_Dwop^4!fR6H%8~k9CV3^YY+>h(e5PT zgWLG5vmc#;A<8zqU^*bR=dq+@ZPp!4_d^~2uR(~TFdvkmWYn;J90nd!)?~S8W4io% z{DocW_gp+*1-eC>IG;f@tdx+81G6WwfAc5B=THW$-B3m$6M=Favf+0CufvoLnak;J zIz!scd1iJ^NX)mO&j;LuD6AP94+TVgYdSK@6BQ|}2t+5SqR4a!k;_Ele0#YL?Teie zf#HN;<QinE|2!nJSvrYmiixZ4r4H_%)Ap=9d>E!c26>4fW`ZzX3oA5w*mkr|g6Kp| zqwNor(M^3UM#3lFGtwC)e^MS{*%&X(SJQYa>oUUFWzQD1vH2~##h7_Ag1W_4I}$j6 z9L!E80|mOaL95yHM*zUhk#<t!uV$nAJ%Ivws|c>9`dTg`IC1{;CNm{C#h{JwqXQmb z;KRxTKlO3~5NXtsPhe1^u#$Tu<NgHpI$sfc=Ln+#=}f()>)jL9eN;j|ziuTI0fN~l zW?5`%bFS-8sIMlX9!y}b3QZ)1;8FLQYC}_pQIs(<e)7kk>zbuhojjt}q?Bx<VIy@v z&m!QNJ1*1)ysE=#ys=AGlClE~NW_s<J;Leyq*Mwu3y(v6-#b(qbja`5zx%yt!daer zM8u^nMCwy5eKgvTU`1><<2_yEL*bz5Ua^xj<Id-IH&LRE#dIG`>y_<;N$x1}9LNH! zYSF{Jw&4tb7fr+Z+>L9N4{)@C&keJprMN^<hq{^eZF@cnOEp0;_r3-+QE;WpmK#-m z$&$?6X-BE*??&Lcf?;A8M-zUcX8;k0M`q<|Uf&KMx8b;XBn>jS8T2enQSdNm53?ti z8}ZnSVs6A_pMaH(K1Whcy8leSip>TXE(`W8NFa&NldNc~0mRCb^@H76uKL(s2nZap z)Q{W4ly=7J;6i&QhN{dw;0ez4!F9R;cEl{q>jHP-LN))h10(DJR}|ivZ!vXsF-uE( zlliQOlh}0(mz&&iDEL{uLG&_-hi5Z-(2b35#0i{C(EfQvMFq-G3Qx!bj4b9aeQgU1 zDRxcr+$tLg58sL(9$5b40-6s`A9fjb0S+Apil20Pd@Xn{VtTQTp6Y!F;4zw&Cy4Wq zD4E5n5^3}AMvo4h!X-@tC&$ZW3{%$|+4CVj1!H$IG>JYq;!b(=>WDrp6&a*@Wkij3 zyNJSJ8BYcYmV$<QyU`O2d|B^EQN$4@Pp~6Nu5!J#E7x0)`r<gyopYPSp}!hXmS%-~ z$u@-L27;1zla<VR$Wu7v>xpPbjXSy<IiP9AtV#5;uar|dY+LG$822?<`P)8<c3b45 zF-sROT<~_v-$lr@J@v6^3MYD^m!Fuzis%!!8!0C=??3Fh7M$25)gphApDRPC?Bdmt zg_B_V35cJL_%*T_5wA3S<e@I_?poSxst2Fh;S@3;v4Rwv?sZR$tN_LdKSqaO#5pA2 zCMiE&-`-%7CpG=<MkoXBgTDta31fNpe@PuNxKQGB=en=kkm4s37sa3co>f@Z;_VLL z#7sc}Xf#Z#kF4>V30<~*!6f9Hb-A>W1P!WRVZzx<%!X5HtQ!-DqlCjdcbly-Vujqc zp7$poIdHsvJEWg6-x`g!Pj%TE>|4>a<#y!;HYP_atwUmjiF5J>bT<Q9S}kTKZ!I#4 z`NF#8l8#O6KYe|%VIxa;M$=ZknJ=_r$rxtkLJOOJ5WJf*l2VM-_(nXz3YkAK@y!Kb zs{l@Qq>^A+nq+O$GT_gRmme4^q+_So132P1J1t8Km728?IK48rKfK(*`5xJ=RL`>H zm9AbpKifN7V#l?$sA8E&1!-bnQU8Lto1_`ZX}Z|kfm`5==*%mmqe?0fUYE{sg0I%& zpz8Zg+9w(0#sa&Zvl#}GKMZEmizyr-jR8kI-SoJ<Wd>&{A8}2D4`8{Vv?J$>cI$L_ zUjl&ibw@%#y3=vg|I^x6hPBak?NWnMta$O37AOURTd@kor9g{AaQ74sq!f3T5Tu0y z#odZaaY&21LkJ!mLg1w5dC&K>?{$8D`H^d`nSIUdHM92GdoQ_f7jfL2z7zhm$0}*? zbQ*t`SljfxzItv^5w>-;5>K>jZTD=-{=f)A6^}kb%|c5GJjiONMUr#-cBCnNosF^- z@cETWENo`ZFntRlTKoUT5qCq5V-OYwvdZe$rwJe=ok7gasCGtPPR<CMRNHtu?=9dk zn=)RkH&SD-=ZiU>DB^Cp#rf_oQvP+abkeRJJYH=6%ii=2&ML~UD!qVrg0lNYFRb;q z3m;TtuFuxqLgq!2oRQB}UrAufCr^3Niz2K$m;joo%jZ)+8pzfLa8Y@Z7K?tF53po+ zFmfXC%gjY*Rf0Uz<~5iG-ITL2fvpKEuM1klO-Ct4JX}jlqSsrkrR?n0hs~ys19dQi z^b}r8w)NR}T}(9Hog?Uai`HsI2rsHfq$_hW#u!>ZOC!(kX+NmZ_&xve>!BwmfHNEt zuLgvnLll2<`>HChJHd%9!I{_fX@nSGD5cg;%B<c`{<;Sz{ru;fJ!C?_Ggwbu{bd!J zAs5K?;$=&))v^uZto&so$b&4?4xNxFjOwt_*eo6QY1~vRb-J%LRBR3zpFqS2cgIaN zw{S$;)3u$lO@Mm5i0H7^b|u3QU~xH%ab^kSk`3m+*cV}yc0@E*dV-#GH;PRdR+b)C z#RR>)%onbM=$P&<2%%YbMQP+<aa`;+b}R8j2A;Nv!>XAJ4(D8#4<xn$FpV`_ndRuJ zl%-EIm(<#B{A<f)+)#GL%iAR1S<4PDCGB>Lk%pZ176n)aqsjgdmOD;RL;pwAY1*%d z=%Zh<mUR(jjRjqSy;ezT^d(fYZY&0Q=WbLbj(Ia?p(=8ZL|x9h!uz|NeIvG831+_k z^to2CTkjJ%B<V_{?QwH1eIb!~@9asDdB<2$DM0RHgRlkKFn8}djww3Aa<e|A5zZ)( zQ{@)Vl48?b9a=_jG<aS)5p7GqhUlpguSL`4rcHHQ>nT8W2OLyxPyU|!IBTnp^zsh{ zL=$c2yBuU!ET@6){XXnkR5vAFv&)g`ML~XaKHfWALlz2?I?2UuJuq{45&hF8rNjZT zCrxb=<n|>?13^!2L7uXo^;OlUz?;@iv@*W)=mQ(tlTl{{cf@z3P`vuY)q)MWPhgcn zi-RL)GI-)Nn@9O|sx4mlS2z9Y97UTc%U*U!d3vlZ(^{Yb6OWZ18?F6WtOo96X^GKr ztaF4|&8KYK2je>fqI^-#vWNrspjPD}Pq_W1lKC~PbX@QY>L3an>l`XCi<zy7Zi$LA zo&A+>r&Q)o+7U#)LgQ}63^7p1Qh%%1mqMo9SjfS>;~QQw<I6HWg^REvR7f1L6p^J* zho{r}yR3f3u3IOQ=`+YRp2$e~!3C%r$5k6bX*!92?`_u&5fczFNN+m()*X8A)rT5x zb9mc>wc!NKtH5&Ld4{EMbI0PK#DmyJJRAFBfwyX_o1SkXtQ*#T8Xjtv{1XB`aCBE} z>m{HDlv%<VbCsa4uwH&%*dV=>ZyJ^mbOnioHUqJzrW)KGb0_B6srIPPb}~qi8#IFv zm`uJk8~o|_sclsiiB4^i-zj~UvloZcM9%@G^dfICpB3~ovzKI6LZUYe>mD{l6E3b0 zJR0TjSTP5I{1^#KXQRUGRtt-LHkzz)G)g90*Cb_xuG0Pd?o5KM?w2|;4IsLOV)g4B zHsh3U+=jZN(DPcz>Si&=w2(ZT$vm)T#aD7l6Vtt46UfSZVV_ej#7(!MZr@i6%1y{h z4E2fVxxswSPx2#<s`v%fZJfPv!a}i-E-Klz^(Pwk86~5^L3d1`O^4PQvqu!BLo7FL zeE3%VF|%XKI1&@*UUO<W>8G<@Gx}BYB>{HL3^v@-+0+v{T&r={dAm=#s|YNZAl2GT zrt6q_Nh-|*PC0;7uf_+MB=qTi7F{1C<qsq{a|XB(?%5$_5Iyk8<>|Bu+olc-a?iM3 z*aK&evNVL{%GNM+TY15tQq(~NDlF?V&;Z&I%zF-}<A3=@il@|zyMUE@x!-4H5_#~@ zaTL~p_l7`3$Khjaz*w2FaJ|Jwu!>U_H*{8Sq|!reK>IGSZyMfkcvo*@tWw-u5E1pP z!?Hzv)J5DBS4z7U;s63U&Dpv@oG&TJPixW+_Dc$n8$=Bdc@})-E{qyN#N^N#6khif z269nwo=7eP2(xUozunb&>t7;ULZ;4RYwqm?nKJ%>LM^ra65goICn;r`^ESmfVuj8& z@MOt2Zt5l-EN4}W&NSkL=UpG0S1M;v9LkwtVjnfuec_jI2eduC5CCfJepFq5ZO#Gg z6AX4~*d5;#f1|RNik@tmSei^npFwvu(Q&r|KjHFmiqNB{xRH>3`ZX{(O$2D3gnqE9 zaQt)koiL0?hxWijt`4MF4C_1iaJ=+^Gp#k@IPqx<_@S5qKR|TXP6|%I|B@wR=_&wv z>9%|C%MHhU&{z$08WcAdHpru%%;cJs-3Vhhu;4o^JkE+@k7GI|G#^FzoKfa~OvaBJ zid@RaDp8XsCv3;4K`6K_7RwwXnj(sn>g$!*6OGO!7TG`qxzaGnp5&h93ZJd1^F8o} zR$=7595=h!oT;4-y|EcM&((S-TTj(MJU4aK+HR*P5%<HF9wa>LhC9`}fF<2+2>W8Q zpR2~20$rBV?y{fKC<$$AD-B&f1w>{yuFW$tjCuCm_kdx?c9bM!eLk6<a6YQ*sfM%H z=p|I^GTdc*mHN`DoYp?f%b2;kSnNV2ws2<Fkl_exJ*y{X`vte)`2WOwR~<~lA|eEy zX_cf|XUCdzeXl~4w(P2eQ_bj<Ey`j+qX)6rsT<SP97MDN51%~?!zX7o(_KHtE|!1K z|KP(x;fM#kpA-@q&5^_R2pPNtyH9&Az*w+fif8Xaf{5rW6q5B41VV*C-uro{_l1P% zq$v@l3cW33EuV)<e;j>T-2~n(t_pRfED&M3>#o3TTcedLpU|eL?9N;8ZKYw-+)SHo z*v*$ai5e5c5ShVzl=;@T>yZpsY3mk(_E0(ejkv~QW=uZh23!9QlMX`Vdy@~6N>mh= z24CvuGCWWF{gK#-@U9}NNbK^Kj_JkyMlbO@eVpq?k-1ZN0g?U@x|*@VrQ%(q!K}mc zT){W%I@0>Q8N1<nmK_#fxpau-Ee*3T58$B$&>^JPj>D$!ggYf0T75TesxF)Fbh{D- zj^6?A0(rKGugR~sPdvP7f`~fI<cS`3A9NJ(WP}y>l;H^<sC+3hK8D1CtxNwgt1h)J zXRw*=1b{)RVUySI`V3a3l-3-@<h%IzORK%{`t>d>J}oWRS1^~gK69_)5IGBZJBg-G z9?{*NQjIQ>xEgl!V*Jp|)0WP{V3H;ERr!mvxy!(TLQAUhF2f8<4hdB0J@wvV^y&Ed z&Zc5*vM~mBj^)(eUnkMFBlv89j5v+CI^{3o&<4*3;;zkS4@y1ZL26$`WY!Ka_M$mx zN9<>eWVU@^yL!HhWlPH0AHUDG>CdJ|_;ZF!D1G_t?pe4Y^_T}ad0i(luZfF@KK{JE znMYG+`J|)9Z3#0Hs(nu=Cx4<vgophfftOpk?y!we0Q6I^n0EY@L-gX};v3_|bWGs= z8--e>7Q3_c18Ji14s+kleV`$7xFrHbZa7=nQp3Z7Qrxq8I!t51k~0w2zHF|{QQts? zS|<<qGP%fzG4*4xL<MWF!RCS<qPCEG&akF%gr*LuBl$dCdTxJ@MrRhmnv{Bp;IEhJ zW!fn%`)*fHmqdj@^kt$Blc3<c98OR{St;|MLvU>)uGfY4T6k*Ag1kHWig^>WuWyB> zHRZAW*fUFC@BP1mvd-R1Xh$E|HP2%JuSxbkzxc&=UT|eZTTuQ_Hd~Luc5brk&YT#d z<DN)gGB?Q!Ebg_K`|ek4wEzyim|H};nENskDUU@fAK80Z?|te3(0|&Mz#dp#^dJAw zKVhdHNX$q}uR(eHs}EJsdXNu3NlWv)!r)+8FC(&tSp0A*E?q2Cc>Gc8lNTNyo)&OG z`>$+^@nUo>rx4p8sawp<=RfkH@$&Mxs^V%NJ3A8)?+a<)m85xQ3cMkfU2?wS%qy7a zufkGvlY5_h?R-T*C2)r7R!rgJ>`ge95Cp0Jkrg7ny1P6&AYVzNZ%~RyLQYNu&@Z#} zN|SQzuspW0xfZxLGZilURj+sgxVNd0+xl;f&TolkF=?ry)(>!JYGF{mACy3#zb~f9 z!`pJQ+ac!cTtBWENceH)qg&mPm5T&JNOW+f@4;gG9rE<&Eb8SZF1bhB^W=knGl<sP ziZG-NAnTn4V>_?n<qR7od|+!C2PuV#N{|eO4j!KR1`{L*a&cIMd@AxE9sJMGo9NMS z8W!=%u!Z{u`@ln$kSd1<t)_FbG5y}F6lqmcCB~H$tz0AHTV!_lb$a4GzQ>c&B~$wB zM$R_x_5R4UAtmj_^9&nexvs{H--`D%L5wcdBwQ5=a_?pKj!WAn9oY`dy$id?k!f*O z?wVF+P7F2ycF=`0TU9voNOdzVt0$TLeK&~bJ(ce#R-e#$61?^GX3F0O2hJ`|Kf~PV z`Q2T=jyK-7De?^D&Z;H1#B<8FkOOW`C-a!BNF=0c#RdyUubzU~<Z*Zs^9=Iw_CuHk zM>v?DURi2*?J&Z_IFi-U{{EOJJtGw*)^;<|G5eRN4=lNFEDC*Q07#^oO|xy;ruk(2 zzPjBTtiynzYhge~TIabt{VFDXP0N+j5=~&_v@^}R&UBp!j8<KPpN&vFJ$k0Wbe4kV z!qGH=U;n6DX*t+J)fY9~Ggr78=$mG^J8&WMmtMxPd8Ud&yVQ%HFlrcf>jOk=hwUxh z@N-`+6};n8k91*V)GlTVkyj!3kot6y^kriE`+UthW)@C2fPVP;D=+%d$SlLeeBC<Q zF@j*V6ppm-Zc$H^Gyljr!hRh0bF#GCJb34C7n8M|>RS}Xzs|IK*$YbT?e@PW@V|Ri z$mN(BlA{jI)SfXBzDDf5(!VT?m>f<`Jq*(@9#f2H&`)y^Ou9ej!n~tDRJpZ^Xsju@ z!GcIyn(yJBGPCXtj&yS_Qj=0hsc44%Gi?9!zxuwJb1T&vHW(#wL7z+JJC(PvdbpkJ zS`Au$!QZzlE}tEfarA7;-_7?Cg`8?jSAy#s&jWp~>E!J<rDfe#n`=H2WVXOQ5TwdP z(=X`*_f)vyqrrTS?mgIFihQsTciq+t_Ra8dA|oRscJ8XCVBwrn233)}uif3fqp0z; z!E9O7<;UlMJnnn)e?X68$0N;oP0?2R`jXo7;MOM}X&~^loAEf33Ga;l){>};3EaP- z{8ks<wEYFMPg?(&;_smuEB5Mtr3v%Gr})s&P#t0O2IW5uk@OYpfJ;R54D+bSpca5R z|9-sX3F-N%g#POz^gy(l@31wv?X++F0`mJ@5az08wqXxPs%?{t8vaZ>3+aKp!!|8^ zU)<M2+5yGZNFJ^ans)9-f78uT7@zy=(W_E@6f`u}*ep8H5t$AihfU8e`($n)ZtKVh z|I880r`Z?db&v9ybVm>of6hO1!hd?z)1ufsn09$GvlkK-)z#lmz|GB#WkUE-yWpGb z`d_7M(S5axU!zM&FnEMUSXBP)+4}gaTeyo`2-yFprMbb5n;3^?iP=DkBaX*zy=8r^ zv#Am*x!EDDWu~ppe>^$=Sen>|*H}qMYIf$E=;C{&&kxorm0P9|_f-DY4u%7Joe2R- z4$ZHx0`KVv|1AeZzZvguosh1`Ui>e6PkQbP@4fWRaD)G?Ea&e0Z)9X>&HEC1zZ?AZ zW}g79|L*Jmf?~y9heVJ2NT2WZAHG?o)``bHaQE(=KRSPP3!uY|LUyT&`Wy>%j1#YH zS6Aw|*Sq%W(M*3P-g8juOLZC9mTmd+rjwsjZXlKUU~m1q2d_gsE7o2*Gna%@na`~e z^NR47KQ^Arb7rxP>tXo($Ghk;06Y@CL0w7Ed<T4E|HE--#}EI2)qtXg^?{m9wbMI` zD=YrdrA&UtiB`iarb!t!=5ze2O1_bvZf~ideK%9?l}*;<Ys56Yi+=jDyp=4$b~5x7 z!O)iKoVjWc(YPlmv#apLX1G%PT`hCYr<?4W1<y$&&|I;I$O!KR-maX)qf)&nhj>*J z)fqQuQOD7Ixl(K1NsX;u;WC;`S@UmnXn9{7J$m5v^TrlYnvb35n5R0HJh8;4eey++ z2HH11;C<9_4whTwo%cR_mt6!~F$Edo^l|3|9upG~jPbu)Iu|y<y0dO`@hD5@>IXqp ziB?pMi62Gux5394$@S>hDpfDN2|;*OS;mQcxACYRSE*}w`Fu|svA*+yOcp_uWjg2d zDJ)R^ybW<?jb2M=oKi)Z!desDU`wPw&rIEBK6XwW0g^-qyYrqV&g;J+i)plfaE#&4 zy)z6xS~{v|p{Y?wbb|5RAiPzJPhR%EB+WHhpW&iF^btchIZSh-SB%CtTIxrIgDpkZ ziblzVa&x^%bY45=?yg8iO2nO*t;v|qi`qi+t4pBBMbpdCAGacAq+&BqRh`Zr)Iylm zs7cHuq%DMhQC~&6IKptLH6ybovQOXgb~0Uiy`D;4QWXR^ELN&ST05!U+T9cL^FjJA zm}|DorLp-&Hs=WKa{j4nyXw@%)cL|+7+(VM)GoJ{k(Dgmy4>m}O8B3eiL>Sdy!5LK z2QG%`>wbYhP&k+8iImw0kfbpVj_hGVD@)yidJFlAy#!cB;{;il>JwML2)9_Q7qm>( za>vm)CK~+;FGcnDZY8hmbSG6@PB)3a9Vc4Ql{mK=2HMS5W~M84|2!CYdO-}_;+c&5 z6-v$)5*EfRDhlFxA}R{S(x0fLiNsoat0>J!dU~&BZ!-zSAoI43^i7Us9eGP<A4=K) zIghhi0^^LSp@OE|)_WFG&%=?j{_O96CLleA_|?Aln`N1riq=DDGDoMngH<7YL4>3R zib!g0r)No%D`F|<E;x$w;EZx_d!tUiy)~+%ORmsyCb;F+m&e<Bf_@V=>1Olo9U_E| zF!B7KOA@|mEm7%c_e!_rcx_+LF!yzXRvbHYbMD?Dg!J;{<_Xh$UuX9+%^2u@Kj6mt zLoa2qu6&I=b*7oKZAr(z8mpH&1dH=wdr`SL>C2;6nH!71v|y%Uf7{I&*y~J-Ayk!5 z6z}zvx(c2aR`Rwp)XMo4dT$DZV#ddyZ^eih;dlcKSJ8VdmX~KJl`)7M=Hj*kuzP*f zqr}<bajcdi>34`vu035;Lf*^t_E{TcOZeh;`+|-c_ota@_5sNZ!4HY2<x34sQe{uP z*cG#rMZuh*hJEhdkRGoPyV<Db7$BitO=DmT$QEV+=h@v64PcsgkZDsYtpM2_;3-9) z1>_VWP@ga$$@4=p9Q>K)<!lTC&1`<%i2bGJ?2zfdHo52eXTb`V1Gz<NYhCH2d(UzV z^<GC9(PQS;w!9qVZbhE4t)0k$K5^mG_|PjeiXc&6T4O=-lSZEPez>>Ql@N}Dn_PSS zV!^wgRI@<*xPcJSpS-2!{*yJX0<e`@<>ziQv2v~&{4@IvKkY<;%8H~^IfvkVkUhd9 z15$R+yj?-PLWzY|N;r|+t(CF=fcG^GwWsLoW<Dp991H(v3D4FQmzezm64_sVStX}e z%nY+c937Z<3VD5eR>FGuY&1`EitLP<UFp}NdH|&>VjwhL<qn%_hPZq@t1=dC8Gx<o z=fO^1oceY5KVreO)oSc?7=6!-H^++=u`NVA56s42n;B<0jhsF}{ZyHUxKrV2MlTLR zb3EOp*~0RGDEBX~(BpMO(5?mfucN&KI%$r-VyAbZ#BQJgssR9?j`~?I#vqm4%}dyO zng6zyk_9IfwZ3?mdJf2)@hQcRl5bDqYQP;or~DcvmuxSD@bj$NZhBA`_V~lWZ4>Z> z?we2cGTO`F>!2qMayh-Q{pYUv_h~<>8UsHmB(Z*5G{@>!v|swhTKJ^F6274=LzMds zDVrnTK%w<1CBqE$Ybq^w>|S_(f4`N>?GZn7|F3e>JL;^6RA*OJ`NMrD#AcrkC&z3O zfJmILvE@!JA-e84jR>&Pg6Mc_!m=xZ<~L+KmdWN28O314hngxesB&D$z>@gzn|2Xy zPL#s2KnN9#%;Xb&MBkL3*t+K`xi)>bW(eLCSA<v0@Y(70M}58+<u+y&_2TVl5YBp~ z>rD_TY?-Beeg%h5*?q@A(hBd@4p6Wa<vhcM(>^i*o1G^On-qYZPhYJ5MnUOU6cH zV7KY(T>zUwo7;_L2!F`+V5=J`pjiI=I!BNlJ~9IMy1kbY@AGI0hkpV2Vy@!R?O@Ht zX5WSK^Q_qB+YVNF(KM&Jpn?Egjqir4%?phEHGAmcui(3FOOaUmYX7gwFN6RN>uAeV zwR$srg@B3Nota9Jgq~y5YNmk=>S-sS|MUm+iLhbG@W(GSxq`HLYzNvNdcNX}@n{hl z2m6r#_d#Oub8UW`KreIrcQYcc+X7!GnfG}pzkofNR2ZcEB}BuRf{NDsPQBH-dWC!o z|6I}5E3(X_>s9=m!tn8xFfPL1csq0Jgqa9~azu@9J-+a1KQ9@X@^qqxG+J0JrDY4> zem=~?WIVNd4=mu#TR5(YK-Db~UP<6~i1ZhcNUci4thYs60y-MB_I+A5JzzL1gme&e z(v(=qdSg}2&cg+_Z_@SqZ~Fuo+I|JWe^x7O>Q=~zb0pD!z4EV?4+m-|H@+NnF=waL z3}i!4=2~W2cvy-X65|rn%l!zW3=Iog#!_&B&z6G4PiH}$KYpOLE8%=t{}M61$cuOH zC@7!3Gg@r*(;;zwtU=27Kp+jxys)}7ukn=E>4|}&S;_6>{gWz=1H2I-wpRy$+(Ct0 z<?aGx<&DF3-{adHxq#&mRdxl+A%_zkK4)91vXfU&b2^mhb*jV26Lo(T3`E)<rz)|R z)-q_f)~;yA86VhC^-B95;ZXJ^u~zBZ`YKrsYS_QxxfNvmV$)eYg@;CKvR2Htp~Bgz zi{h$eJd}9q4KPA`{kkU2WQQ?3NH1uRcf{kn%A057cI~E)QKsSXiWkHT&l7Ik!sYQk zvFnOr=<kZ8`wg~_MF6NVTj`37U=T~1s<h-cYQ+g6W=K805A__)GOix6(}vKC$!}|4 z3!BplA?BwU?Nk<OXcTvF-|_8Oe1Ic#Xn7M@(9z`89{1ZonQMd4a->iDcbDfd7`Qv= z8>Wb!w!INyxOS?vRc&Y~B^k`V<!?PwPQ>v1ohf`2yHz%xtXnI;!DAN#mR$3jYpshr zfUGF=9aafE?!K`i6NPRU9QWB5aolUdCJr(#PiBaU+g?O9?{TZPu;sZPbGpr*O2CNs zj1{)X!9TN!m@+qq_GU;bcV@io7{%jS0JpmCP&LiPt0BY=XQE8$4be1X!i`<=z->7a zL){6$+J|IpfrJBpi_}cU5LfX)dO6E+H@#aHLfO=IkhtpJbA%IpLv@Yy7qfaEVp)eZ z6Boi*828(PA}KaD5(~rXQ;!mtpe_h()~xbh`1x2!I1U^qqv+sCal4*zU-BEqcx}ng zfVKWNZ=YRC${1J;=K1R_fyjeZriGHF$aGN$@rfuQz5QbJO}O|X6tp|wR|T$McvSMy zRz6h#@NzWjX&leWrVV2I3&VC~^QR@lgabk5r*=0vDLrl1<SkB!d(P{U;*QRIX*iMq zM#I5Ao=5Zd&T@VX0ZJ`UQK{l@uP;nO93pYcoyJ_K1{piH(o@yM1d_!q%j{=_ypA^f z^77cQjB3BNepr#47dtl?f>CdV(nMclH9sRGLmbsfZnw}ZvGu6J{F!>7*P30Yp6$q& zH&2BFrU#6xteFOY8WYaWTLSBpR*L8YVO+d)ODA6!%dqpaMQZ)Tp%(AM;YmM%UY@p} zZmW3D-veap`B?I&y=ijLkS@^s0eunb=w3L}f<80ZZZTxJGb(mA-t=fR(1u&t_(xdI z02*cRT?$M>8mRmcy6DaHdAlSOj6#r>=x~>r4kr(YJFIN36+-u5$&KOp8YFL9Ky($I zE;q`UG6(nQm_4@3!}2Siwb38lztzG7UqwQAwqVpxYgcYPmpY~UHPyY(7aAU(t)8QR zgiA<BuxsQJ;$Zh#ZP=ZuL^1Yknka}B<5{ERJ8FA>sM!@(7XwZ>j?EY?rjwiU5)^5A z<T?|?|IS{UAbCdv3ch?f58m<(Yk;BddWO_qXc~>pjv;RdCx^{>78|gOEA1v&p>Tbe z$9cT1-A)UX@HZXU=c3#a=boah@HXkw+eYna95qw1OQ0I(QEIYr9?yc82tT-5-Zu^^ z_}%A?=OVu0>txX9n3-xBRYPl<px~VQV>9A%J%LWo8;282b^&L?4zEp5eYT%l_;*$h zXm7|*Ts7ry+jj|m#&>K4OR-tN<w@4RkAu^EiF`C}eqeRq{9qGlJ})4|igS`ZkXjRr zo36XK7l+La*s>o{Dj#Cnudo(ifSp?So*N&PR)l;Z4@a#N_+C!6JSLGi<4IqD!BMcg zHy0x8zGwdHNSGy}rEqMuJcV=xB$03Ee*ulJ>Mg$VuSHbajOo_MFc_Z#vp3#etXoV? z!n<7NrBY0g<u`;sg`wBL<<r}59+hq-uN&wal(Fixt-gjucMYFxdSqDZW>mP&9Ime# zApNMjIVp~aK5JXCFm6wTe}<~^+aU#UO6;{?nf<U303;Z@pT0W7qhM=vU^Dc5m|6?G z3hf~F$9dc2<@!5fkjSBh?QAQS;I6d!A`I(2M~!I#v2=o}($crJO7xA}1MuG!YI0!} z-k8l|T`WT62uF4PP?!l)6%bKan9D;xS|G91&w7A@L&$!9VaRa|F|uGYNA{XXN}ipa z-Jd*|Nyu^GRr@-#*V&o*$O}Pe$PP+VMi1pJbd$8IXK^e5^nMgXHi&|)9>)XiKSuW| z83UOjDxK3nS&c4OZI*rUR^Fz{H<lROHga8?Zq}-fy5oD+$SxZsE*<DX<l$@1qC4uI zSLV2+wA1(9{29MV>TpgVM5rxetMb{5Wy*VN;v&T@*-eddCHcN_?}$^W9mT~yD5twg z&~$dRWFH<AxD`uEIN9LNo#}hQ{#Ygg$LMT-34DRwz05TvV<~lh$5wQ)$XLhsb+n(p zZvh0>mY6GUvkGP8t2FTe>fV>C1{!Qlk~M@LtC0#6A;K|7@+L#vi^Z(2`PkK`>(+So zk8g8zI@}=kYQ}*dpV*U5@=|Zz1z4=x*@4$T0$v<2<|@y<Id`*Xx4Z#DB~_I&bqui6 z$r%`n0=sZ=l9?AL`U8O6<Vmks8)3PZ3k}x4=Y(Wt9Uv4oi~i&+nyNvqa<DaW`Zejj z0qqC6ZhSrF<dMF<Zf=P>2ba^<juDc~s@BF{29nw*WW~5$IU++(DA>N99SiT@C2l*_ zr?(uATGJEI_&i@dZCb_M_z`JaYAhxKg9h)emE&P5th1qOIrhtHQ4ZI_;cpbLmrqaW zDz4*s_h)emN*{FXgCx$(+ip)Y`DBu)@4bO8xX|zY3*)o8OS(;&<~qW~vt-!Abd3W6 ziyMIIJRI5w2k+>qyIc@*t{nW>qCUsmd`jjXmvZziDKTZEQW#e{ZBaLi#xWwjzYBxb zk<8+Yy)|#LT&^cdW+c@gYf8;iR$-3PZD+Ll1U!K}#F6hN7IT$qTIvX{#3mVF{ls@k zNGyMTei=c-j|+i7eoyjP-f~3`kKZ+n+f$Xn*p`+OokS6nQ;qyqVkD855v1Akd427E z;Hu?iBL4Y-E3OS~Pkd8Ez^`W4KC*97(5KU;w7e)3md_I8bv2@6L8JTh{%k_6j2r82 z{G$Pp^d$oWaTJQ=VQcAqMr3LE+X`n>h3$;)%h$qGDaK}l)s=SiQeaL&kxdoo2@|jB ziewc1{9xZN*K$Twwp)4`A-@8-HhP8=ATbHW^Qp|AT%A)&r+w3;Vt=<c=d%)^q|S)# zyh~~gcdzk~IFeRyxwv*d3xpV=m+(rMZ}PtNvrvmWicvxV>+JKyQl?tX*70Ins*Jy$ zZ7sIBWy9uRc3xUIsgeI^Y_|2?H!9a~dyDf@jw#KrfMZ1+9z2T2W!l~{rPDoKk@?Z~ z4O9H*_@C6TCDBMLli@33Z+bS<?Xx>)vp-deW^(yVTM{LJHCZP0E(shE?$_fi_a!Xv z6_)1itPM=Yh?P>lyj{wvu<v!9(A}36P<+T@Wh-L51$LA>)Fn+gzAxHW%$?GB6aOi_ zN@nO*N%C0k&h{Kekc)qS5bL6tVUjx4ppR~ze?gWNO}@9K`isypH6P5mw((Okq$QW@ z5msliU=m%o0{M3r(_q#x8iN^;uxL{+o^O%dY^RL59_hMgx|iSH_eZ}*XMqe|&{Wbg zGRy1hZm;Rc|0h@y+tBHEc1vkq0?KrC<ySt_Wue@xJaAjH=p%YP(XRgHgXBrREBBh* z5*(y1Mvc)8)=w?9w_GtNbD3L8)3Dk{<R=)s?QECYl49VDKdH<}fq#_qIs8sIO<8vZ zc;Ic<8^fWCXE<^0L(6$mLZJPlJAibFo-khjb7NJJ(^0N4c2Bl&tqT|6$maxtjgtqO zN*V11bKRoeNanm6Wy}3;h*7>f31zxAi=c=|3f7BSW<A161<>!g!l13^8%1%jq_d{i zR~YP;HU`TeRBrO)-Y0*C+p&=%>rKKTgQp~jIdr%Y{$}g`DRYXL(UYwT6*|H5gAG}J zsOT2|bKLd&fC@I#YSx&Tm<zco6Hpf4Y{Ajel<w9Ucw3XKlGS2KcSUF3mZ2k00=S&_ z9#7Pp%dbDrz0zu%qj7)7(C)>-E;}LGPExiaG~hw95U*=H*_9+&caCEDwgFEZiLaFG zj?9?zt+LGZy=pNLQV5iQ?J;!!Vumxs!!K_uZ;qFut}$W(@w$IVxw1*?n`?hUf=(hA zKj4cs;;fH`bJ{ndE<9P(+lU?5h`tqUE0pK#5WDqmcXyYNhA-f^z&>cV=8H`Zh3#4V z7d^Xk;NvkZ?5Zpsdx_Vq=l<**|Ee%shO4zU@@|VyZG_3Ojatub?N|9<PVWJtY(D zlHK(V)?c)t{(+b&LchJ-7I%_dq!Pjcv5!)|euNbdcxG}!N=C@>i$H3n8$)F6lc}22 zYI2j#H?tS%9aQdtd8S#c;8~=1Oj*1GIY7sSLr;dnLC)0qHbpGr&X1Qu>GI9=Wcj0W zX0;j~4T>kJ_tpR;iVMn<K+eLb`TFBK(Ou&6OSI&;(Z(30^h0PNub57S8Fg~n1_88A z`0L#3<TFfV=ytsw8@roecC)_1+d|EEJ<g3~ZwoM{0o>;?6TV{bj%dL)a@my>a{G}C zB@>gIq4I7#c28JXW2~yp8EuQj&b=mybxDviAyco6<R0do>|$L4f!};A@7_bfCtjFf zBMdM3|8QmR8sfp3R?pwS57#S%>*EpxU0l%~0=|*asdnpuU6EENa;jb4f}b^~??p2n z)11xOQe=!qh2?Oddh&V&yagz<!p~VP^;pO&H$h&)&s4Ro*lj)l<*<cY;)d;nT{J>h zCtQ{8`h$`i)@kO02-QQm;);Zl(FkhG@59Hzs7C$XJ2QScMIWsDFgfaoS?ItMY0OY- zH?2m!l1Q~!v>C9v?eak0wgUDsIUb8d(B9GE?A%NL#mU+EHzS(!TfVWWJ9~$_(?NuE zqvFSy!Q1YPLmy+T8;_B!>QuQ+L)p?qv=hV~{K1XW#L-{OLmz(nq|WpxdVkE%jyXUF zdeaK6FH6SiGn7_mr+EGxgj3v{0*9v?t#5IC(=DKQpL)EuHD_*hEyvFJai{fWGed1$ z{FD+{5E?IvLf{>Fe8z?(-XVU~YN=fY;z#Vzq|&~S?D)=&{#m6?(>FJg+zaqIU(0Jw zkmt7X2SG4HKtuZtu&SR@w~Dimrum^#qD_p`Hn+@)gG^+I`a7@v_g9>k6y(i&uk-an zN>Z}3omCCS$4pn{26%aO+?@yLU(Dg=h(Kx{x^5=Q5gpX2*ZUHYtpL=jjT!FUtkYay z3k8mB?*~_Xd+<sQX(IsH6=UWvy51VEV;D<5$u{&5Ic@Ywp~{y1#bU2(p2|^}!p9vO zd?Bv#qZJERq|THxGhFL0teDHWTI9d!K28Te`BD3U{AT~WqS2H$ihb_EO*&F4GD5$| zefBvKi9zhOd5;>$@z<-*5Y2C6ym2vIvWesSUhx$PcSAp0Yzadf5$Y!^vJOgto*Nyg zMr|i%297}Wf;L6z@yh@vV7@|Bt;U^!wqnnsY3CCd<61dx{)ixmp_{%|c`NnC=u<{% z?L8X(kc+rrh1;aVE&_NX4YiT}EAy5**)NYmoo*=Ic6;z5TI03V{3@wr^8uk_^+{8& zv#7gfA!XrM7&{-|uw289KN2KnC6XBQWYEx^N{8k)$70CJ7j+WzIdHJPg-RwZSi_e0 zFp~hy1pihJ`k=(Y7|z(4O0u~|t8~9!2OF_54hwCY&c?&WaEx!?i9Kq)rQ;rd{q=TI zvu<#0c!cTLqOSYcBsmR@Ja&YY>lP!gwVeJ9imn38t96h<wRC!_j)SQQB{nbK``TkT z7?WU)_0wFH<dxPmzl<Zlks7f&tjUVcd$Vw@U;ijvD_wZB4|yDlsqC(3nB}kHf(QrV zNv~!OP+>SEn9f3{K~(z+o!4IU13(7{_L22sP1}oW%0Hs2v0^=4U*uIsF#b7d3RR}4 zd?nab_E{N7XZM}QJM4`fL3bX*Ml6&#-)EpRdL0E@#iS<GFv047^!#_Q?cj}@V!h3O zh1q)Dr?}QqQP<Zq-UR=8m9e{u9)k{>YLjYR&}GZ-PtbEf`#&@A?}J!y9`s+t(%;d2 c7uidx%~u>TWSI{Kaj-x6H!9L4uZ%wZA35#hDF6Tf literal 0 HcmV?d00001 diff --git a/doc/images/tutorials/history_panel/05.png b/doc/images/tutorials/history_panel/05.png new file mode 100644 index 0000000000000000000000000000000000000000..8e8f0ed014c0d3ef6128fad8151f5dcac8092458 GIT binary patch literal 110922 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 Y7<jP<Z|tZ{JOW-fl{6Id70mtq2O7Y5xc~qF literal 0 HcmV?d00001 diff --git a/doc/images/tutorials/history_panel/06.png b/doc/images/tutorials/history_panel/06.png new file mode 100644 index 0000000000000000000000000000000000000000..82693f521d4fadcd83d1809d488be69bf1558e60 GIT binary patch literal 142707 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%0D{;y{^V)u(iH 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%0DyhqgY|OB$&ysEE$8;l1_Ud@UR#<Dd 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 BFBkv- literal 0 HcmV?d00001 diff --git a/doc/images/tutorials/history_panel/07.png b/doc/images/tutorials/history_panel/07.png new file mode 100644 index 0000000000000000000000000000000000000000..1049e07edc327c542cff2aa25ef7f2f25995cb68 GIT binary patch literal 125717 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 literal 0 HcmV?d00001 diff --git a/doc/images/tutorials/history_panel/08.png b/doc/images/tutorials/history_panel/08.png new file mode 100644 index 0000000000000000000000000000000000000000..379bee09f067aee75eff9490cbf494e2486c5cbf GIT binary patch literal 189709 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�&^o}uiyAzxOU|nrSf?&a>t00q-&p)mN6fuD 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 literal 0 HcmV?d00001 diff --git a/doc/images/tutorials/history_panel/09.png b/doc/images/tutorials/history_panel/09.png new file mode 100644 index 0000000000000000000000000000000000000000..cbe59e4ce40d24b691a017ea376537a1e261842a GIT binary patch literal 316785 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 =k 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%0AF!%yd=cji-vP@ncLF2nLu_$ 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 literal 0 HcmV?d00001 diff --git a/doc/intro/tutorials/history_panel.rst b/doc/intro/tutorials/history_panel.rst new file mode 100644 index 000000000..73cf98e55 --- /dev/null +++ b/doc/intro/tutorials/history_panel.rst @@ -0,0 +1,173 @@ +.. _tutorial_history_panel: + +:octicon:`book;1em;sd-text-info` Recording and replaying a processing chain +========================================================================== + +.. meta:: + :description: Tutorial on how to record, replay and share a processing chain with the History Panel of DataLab, the open-source scientific data analysis and visualization platform + :keywords: DataLab, tutorial, history, record, replay, session, reproducibility, processing chain, dlhist, HDF5 + +This tutorial shows how to use the **History Panel** to make a processing +workflow reproducible: + +- Record a complete processing chain on a test signal +- Inspect the recorded actions and their workspace state +- Replay the chain, and replay it step-by-step with modified parameters +- Duplicate a session to compare two processing variants +- Save the session and re-apply it to a different dataset + +.. seealso:: + + The reference documentation of the panel (toolbar, tree view, persistence + rules, chain reconnection) is available in the :ref:`historypanel` section. + +Showing the History Panel +------------------------- + +The History Panel is visible by default, but could be hidden in your configuration. + In this case, to display it, check the "History Panel" entry in the "View" menu. + +.. figure:: ../../images/tutorials/history_panel/01.png + + The "View > History Panel" menu entry, which toggles the visibility of the + panel. + +The panel is empty when it is first displayed. It is made of three parts: +a toolbar at the top, the tree of recorded sessions and actions in the middle +(with the "Title", "Date and time" and "Description" columns), and the +workspace state tables at the bottom ("Signal" / "Shape" on the left, +"Image" / "Dimensions" on the right). + +.. figure:: ../../images/tutorials/history_panel/02.png + + The empty History Panel: toolbar, action tree and workspace state tables. + +Like the other panels of DataLab, the History Panel is dockable: it can be +moved to any side of the main window, or detached as a floating window. Here, +it is docked on the left side, next to the Signal Panel, so that the recorded +actions remain visible while working on the data. We use this configuration in the rest + of the tutorial, but you can choose any layout that suits your workflow. + +.. figure:: ../../images/tutorials/history_panel/03.png + + The History Panel docked on the left side of the main window. + +Recording a processing chain +---------------------------- + +Recording is disabled by default: the History Panel only starts collecting +actions once the |record| **Record mode** button is enabled in its toolbar. + +.. |record| image:: ../../../datalab/data/icons/record.svg + :width: 24px + :height: 24px + :class: dark-light no-scaled-link + +The first object created after enabling the recording opens a new **session**, +which acts as a container for the whole processing chain. From then on, every +action producing or modifying an object -- creating a signal, running a +computation, removing an object -- is appended to that session. + +When a new object is created afterwards, DataLab asks whether the current +session should be closed and a new one started. Since we want to record a +single, continuous processing chain, we answer **No** to keep appending to the +session already in progress. + +To illustrate the recording of a processing chain, let's create a test using the +"Create > Gaussian" menu entry and then add to it some noise using "Processing +> Noise Addition > Gaussian Noise". + +.. figure:: ../../images/tutorials/history_panel/04.png + + The History Panel after creating a Gaussian signal and adding noise to it. + +The tree now contains a **Processing** session with the two recorded actions: +the creation of the Gaussian signal and the addition of Gaussian noise. The +selected noise action exposes its parameters in the description column. The +Signal Panel shows both the original and resulting signals, while the +Processing Parameters panel displays the seed, mean and standard deviation +used for the selected action. + +To create a longer chain, we can apply a few more processing steps, for example a +fitting. Once done, the action is recorded in the History Panel, and the resulting +signal is displayed in the Signal Panel. + +.. figure:: ../../images/tutorials/history_panel/05.png + + The History Panel after fitting the noisy signal. + +Familiarizing with the history panel commands +--------------------------------------------- + +Now we have a very simple processing chain, which is enough to illustrate the main +features of the History Panel. +The toolbar provides the following commands: + +- **Record mode** toggles the recording of subsequent actions. +- **New session** starts a separate history session. +- **Open history file** and **Save history file** load or save a standalone + ``.dlhist`` history file. +- **Previous step** and **Next step** select the adjacent action in the current + session. +- **Replay** applies the selected session or action without showing parameter + dialogs, whereas **Step-by-step** replays it while allowing parameters to be + edited at each step. +- **Duplicate** copies the selected session, or the complete session + containing the selected action, to compare a processing variant. +- **Remove incompatible** removes actions that cannot be directly applied in the + current workspace (i.e. because a signal has been deleted), and **Delete** removes + the selected history entry. + +When an action is selected in the tree, the corresponding resulting signal is displayed +in the Signal Panel. + +Now select the fitting signal in the signal panel, and delete it using the "Delete" +button in the toolbar or pressing the "Delete" key. The fitting action is still available in the History Panel, as it can be replayed using the **Replay** button. In addition the delete action has been recorded in the history, but it is grayed: the reason it that the fitting signal has been deleted, so the action cannot be directly applied in the current workspace. + +.. figure:: ../../images/tutorials/history_panel/06.png + + The deleted fitted signal is no longer listed in the Signal Panel. Its fit + action and the recorded deletion are grayed in the History Panel because + they cannot be replayed in the current workspace. + +We can now replay the fitting action: the resulting signal is recreated in the signal panel and the "delete" action is no longer grayed, as it can now be applied to the newly created signal. + +.. figure:: ../../images/tutorials/history_panel/07.png + + Replaying the fit recreates the fitting signal. All recorded actions are + again compatible with the current workspace. + + + +Duplicating the chain to compare variants +----------------------------------------- + +We can now duplicate the chain to compare two processing variants. First of all, delete the "Remove selected objects" history record using the delete key. Then Select the +**Processing** session in the History Panel and click **Duplicate**. DataLab +creates a new **Processing Copy** session and a ``Copy - Processing`` group in +the Signal Panel. This group contains independent copies of the signals used +and produced by the original chain. + +.. figure:: ../../images/tutorials/history_panel/08.png + + The **Processing Copy** session contains the duplicated actions. The + ``Copy - Processing`` group contains the independent signal copies. + +To create a variant, select the **Processing Copy** session and click +**Step-by-step**. DataLab displays a parameter dialog for each action. In the +**Add Gaussian noise** dialog, change the noise level, for example set +``sigma`` to ``0.05``, then accept the remaining dialogs. The copied signal +chain is recomputed in place: its noisy signal and fit now use the new noise +level, while the original **Processing** session remains unchanged. + +.. figure:: ../../images/tutorials/history_panel/09.png + + The selected noise action in **Processing Copy** uses ``sigma = 0.05``. + The original chain and the modified copy remain available side by side. + +This can be useful to compare the effect of the noise level on the fitting result, or +to explore other processing variants. In this example, selecting both the original and +copied fitting signals in the Signal Panel we can see that there is a difference between +them, but is quite slight. + + diff --git a/doc/intro/tutorials/index.rst b/doc/intro/tutorials/index.rst index 9ed619d55..a09303026 100644 --- a/doc/intro/tutorials/index.rst +++ b/doc/intro/tutorials/index.rst @@ -51,5 +51,6 @@ on a specific aspect of the software and is intended to be self-contained. blobs fabry_perot laser_beam + history_panel custom_func work_with_spyder From 9cecc0dfbed17fa8ce004248b5b35c4dc6b8e2da Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Thu, 13 Aug 2026 10:23:11 +0200 Subject: [PATCH 092/108] Fix: History panel: a corrupted ROI payload no longer aborts the whole history load Loading a .dlhist file or an HDF5 workspace whose history contained a single undecodable ROI payload (renamed ROI class, untrusted module, corrupted data) raised an error that made the entire history load fail. ROI decode failures are now degraded locally: the affected action loads with empty parameters, is flagged as broken (new transient decode_failed attribute, propagated by copies and duplications) and is reported through the existing incompatible-action UX (disabled row, broken-chain repair, remove-incompatible). The flag is enforced at the execution boundary so a broken action can never be recomputed or replayed with altered semantics (e.g. a broken ROI mutation silently deleting ROIs): cascade, reconnection, replay and restore paths all skip it with a warning. A corrupted edit snapshot is discarded instead of shadowing valid parameters. The trusted-module security check on ROI decoding is unchanged. --- .../gui/panel/history/interactive_replay.py | 13 +++++ datalab/gui/panel/history/recompute.py | 13 +++++ datalab/history/action.py | 54 +++++++++++++++++- datalab/history/core.py | 37 +++++++++++-- .../common/history_model_unit_test.py | 55 +++++++++++++++++++ 5 files changed, 164 insertions(+), 8 deletions(-) diff --git a/datalab/gui/panel/history/interactive_replay.py b/datalab/gui/panel/history/interactive_replay.py index 5321dd91b..c686d55cd 100644 --- a/datalab/gui/panel/history/interactive_replay.py +++ b/datalab/gui/panel/history/interactive_replay.py @@ -511,6 +511,19 @@ def run_replay_actions( try: for action in execution_plan: if action in deferred_actions: + if getattr(action, "decode_failed", False): + # Deferred actions bypass ``recompute_action_in_place`` + # (direct ``action.replay``): apply the same guard so + # broken persisted parameters are never executed. + panel.runtime.execution.cascade_warnings.append( + _( + "Action %s was skipped: its recorded " + "parameters could not be read from the " + "history file." + ) + % (action.title or action.method_name or action.uuid) + ) + continue if hchain.action_mutates_any(action, blocked_outputs): # Mutation targeting an object whose recompute failed # upstream: skip it like a blocked compute. diff --git a/datalab/gui/panel/history/recompute.py b/datalab/gui/panel/history/recompute.py index fdb08e355..ec6fe43f2 100644 --- a/datalab/gui/panel/history/recompute.py +++ b/datalab/gui/panel/history/recompute.py @@ -246,6 +246,19 @@ def recompute_mutation_in_place(panel: HistoryPanel, action: HistoryAction) -> b def recompute_action_in_place(panel: HistoryPanel, action: HistoryAction) -> bool: """Re-run ``action`` on the existing output object(s) (same UUIDs).""" + if getattr(action, "decode_failed", False): + # Broken persisted parameters: executing would silently change + # semantics (e.g. a mutation payload degraded to None deletes ROIs). + # Not marked stale: the action is permanently non-recomputable. + panel.runtime.execution.cascade_warnings.append( + _( + "Action %s was skipped: its recorded parameters could not " + "be read from the history file." + ) + % (action.title or action.func_name or action.uuid) + ) + panel.tree.refresh_action_item(action) + return False if ( action.kind == HistoryAction.KIND_UI and action.method_name in HistoryAction.UI_CREATION_METHODS diff --git a/datalab/history/action.py b/datalab/history/action.py index ba7c1035f..a54dd0a20 100644 --- a/datalab/history/action.py +++ b/datalab/history/action.py @@ -34,6 +34,7 @@ from datalab.gui import ObjItf from datalab.history.core import ( HISTORY_ACTION_SCHEMA_VERSION, + HistoryDecodeError, copy_history_value, decode_kwargs, encode_kwargs, @@ -202,6 +203,12 @@ def __init__( # display a "stale" visual marker in the tree. Cleared once the # action has been recomputed. self.is_stale: bool = False + # Transient flag (NOT serialized): set when a persisted kwarg payload + # could not be decoded at load time (e.g. corrupt or untrusted ROI). + # A broken action is permanently incompatible (see + # :meth:`is_current_state_compatible`) so it can never be replayed + # with altered semantics. + self.decode_failed: bool = False # Snapshot of original kwargs before edit-mode modification. # Set lazily when the first edit-mode change touches this action. # Persisted to HDF5 so the pre-edit values remain available after a @@ -260,6 +267,8 @@ def copy(self, title_suffix: str | None = None) -> HistoryAction: new_action.plugin_origin = copy_history_value(self.plugin_origin) new_action.output_uuids = list(self.output_uuids) new_action.effects = copy_history_value(self.effects) + # A broken action stays broken: its copy must not become replayable. + new_action.decode_failed = self.decode_failed # Note: saved_kwargs is intentionally NOT propagated to the copy. # Copying an action acts as an implicit commit (no pending edits). return new_action @@ -471,7 +480,12 @@ def is_current_state_compatible(self, mainwindow: DLMainWindow) -> bool: Mutation actions exclude their own targets from the ROI signature comparison (the recorded state contains the post-mutation ROI). + + Actions whose persisted kwargs could not be decoded at load time are + never compatible: replaying them would use degraded parameters. """ + if self.decode_failed: + return False return self.state.is_current_state_compatible( mainwindow, ignore_roi_uuids=self.__roi_exclusions() ) @@ -801,11 +815,31 @@ def deserialize_descriptors( def deserialize_kwargs_snapshot( action: HistoryAction, reader: NativeH5Reader, current: Any ) -> None: - """Deserialize call arguments and the optional edit snapshot.""" + """Deserialize call arguments and the optional edit snapshot. + + A payload decode failure (:class:`HistoryDecodeError`) is degraded locally + instead of aborting the whole file load: kwargs are reset to an empty dict, + a corrupted edit snapshot is dropped (``saved_kwargs = None``, no rollback + value) and the action is flagged as broken (``decode_failed``), routing it + into the existing incompatible-action UX. + """ if "kwargs" in current.attrs or "kwargs" in current: with reader.group("kwargs"): raw = reader.read_dict() - action.kwargs = decode_kwargs(raw) + try: + action.kwargs = decode_kwargs(raw) + except HistoryDecodeError as exc: + # ``decode_kwargs`` already emitted a user-visible warning: + # keep only a debug trace here to avoid double reporting. + _logger.debug( + "Failed to decode kwargs for action %s (%s): %s; " + "marking the action as incompatible.", + action.uuid, + action.func_name or action.method_name or action.title, + exc, + ) + action.kwargs = {} + action.decode_failed = True else: action.kwargs = {} # ``saved_kwargs`` group is present only when an Edit mode snapshot @@ -813,7 +847,21 @@ def deserialize_kwargs_snapshot( if "saved_kwargs" in current.attrs or "saved_kwargs" in current: with reader.group("saved_kwargs"): raw_saved = reader.read_dict() - action.saved_kwargs = decode_kwargs(raw_saved) + try: + action.saved_kwargs = decode_kwargs(raw_saved) + except HistoryDecodeError as exc: + _logger.debug( + "Failed to decode saved_kwargs for action %s (%s): %s; " + "marking the action as incompatible.", + action.uuid, + action.func_name or action.method_name or action.title, + exc, + ) + # No usable rollback value: drop the snapshot entirely so + # ``has_pending_edits`` stays False (``decode_failed`` already + # marks the damage). + action.saved_kwargs = None + action.decode_failed = True else: action.saved_kwargs = None diff --git a/datalab/history/core.py b/datalab/history/core.py index c1d0fc437..709e66c74 100644 --- a/datalab/history/core.py +++ b/datalab/history/core.py @@ -37,6 +37,20 @@ _ROI_MARKER = "__roi_json__" +class HistoryDecodeError(Exception): + """Raised when a persisted history kwarg payload cannot be safely decoded. + + Args: + key: Name of the kwarg whose payload failed to decode. + error: Original exception raised by the low-level decoder. + """ + + def __init__(self, key: str, error: Exception) -> None: + super().__init__(f"Failed to deserialize history ROI kwarg {key!r}: {error}") + self.key = key + self.error = error + + def get_datetime_str() -> str: """Return current date and time as a string""" return QC.QDateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss") @@ -131,7 +145,15 @@ def encode_kwargs(kwargs: dict[str, Any]) -> dict[str, Any]: def decode_kwargs(kwargs: dict[str, Any]) -> dict[str, Any]: - """Inverse of :func:`encode_kwargs`.""" + """Inverse of :func:`encode_kwargs`. + + Raises: + HistoryDecodeError: If a ROI payload cannot be decoded (untrusted + module, unknown class, corrupted payload). A degraded ROI value + would silently change replay semantics (None means "delete ROIs" + for mutations), so the caller must flag the owning action as + broken instead of substituting a default value. + """ decoded: dict[str, Any] = {} for key, value in kwargs.items(): if isinstance(value, dict) and _DATASET_MARKER in value: @@ -145,10 +167,15 @@ def decode_kwargs(kwargs: dict[str, Any]) -> dict[str, Any]: elif isinstance(value, dict) and _ROI_MARKER in value: try: decoded[key] = decode_roi(value[_ROI_MARKER]) - except Exception as exc: - raise ValueError( - f"Failed to deserialize history ROI kwarg {key!r}: {exc}" - ) from exc + except ( + TypeError, + ValueError, + KeyError, + ImportError, + AttributeError, + ) as exc: + warnings.warn(_("Failed to deserialize history ROI kwarg %r.") % key) + raise HistoryDecodeError(key, exc) from exc elif isinstance(value, dict) and _DATASET_LIST_MARKER in value: try: decoded[key] = [ diff --git a/datalab/tests/features/common/history_model_unit_test.py b/datalab/tests/features/common/history_model_unit_test.py index 6cb3de4f8..0023974ca 100644 --- a/datalab/tests/features/common/history_model_unit_test.py +++ b/datalab/tests/features/common/history_model_unit_test.py @@ -4,6 +4,7 @@ from __future__ import annotations +import json import os import tempfile from contextlib import contextmanager, nullcontext @@ -720,6 +721,60 @@ def test_action_hdf5_current_and_legacy_contract() -> None: assert legacy.state.titles == {"signal": ["Source"]} +def test_action_hdf5_roi_decode_failure_degrades_locally() -> None: + """Degrade a corrupt ROI kwarg locally instead of aborting the file load.""" + action = build_history_action() + # Raw marker dict passes through encode_kwargs untouched, simulating a + # persisted ROI payload referencing an untrusted (non-sigima) module. + corrupt_payload = { + "__roi_json__": json.dumps( + {"module": "evil.module", "class": "FakeROI", "data": {}} + ) + } + action.kwargs["payload"] = corrupt_payload + # A corrupted edit snapshot must be dropped (no usable rollback value). + action.saved_kwargs = {"payload": dict(corrupt_payload)} + valid_action = build_history_action() + session = HistorySession(number=1) + session.add_action(action) + session.add_action(valid_action) + with tempfile.TemporaryDirectory() as tmpdir: + path = os.path.join(tmpdir, "history.dlhist") + with NativeH5Writer(path) as writer: + writer.write_object_list([session], "history_session") + with pytest.warns(UserWarning, match="ROI kwarg"): + loaded = read_history_sessions(path)[0] + broken, intact = loaded.actions + # The broken action loads with degraded kwargs and is permanently + # incompatible, so it can never be replayed with altered semantics. + assert broken.decode_failed is True + assert broken.kwargs == {} + assert broken.saved_kwargs is None + assert broken.has_pending_edits is False + assert broken.is_current_state_compatible(Mock()) is False + assert broken.copy().decode_failed is True + # The rest of the file loads normally. + assert intact.decode_failed is False + assert intact.kwargs == {"obj2_uuids": ["second-uuid"], "pairwise": False} + + +def test_recompute_in_place_skips_decode_failed_action() -> None: + """Never execute an action whose persisted parameters failed to decode.""" + warnings: list[str] = [] + panel = SimpleNamespace( + runtime=SimpleNamespace(execution=SimpleNamespace(cascade_warnings=warnings)), + tree=SimpleNamespace(refresh_action_item=lambda action: None), + ) + action = HistoryAction( + title="Edit ROI", kind=HistoryAction.KIND_MUTATION, mutation_key="roi" + ) + action.decode_failed = True + assert hrec.recompute_action_in_place(panel, action) is False + # Not marked stale: the action is permanently non-recomputable. + assert action.is_stale is False + assert any("Edit ROI" in warning for warning in warnings) + + def test_action_copy_remaps_all_uuid_references() -> None: """Copy an action independently and rewrite every captured UUID field.""" action = build_history_action() From c3e57a74cbd14458c6b672f025299e96824dd17d Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Thu, 13 Aug 2026 11:47:52 +0200 Subject: [PATCH 093/108] Fix: History panel: recording no longer crashes on objects without data WorkspaceState.save built the informative shape list with a direct obj.data.shape access, raising AttributeError when a selected object had no data array and aborting the user's operation at recording time. The shape capture is now defensive, consistent with get_object_metadata, and stores an empty placeholder instead. --- datalab/history/workspace_state.py | 2 +- .../common/history_model_unit_test.py | 27 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/datalab/history/workspace_state.py b/datalab/history/workspace_state.py index 277d9a318..3d34e6659 100644 --- a/datalab/history/workspace_state.py +++ b/datalab/history/workspace_state.py @@ -220,7 +220,7 @@ def save(self, mainwindow: DLMainWindow, panel_str: str | None = None) -> None: for panel in (mainwindow.signalpanel, mainwindow.imagepanel): sel_uuids = self.selection.get(panel.PANEL_STR_ID, []) self.states[panel.PANEL_STR_ID] = [ - str(obj.data.shape) + str(getattr(getattr(obj, "data", None), "shape", "")) for obj in panel.objmodel if get_uuid(obj) in sel_uuids ] diff --git a/datalab/tests/features/common/history_model_unit_test.py b/datalab/tests/features/common/history_model_unit_test.py index 0023974ca..2d6a7178b 100644 --- a/datalab/tests/features/common/history_model_unit_test.py +++ b/datalab/tests/features/common/history_model_unit_test.py @@ -17,6 +17,7 @@ from sigima.objects import ( Gauss2DParam, ImageObj, + SignalObj, SignalROI, create_image_from_param, create_image_roi, @@ -887,6 +888,32 @@ def test_state_compatibility_handles_roi_signature_and_legacy_metadata() -> None assert not state.is_current_state_compatible(mainwindow) +def test_workspace_state_save_tolerates_object_without_data() -> None: + """Capture states without crashing when a selected object has no data.""" + obj = create_paracetamol_signal() + empty_obj = SignalObj() + empty_obj.title = "Empty" + + def make_panel(panel_id: str, objs: list) -> SimpleNamespace: + return SimpleNamespace( + PANEL_STR_ID=panel_id, + objmodel=CascadeObjectModel(objs), + objview=SimpleNamespace(get_sel_objects=lambda include_groups=True: objs), + ) + + mainwindow = cast( + DLMainWindow, + SimpleNamespace( + signalpanel=make_panel("signal", [obj, empty_obj]), + imagepanel=make_panel("image", []), + ), + ) + state = WorkspaceState() + state.save(mainwindow) + assert state.states["signal"] == [str(obj.data.shape), ""] + assert state.object_metadata["signal"][get_uuid(empty_obj)] == {} + + def test_mutation_action_model_contract() -> None: """Round-trip, copy and remap mutation actions with and without payload.""" From 6675786bed130bdcf281ff0333028bce01cbcf03 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Thu, 13 Aug 2026 14:05:29 +0200 Subject: [PATCH 094/108] Fix: History panel: coalesce compatibility refreshes triggered by workspace changes The full-tree compatibility refresh (O(actions x objects), including ROI signature hashing) was connected directly to the object added/removed/modified signals of both data panels, so batch file loads and intermediate objects created during cascade recomputes triggered one full refresh per object, freezing the UI on large workspaces with long histories. Signal-driven refreshes are now coalesced per event-loop turn (pending flag + zero-delay timer, mirroring the existing session prompt debounce), with a liveness guard for shutdown. Explicit refresh calls in engine epilogues remain synchronous, and the reconnect/prune ordering on object removal is unchanged. --- datalab/gui/panel/history/runtime.py | 34 +++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/datalab/gui/panel/history/runtime.py b/datalab/gui/panel/history/runtime.py index 31dfc730b..84c3fd5b6 100644 --- a/datalab/gui/panel/history/runtime.py +++ b/datalab/gui/panel/history/runtime.py @@ -137,6 +137,7 @@ def __init__( self.action_output_uuids: dict[str, list[str]] = {} self.output_to_action: dict[str, str] = {} self.tracking_enabled = False + self.compatibility_refresh_pending = False self.object_tracking_connections: list[tuple[Any, Any]] = [] self.build_tracking_connections() @@ -150,12 +151,12 @@ def build_tracking_connections(self) -> None: ( ( data_panel.SIG_OBJECT_ADDED, - self.panel.refresh_compatibility_items, + self.schedule_compatibility_refresh, ), (data_panel.SIG_OBJECT_ADDED, self.refresh_obj_ids_snapshot), ( data_panel.SIG_OBJECT_REMOVED, - self.panel.refresh_compatibility_items, + self.schedule_compatibility_refresh, ), ( data_panel.SIG_OBJECT_REMOVED, @@ -164,11 +165,38 @@ def build_tracking_connections(self) -> None: (data_panel.SIG_OBJECT_REMOVED, self.prune_output_mapping), ( data_panel.SIG_OBJECT_MODIFIED, - self.panel.refresh_compatibility_items, + self.schedule_compatibility_refresh, ), ) ) + def schedule_compatibility_refresh(self, *args: Any) -> None: + """Coalesce signal-driven compatibility refreshes within an event-loop turn. + + Data panel object signals (added/removed/modified) may fire many times + in a row (file loading, cascade recompute); a single + :meth:`HistoryPanel.refresh_compatibility_items` run is deferred until + control returns to the event loop. Explicit epilogue refreshes remain + synchronous and do not go through this debounce. + + Args: + args: Signal payload, ignored + """ + del args + if self.compatibility_refresh_pending: + return + self.compatibility_refresh_pending = True + QC.QTimer.singleShot(0, self.run_pending_compatibility_refresh) + + def run_pending_compatibility_refresh(self) -> None: + """Run the deferred compatibility refresh scheduled by data panel signals.""" + self.compatibility_refresh_pending = False + try: + self.panel.refresh_compatibility_items() + except RuntimeError: + # Panel widgets were destroyed before the timer fired (shutdown) + pass + def set_tracking_enabled(self, enabled: bool) -> None: """Enable or disable synchronization with data panel object changes.""" if enabled == self.tracking_enabled: From a8dec1d27250bf5d8328998a1a684ccd6137fafc Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Thu, 13 Aug 2026 16:38:03 +0200 Subject: [PATCH 095/108] Doc: History panel: align session model description and document stability fixes The documentation stated that the Signals and Images panels each had their own active history session, which does not match the actual behavior: a single active recording session is shared by both panels, with sessions related to panels only through the actions they contain. Also documents the new behaviors introduced by the stability fixes: amber marking of outdated steps, unavailability of History commands while a replay or recompute is running, and degraded loading of undecodable history entries. Adds the corresponding user-focused entries to the 1.3.0 release notes. --- doc/features/common/historypanel.rst | 45 +++++++++++++++++++++------- doc/release_notes/release_1.03.md | 5 ++++ 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/doc/features/common/historypanel.rst b/doc/features/common/historypanel.rst index ec71444d2..272040ec1 100644 --- a/doc/features/common/historypanel.rst +++ b/doc/features/common/historypanel.rst @@ -79,9 +79,12 @@ Recording and session lifecycle Actions are recorded only while **Record mode** is enabled. Turning record mode off preserves existing sessions but does not add new entries. -The Signals and Images panels each have their own active session. New actions -are added to the active session of the data panel they concern, so switching -between signals and images does not mix their recording contexts. +There is a single active recording session, shared by the Signals and Images +panels. New actions from both panels are chained into that session (one is +created on first use), so mixed signal/image pipelines are recorded together +and recording resumes in the user-selected session. Each session remains +associated with the Signals or Images panel for display purposes, through the +actions it contains. When a new object is created or a file is loaded into a populated active session, a configurable policy determines whether DataLab asks, starts a new @@ -157,8 +160,8 @@ The toolbar at the top of the panel exposes the following actions: - |record| **Record mode**: toggle the recording of new actions. When off, no new entry is added to the history (existing sessions are preserved). -- |new_session| **New session**: start a new active history session for the - current data panel. +- |new_session| **New session**: start a new history session and make it the + active recording session. - |open_history| **Open history file**: load recorded sessions from a standalone ``.dlhist`` file. - |save_history| **Save history file**: save the current recorded sessions to a @@ -222,14 +225,22 @@ The toolbar at the top of the panel exposes the following actions: Double-clicking a tree item invokes **Replay** for the current selection, with the same in-place recompute semantics documented above. +.. note:: + + While a replay or recompute is in progress, History Panel commands are + unavailable: the toolbar actions are disabled, and tree interactions + (context menu, double-click, :kbd:`Del` key) are ignored until the run + completes. + Tree view --------- The tree view organizes recorded actions into expandable sessions: -- Each top-level row is a **session** associated with the Signals or Images - panel. Sessions may be started when recording is enabled, with **New - session**, or according to the configured session policy. +- Each top-level row is a **session**; the panel(s) it relates to are + determined by the actions it contains. Sessions may be started when + recording is enabled, with **New session**, or according to the configured + session policy. - Each child row is an **action**, with its title, date/time and a description summarising its parameters or resolved call when available. A UI action whose call cannot be resolved may have an empty description. @@ -242,8 +253,8 @@ When an action row is selected, its result object is selected in the corresponding data panel when available; otherwise, its existing input objects are selected. DataLab then switches to that data panel. -While Record mode is enabled, selecting a session row makes that session active -for its data panel. +While Record mode is enabled, selecting a session row (or one of its actions) +makes that session the active recording session. Actions that are not compatible with the current workspace state (for example because a referenced object identifier no longer exists, or because its data @@ -252,6 +263,11 @@ tooltip. Attempting to replay them opens the broken chain resolution dialog described below. +Actions left **outdated** by a failed or interrupted recompute, or by +parameter edits whose propagation to downstream steps is still pending, are +highlighted with an amber background and carry an explanatory tooltip. +Replaying them refreshes their result and clears the marker. + Broken chain resolution ----------------------- @@ -302,6 +318,15 @@ The history can be persisted in two complementary ways: remaps their identifiers to avoid collisions, and appends imported history sessions that reference those fresh identifiers. +.. note:: + + A history entry whose saved parameters can no longer be decoded (for + example a ROI payload written by an incompatible version of DataLab) does + not prevent the rest of the file from loading: the affected action is + loaded as incompatible — shown as a disabled row with an explanatory + tooltip, and never replayed — while all other sessions and actions load + normally. Such entries can be cleaned up with **Remove incompatible**. + .. warning:: Replaying a session that depends on external files (e.g. opening a diff --git a/doc/release_notes/release_1.03.md b/doc/release_notes/release_1.03.md index 9f15d7bfc..bfa99d398 100644 --- a/doc/release_notes/release_1.03.md +++ b/doc/release_notes/release_1.03.md @@ -80,3 +80,8 @@ and Image panels. * Fixed duplicated processing chains interfering with their source chain: replaying either session now only affects its own objects * Fixed session replay aborting when the session contained a recorded object deletion — recorded deletions that can no longer be safely applied (captured state mismatch, targets re-created earlier in the same replay, or targets belonging to another session) are now skipped with a warning * Removed the yellow highlight that could persist on history entries after a failed replay +* Fixed outdated steps having no visual indication in the history tree — actions left outdated by a failed or interrupted recompute, or by parameter edits pending propagation, are now highlighted with an amber background and a tooltip suggesting to replay them +* Fixed potential crashes or corrupted histories when clicking History panel commands (Replay, Delete, Duplicate, ...) while a long replay or recompute was still running — commands are now unavailable until the run completes +* Fixed a single corrupted history entry (e.g. a ROI saved by an incompatible version) preventing an entire `.dlhist` file or HDF5 workspace history from loading — the affected action now loads as incompatible while the rest of the history loads normally +* Fixed recording aborting the user's operation when a selected object had no data +* Improved performance: opening many files or replaying long processing chains no longer freezes the interface while the History panel repeatedly rechecks action compatibility From b9a2e291f0f1fd64e623013b4224284904205edd Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Fri, 14 Aug 2026 10:41:18 +0200 Subject: [PATCH 096/108] i18n: update French UI translations for History panel stability fixes Adds translations for the new outdated-step tooltip and the undecodable-entry replay warning, and fixes fuzzy entries introduced by the translation scan. --- datalab/locale/fr/LC_MESSAGES/datalab.po | 46 +++++++++++++++++------- 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/datalab/locale/fr/LC_MESSAGES/datalab.po b/datalab/locale/fr/LC_MESSAGES/datalab.po index 38df314ae..b2c02981f 100644 --- a/datalab/locale/fr/LC_MESSAGES/datalab.po +++ b/datalab/locale/fr/LC_MESSAGES/datalab.po @@ -4,7 +4,6 @@ # msgid "" msgstr "" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" @@ -65,6 +64,9 @@ msgstr "Assistant IA prêt. Configurez votre fournisseur dans le menu Edition > msgid "You" msgstr "Vous" +msgid "Assistant" +msgstr "Assistant" + msgid "Save to Macros" msgstr "Enregistrer dans les macros" @@ -1508,12 +1510,12 @@ msgstr "Supprimer les métadonnées" msgid "Some selected objects have regions of interest.<br>Do you want to delete them as well?" msgstr "Certains objets sélectionnés ont des régions d'intérêt.<br>Souhaitez-vous les supprimer également ?" -msgid "New group" -msgstr "Nouveau groupe" - msgid "Group name:" msgstr "Nom du groupe :" +msgid "New group" +msgstr "Nouveau groupe" + msgid "Rename object" msgstr "Renommer l'objet" @@ -1640,6 +1642,9 @@ msgstr "Effacer toutes les macros récentes ?" msgid "Macro panel" msgstr "Panneau des macros" +msgid "Python files" +msgstr "Fichiers Python" + msgid "Clear console" msgstr "Effacer la console" @@ -3379,12 +3384,12 @@ msgstr "Cliquer sur OK pour démarrer la démo.<br><br><u>Note :</u><br>- La dé msgid "Click OK to end demo." msgstr "Cliquer sur OK pour terminer la démo." -msgid "Error:" -msgstr "Erreur:" - msgid "Context" msgstr "Contexte" +msgid "Error:" +msgstr "Erreur:" + #, python-format msgid "The file %s could not be read:" msgstr "Le fichier %s n'a pas pu être ouvert :" @@ -3601,18 +3606,18 @@ msgstr "Déplier la sélection" msgid "HDF5 Browser" msgstr "Explorateur HDF5" -msgid "Size" -msgstr "Taille" - -msgid "Type" -msgstr "Type" - msgid "Value" msgstr "Valeur" msgid "Name" msgstr "Nom" +msgid "Size" +msgstr "Taille" + +msgid "Type" +msgstr "Type" + msgid "Unsupported data" msgstr "Données non prises en charge" @@ -3718,6 +3723,9 @@ msgstr "Distance minimale :" msgid "Signal peak detection" msgstr "Détection de pics 1D" +msgid "Peaks:" +msgstr "Pics :" + msgid "Internal console" msgstr "Console interne" @@ -4283,6 +4291,10 @@ msgstr "L'action %s cible des objets produits par une autre session ; elle a ét msgid "Action %s has no recorded pattern and cannot be replayed." msgstr "L'action %s n'a pas de motif enregistré et ne peut pas être rejouée." +#, python-format +msgid "Action %s was skipped: its recorded parameters could not be read from the history file." +msgstr "L'action %s a été ignorée : ses paramètres enregistrés n'ont pas pu être lus depuis le fichier d'historique." + msgid "History panel" msgstr "Panneau d'historique" @@ -4475,6 +4487,10 @@ msgstr "Importé" msgid "Failed to deserialize history DataSet kwarg %r." msgstr "Échec de la désérialisation de l'argument DataSet de l'historique %r." +#, python-format +msgid "Failed to deserialize history ROI kwarg %r." +msgstr "Échec de la désérialisation de l'argument ROI de l'historique %r." + #, python-format msgid "Failed to deserialize history DataSet-list kwarg %r." msgstr "Échec de la désérialisation de l'argument DataSet-list de l'historique %r." @@ -4494,6 +4510,9 @@ msgstr "L'action est compatible avec l'état actuel de l'espace de travail." msgid "Action is not compatible with the current workspace state." msgstr "L'action n'est pas compatible avec l'état actuel de l'espace de travail." +msgid "This step is outdated: replay it to refresh its result." +msgstr "Cette étape est obsolète : rejouez-la pour actualiser son résultat." + msgid "Active recording session." msgstr "Session d'enregistrement active." @@ -4508,3 +4527,4 @@ msgstr "Image" msgid "Dimensions" msgstr "Dimensions" + From b0089baeeb3219d3b5fc5a53cac689781e852d87 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Fri, 14 Aug 2026 13:26:45 +0200 Subject: [PATCH 097/108] Style: History panel: address new pylint warnings from stability fixes Replaces argument-less pass-through lambdas by direct bound-method references in the guarded toolbar wiring, and scopes a pylint disable on recompute_action_in_place for the additional early return added by the decode-failure guard. --- datalab/gui/panel/history/recompute.py | 4 +++- datalab/gui/panel/history/ui.py | 8 ++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/datalab/gui/panel/history/recompute.py b/datalab/gui/panel/history/recompute.py index ec6fe43f2..08413864c 100644 --- a/datalab/gui/panel/history/recompute.py +++ b/datalab/gui/panel/history/recompute.py @@ -244,7 +244,9 @@ def recompute_mutation_in_place(panel: HistoryPanel, action: HistoryAction) -> b return bool(mutated) -def recompute_action_in_place(panel: HistoryPanel, action: HistoryAction) -> bool: +def recompute_action_in_place( # pylint: disable=too-many-return-statements + panel: HistoryPanel, action: HistoryAction +) -> bool: """Re-run ``action`` on the existing output object(s) (same UUIDs).""" if getattr(action, "decode_failed", False): # Broken persisted parameters: executing would silently change diff --git a/datalab/gui/panel/history/ui.py b/datalab/gui/panel/history/ui.py index 4f60c32a8..c169df1b9 100644 --- a/datalab/gui/panel/history/ui.py +++ b/datalab/gui/panel/history/ui.py @@ -63,21 +63,21 @@ def create_actions(self) -> dict[str, QW.QAction]: "new_session": create_action( panel, _("New session"), - self.guarded(lambda: panel.create_new_session()), + self.guarded(panel.create_new_session), icon=get_icon("libre-gui-add.svg"), tip=_("Start a new history session"), ), "open": create_action( panel, _("Open history file..."), - triggered=self.guarded(lambda: panel.open_dlhist_file()), + triggered=self.guarded(panel.open_dlhist_file), icon=get_icon("fileopen_h5.svg"), tip=_("Open history from a standalone .dlhist file"), ), "save": create_action( panel, _("Save history file..."), - triggered=self.guarded(lambda: panel.save_to_dlhist_file()), + triggered=self.guarded(panel.save_to_dlhist_file), icon=get_icon("filesave_h5.svg"), tip=_("Save history to a standalone .dlhist file"), ), @@ -129,7 +129,7 @@ def create_actions(self) -> dict[str, QW.QAction]: "step_by_step": create_action( panel, _("Step-by-step"), - triggered=self.guarded(lambda: panel.replay_step_by_step()), + triggered=self.guarded(panel.replay_step_by_step), icon=get_icon("edit_mode.svg"), tip=_( "Replay the selection step by step, editing parameters at each step" From 819993e96450017999df57dfc167cf322963f96a Mon Sep 17 00:00:00 2001 From: Stefano Pierini <s.pierini@codra.fr> Date: Fri, 14 Aug 2026 15:02:21 +0200 Subject: [PATCH 098/108] Doc: History panel: add images section in tutorial and enhance workflow description --- doc/images/tutorials/history_panel/10.png | Bin 0 -> 523851 bytes doc/images/tutorials/history_panel/11.png | Bin 0 -> 822606 bytes doc/images/tutorials/history_panel/12.png | Bin 0 -> 248002 bytes doc/intro/tutorials/history_panel.rst | 50 ++++++++++++++++++++-- 4 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 doc/images/tutorials/history_panel/10.png create mode 100644 doc/images/tutorials/history_panel/11.png create mode 100644 doc/images/tutorials/history_panel/12.png diff --git a/doc/images/tutorials/history_panel/10.png b/doc/images/tutorials/history_panel/10.png new file mode 100644 index 0000000000000000000000000000000000000000..524de0a168773cac12ccd67f0282051028dcc0da GIT binary patch literal 523851 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ⅆ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�u7@V7JI0ekGzdy^0P@W=05UKd4&dFnO%tdWvfin%7*gh`M zwbpQ$MRPBwQ!XXmbsh=6cg8bitpgJG?g7oS58#@ihrWWBTlkvpZF;Zfe{!bAZXC=X zO(?=9OO?yf9~%kr<*}pwqw4NFy)h84Mm`<AuhA+3-?6bC=Fw|48J!=Up}w5lT>Ou< zdUpbH7sB@;(;+PKYIjNZ4ksOX{hy9iChssi;$3bzH~g+b!*5M)M?a}06~hnjM?W2$ zRPapjYn7^M?UJm1M56n@wk&a)a{-S_-!^~`QtuP93bp=bPRFozZY&_KXVX8l%Cg1B z-Cf+7=H4gv>uc#-RG8lY59$wpb8`8_oGjDOSQZ1~=8t)n?)*fhy>FGs`JsZA<nj+& zay8ji_T!`mJYvPsvcu{pt8p>FTYMt=<oN0jy_A-#oq%DATOdvCI;pDSNT!I^M|}qJ zQnBa8t<Zy|&%AZ?^R*Hl^$v^0lk#lSP}XYY-x9=9My^)9Y!o{o&E&b7mX=Sxwrqai zkChanTDsCq&@Wtudm`%CG>6~3V=vM^5rrakJ!>Lhs&mZTACmmSWZ4v^5_iRZoqZVA zJnVg;yjW9^n5rhV=GjPt#t~t(ox8r|NV*&0i-=55q2#Q?M3ZN;s4I#}%&CN5OJ;wG z)1NhBZi4ilQKUvlHVno+%d3q}RK&trx`|Wtl+;ul&8!iNdD$PlJTZTc)g&tyGqy&U z%<{Dxzh_6GwVtqU+f%^C-hHX*Wr34Q=Qe_4+Bo08WRSp~6*Udd>1$;$W!Xd#)<r$+ zxyGOKp8ae1Pf8ni1wteivjd&}+d^xVN}rn)%c5s%Bl}IYd*}<~nh5*R1dD?Z!$o2n z_u=9F%w}?zM?w*DVc2hfL4@gZ7y1HOutz?qfp61rk%6#ITuYu>atz$6=3TGPJZ6oL z#*{o~vA+uQ3ZI~tkMBoATi=C}vd9$v6w@2#JoRqZS$dx$z<0PTXH23M&nipFF5~Hi zRjaV<l>LNEi4RA~t(F;&Hk4WT`!m?Pi(icS5jG|hI_HBp2jn%zr}ej<W{opgojSA| zKODgo0YT7eOP8M%wQSXhsg@=(>Qlv?`<Mw1P~uN}N0@EizEW&?(z|t6+q^d7__CqR zIciEGjL{cq6tm}RjbYtkKjy0TrK==$dYnrIQ>7=jl8dDlOLV1?H`SJO7n{1*MfAr2 z3uGNzGjVhwwxp?=oI``XA^Af6+~<)xfuB<&&WGMmxF|hzZK!<VD$aL6FIX()y{4Lb zP(iL>X5;5HTfK*<XJYo&GAO5FzZ@lD3aw_gES?#XU1CISP+q5H=_ee;iQxH~32M^j zVV}G{{~#ru@uW|rLBZV)uXWhj=s)Xf@nqyryuZFXyTluxey--<U*22vAgd<8`WwoF z_<MrS*q6JU8zz68{eG?T9^RX2y8osBG`Gn#+)w>Uk&@jl=JhmhomD=bp%rWS2~mqx zwuAg^?K#F5n%2aW6Ok6$%aT&w>{q<P+BqK)_~^=7pb7t4y8h$QXVD*A8K%DmG{KuC zkg5TxO11`NBZhT+<bVsS9VhOO+mgrZXY@nMRle+n8>#~PCO7q2@Ri|2Ekt%}=B1Rp zA?D>?{<>gqo+Hn`OTg^KM{hJajrQRb{rZ{Tn-H692M%N^i|;2XQ_Ck5l6^|TITP%w zgNMqdv^tpuhZ>l}b4mM>U3uiLhkcGxT>`V~*h}$7`k{%h;S&}F56`|Pe@D4QCXXYA zEq^{EB~IQERjT&UA9h-wy7XL5cirx@&D9JrSMiR8)R)IeG~zNq1&OA|W=57(8!6Q& z%=>!wQ&K7MoD}8wi^?Xp8#7K?GO!e*gmm0T30qBV^Ub{o<yRUs-0k{jN;`v>)7`aE zLH8y0i_JGH9L_t1S*uy+#dlQbH9oVicP$1%B)1LCiHvXYO>!xmPrXHS%t-$##a|Gb zAWl<NXJ$I$HOdPa$VlVj!91ylv|=%c>BVW($(G1P_nS?yRO7xEw;bYD=co6j$xcZX z^)=$1!F<@##|+bsWqe*Au~bi35)l>AOrBo($)7Xr@mza92a%7q$?@E%t+{(`%U-f; zMg?j9^01&?(T8G(Oq<8pv$ZD=sFs=G8E87PH=yUxYeD^pOg0ok*bXGnYh*&al;_$l zcW*^n2yRu6c0xv$@%<Ow<uly1RvR>KS|m!sq*z*T0}7~*Dl^Pyo##d?eeUZUUS5{X z=;m2|@+@``$obWnQGJQwyX=xsVaH9He{oF`AqZ-0f|09rqhoGzVHE<JYHI~MW1V=N z-J7a(S#B6)o_68Z4Po`})f&-oYkErvZuJwM4$N$<L?-va0;6e}VX-i+whLc(394<^ zx{D?oL_YS4qUSTS&b*{<beQo$Ns;?t3VaAPnt9$P(e&6gNRv>F<$Xp4Xz8#wt65wi zI!ld&ROzHS5I#$J``N1f8%yWQ2F*6kZvS~F8A_fKk2%oSY%e(~A8Ls*Xge2DB(92} zaD9~0EY)^WU-Xw<$@85NX)$YY|MljxJSLV?dfPUo<QT~)2Fv$83*WV1qobuUc%dkq zPV`X8Yq>qODy>8u%uRj!FY6;Du1ow#h4)tc&i{_&llVa$%=T}d$qT2y8>@GZjW0H$ z)i!SzlJ1XScX~-#BA_{*9E>x#rZQ>Vrikm}n?vJMm_4DpA03@i7xW;a>Q$W|8A-%D z6|RqHvm5tV%v8gGSBXfM45a@S<<|QoyHk2KY9vu6avKA+ZUlFF8jYz9q5Q$J9E&M| zZLJdHUg))`+emT>`-A0bJPZq{X{vxBiJuE%QbgZ4pS=?tfJDb?VZog6M9$R5bP)pj z*huuPRLTM;!s@T3zhWyr?2}N6vYZL!>*Eg9`y-pFbFshy()N7j=Moq$CLguy4X5w$ z2E;Y}vka|FVZp*8a^u2`p$g7df(9JOkk{}m7RU!bgkcR#2r7<`ANN~ozC9H7Jk;9y zqu~NBVcmwOfNTK*zTx0f4t2*;$9uXI@urZ1mL;OTqBNm%&jR914ApM$|4z*_MGS5V z(lk-tIuc%PvTxs<QjM#G!GE!R9SBfDX)^ca1E=NBN;|0e2=#zX2w!>7OaYa-d!RQ| zJpZi)Vc3*3XuQ9Z*WqDkAxwSG@-!2GY8~ZqMlVxpUflaSGu6lohyF%i0Kg~=LMZ6g z2jfv+%`_x;dX2l4azbLIP|0e)wH^h<2RExU=D(Z$mO8NK&N!c&`1_}#P^Kkop+4L9 zb|;Vdv4xO00sYE4VnTX@1lhGY=^zDdC-jwio3AaRS`r=h;~v}S`j|a!OAH>wG2Pfo zBd<PFl!<V@7dlh@t!?U7ihHmd;-C0kv5sjzy1i1xZBg6POWr*YHb13#=&_t$gC``V zkzu;3tDyBE-rmoIf7=Icc(m5LAo4jqWrZMjOS~k@3`>`ol%dQmg$1&?5-8{-Lx?On z@j%|raMP<Kp8RI5K7Ac8h3Ts`eBc}ya~rck*amJg9Ji?6jXbk#2SdL4673~MQa^B? zGRW*5pCdv8AJ?sqgjIMu2{sisH?ractg5w%`i?7lmMF|&%CzLZyPf{%6sd4oAwNH6 zGdgQGeg&TFhi(n4S{Rx@RUNVKvTAVTJd(`7q!uO=>{Mdj2aYA^@_fHu4sD#8Yi47U z-PZexT-HKaWy&q6vE`R*<=qyP_%yjULeI|!@u~Mjd0Q>=@!GOP-&^UV8*qCH=H$yC zZh-dab^PT?X560rI_6#QjS$T5>%LCFMas!t0o`Hor)wC;s@VTOetYxVJ5BBEhlEQ^ z_fmH@_m9Jn^Y=q9?XOw~{-)kDC2LYIZC1$%<n${E2WvhyEKN*VDflkd&G?nnr?v#= z8}cg&JTQxOMXf(l+}mUD2cD-HwI`=Hkpid<PhYTn-8j97Q~y?Pr=#}UhTm<ZC)csR zWU8)z?;=t_f2E$6V-!F}!rYtKiXS;b)nCx$-mK?Zr~0XN;9)o~l7Sw6X1}SCHPdo< z+In4p$dF-2odwQ&t``3?RK|bhjY98c5cQ-=Ypg7D0}h(cr@VGXm4u!bazZowv@DXf z#i_O_1rf90-A!c=+dUR*B2XI9y%rO6O8sq55_yj5uZHjw)#i2}E|HWmnfJ&)a4U8w zlz9`%=#s_qnRgSw6lH@nn3HrNTJw9*^e#{&ry#K&IZ47QIIp8_2JOU8@ZXEn_6jLi zAM0M<7G@9->N=VCRgj<RLEnWv58Ai6DYoNYKra@3o@F0m#rvTf^ZEfn%^1i27J8Oo zyDTAFXiVLOFOQ}3H`Qo$esG(JJ;$kqf)Fqq)X?=wyh&*QZW!hN>`yzsE2I$gdtX|X z(Mk)TspS(=k;j5-br(;miB*tsEY?2iCT5!1(dy)PJLr#mCk?C5e6f*SEa0X<9d+hY z$<Lj0n%Z+rzNN)OCVxbJ)lpWwRd4W_Og|;f??a@I7}dCsk0jdc>Q}QIt;wi|XN+v* zR5m&EgAN37soYvCyK(+Vf6tQIW++E1JN&1`x5@0VJIQ14&7Ho5N)%d-Up6hLuqGYo z1*yeu!vjm;Owg%QHUlm`{?O#SSa~BM8a0<hcNnGl&2wT`yTcFW7ew;zT9_?c6=~c& zn3)U2i>gO_glW)xJf^Y}BVnt9hq~x}Vl}K|@yDJJ9iNUS+H4iA_7HzsE?xu1t<JKo z$YIN5@!@Ah-A|!{`PgJS@CeCwZmxu&5kc~DW0uEViY3?=>9oTbk0kv11&EfKu@-5L z{5EgfTzL}*`&MpF>eCE%E;L0c)ZQZtZr&%jL-%Z(8>gPREG-y$l=%C(&=<Oo<CQY8 z8Hs;4z8>7Vr|BpvdJbSVrH>xt196Sak4~viU;qjXsPA=x0*U7&ts?lfbhD7yLO8pr zmi!{;6~v{(p$LE#rBc3?ev#RFn5PRpTYy;$3Bc2Al<&D&2F6o655JRJXhdDV5o{aS zQoMhv)oCKA@o7mm$@#yw)GV@HwBEni`Xi3>o3rvk&lnfyU+-TXSBE)(KluyiSf!)> zbjSTiv$qwi_8p*LKKjuWw5qZ29xh+idlzeEN2O}*9G41h=rz*lu*3Xb_;ZlShl1?F zXPr;^Lt~DuyvIJNi%JzBrQTZFvQ*a1mOO;oUqp@s9BzFaY^y7m;v`GOD4SrC9z|S| zr9G%x<h{r-C6s5hhDq^qH6+8NLD><|cR~yf{zw-Na8|0{my$@64?*>6S+C5f#=9O| zAhH#r(?R=txReaei6X``KY-w$8MBCENMjIjaeKp)ammEXv$Fj`OOygX<}(0jSAO|D zL<j4KoKX?2YH3IcoO^<w-l*m=1`3I_g30{8R2L6fJyfvsZBQ>X(_JhJY#^;A4vpcR zAwERd)oxSlX<oM;*V1}{bELaefSgZdK}xK&a_>!Siv&~}F~dUx!{Hjikwx%0Xx;jE zM-Fi*W_ZZcgp2niyRM^W(I1ifn%%#1xBl$MUhdP+yAQt7i-L-abY0g7am|IITM?&V z+Y*B}jf>c={uNHz#76v91XGG`5B1h%E!OWoHeVCdro$q{Qsg&fd+1{%=mjolw}&s# zVAjPL7vG^8jqShw+y!LXyQqCZ{i5vF7A+}su>2^YQQ3FKCwUb$oyDTgQauySzRK$K zQge7w+npJ_HeFH5+Pf1JSJywIbQ^PIiJ?538U?OtrZgUW&IsPWzyEH7^1xMReomd^ zPRUE>V)yTSMV<wuxkt#mwbd@R(CcKXAXw>+guSa&r3<n6Oc1yPwt4G3$RcbuqBpIN zF~A1_Od7xi@1Ubgc)GV#+MZN*F;WArYT&)j??#D8Ay!ym$vVJA-B1wEjvzx(;&YT5 zj7mG%F1z&DE;LU<@Pi-m+TguYW1IcBa_G~8rB_;K@<#8aGmMKEpZ_gAQFtP;e?kH8 z5Jj}?O>AgE17vHCq*67-{SqUsJ^$bWqT-Rd+mcMcUs3k01IDiu>Ti#Zy>83DOS8g1 zMyqj8VrDL4h}p|8uT7+<uxpJlyD3oiIAz?f55As9hx5!5H``zPxeuo-*TPPWk9a=O z=tPIZYc70On#lx_Uz^Em@i6FpO>Lh5)*<QoL4mzcop3q!V5;#DDy~Kb&fm)uS+RkG z={@>SiL6O1um>7-Hsw~luX3C0ii#+I<`8(?_+1Q)lQ=Uc7=A<TO&S%tjVZdU>mJnf zjoZK9*t?(Yxf&H~@wxpE0eIDEQgr|Fug<?$H}7G`=~@3)FLmzK_rvPddz-FEzh5T1 zC&<%DS?XinYuq}`$+VX+_1NIUX_@W?3NCc)&7HC>%Se7;CbMe<Oi^kwmWPCCiL7fF z8YApBgjIZP%JItBRiTmskaDyvMAgdP#q{+2Dcme8Eo3l1n!X&PxR>K|Bv+QqMvKG+ z_M~YK9vE@+3Y&k8nq;lBc6?GUnFV3qbj`*ZxX&o`Rj!ak1SFVDY$Iv_gUmi5;rA>m z5Z#<tes;(L%L?%@p>#CUsYyPqNS5_mc%sgz5GdTD%P}uih@pnHds|rlP@^0E!u3vw zND~1#pC|~+^*@S!;G=+(a;6!?m@ls}o|5o<K4tkhxsmHZDvKq~2RARr)nVt9-=gdx z!h)!s#s0FVEkcCToLV(blJ8O?moPaE(qvz~MWY44P9=?X%kRw_Xhwx@p~Lo{{ea68 zp_G%QD=buQ&pq2~i9er}m_2c%O2m{*Uut9mu2_r6c5xmTuyC~SX_!;b)Fmylu(Iuq zNx@qD&1+G=@st%Fes6%!fx_VG^sS`DZ4|;9iVnC+11445YzLeGSwYKnE5VZ=P79x@ zO!!Ea>NVPJ$4Y`6b$)BUx#_9ovb#T@Q@Uzv?#aVA!6^BxEsxU${m!8A_pBkyQbAHP zJ&oN$W00{lY2Jwh8{ll<k&&01&w9t-3_3xFR(bC>1_)w?BK0@=x=dlNDmx+c6>0~h zRBP;OKfcHE7>e!<D*0-^Me@!AmHnqA{4#IHMgY0Ob!k55H)$AwQ9&Wb(r&PH!b5^D zHdPz%V<#Xo{;Vit<sbhdP?RxYp>@!AneV0jt{2JMnmrL6b;!*xeA8l9j%SGApLc)z zrE}C`_RQ)v`ougxgwGJpFRszHQT0-sNk@6jovqlSuWF7{*Q-W^`i?Y;!o4^sc~;73 zJ+~k_F&sWz==$}xNM75T5cdK7`2f{uQblqmXi;J-o2t#{Z;Q#E!^bcHg9JG2iZs`4 zS&=IOAUh-)r;_;aY0_@YDgE+&)T1o`9)5^GMDViAFe4FD>t6`#*3Qg84o29oA#MT8 z#vEyF6XKs4m|^d$hP{K#DbZJqlSl1T8ln>o1UIL*BEU5V3wf<8bMq!8a!zWX2})?p zZv%q*TekEX*ASKJK`2Z4UgzY3>xCIEkFE#T{On1X-9&UB+*kd%ys8x~!v4gqi#*9P z{x42yy7-tg_P*hsdL;DzQ8CW!z0idD_J`|xmA^g=6M(;|5yH>=`L=OwWPs`y?Utid zxK^g*V@1)=d1MbY>bAp;PIx}On)RlFG)O8S?F&Vc+?4<~h>>awF8JVO(BgQtY<3MY z7B09jNM9pFmtDe6&d2tn0ki|?2i19LUo*b-=)qi0=$8<0@t=(uT)e`@TX>q>;$00T zvCFcks3#xkRc%Z3MJq3YHC2QsG2bJV-4S9$XPQ!#hNbBV`bxo?Kd8RpY-7cpyN&ix zJZ%%wMlqmT3X4trt^}8b9H~8akzWjhISn8#xdA;BJaZV5E-U`jfx{Zqb4oT2dvhX< z!<8tzK*wI?=_hvN>=s5?FHY6*41Om{#iWjh{bYf7Q%TCm#r)D$@+tTF<K#EoU<7XL zkV3}nVhcvbOncIuR1u_WrSD*05>rs)M6|&3N~AuEd;F|naHOobdHH3@L9=;=yFBPh zzbUh|ZJdJ3gQ%o1u|Ch!YTkp7Lto5+Q)RaN(ywRHy$_JF%b8i3@rFW9h?gYpP(+h& zCMVa>##H8R5V>nYh0r&&hp>dk0;k>GhY5}1A9G%%l*sa)H641}&8NfJtI{3q<BYoj zP_5->L2gCRvdxFc&#$E{n-gp-<_vzdA@mBv!!_YciecMPd}nl0(<h`60AVI$So3lc zFgFW{G-9r1S<923&zk8IyP|d0=k|gv)}Rz5db{Q00m<aG{`<}ATA`w-kk{6hc1%!0 zc{VCK>0jC1jAvZv9FZdP>eOu69@g%l5?SH5HqEfJ%*J(OiRVi_<dp}jWm;9MqtN=G zvxVJcXvFh5<55|vy^#q?mx1(-cYepwhC-G55#d6rzn|shGhSX%B+CDFOf%h4)hY7! z-Na-wqJ}BAj`35$X>g0reC+#V8cRe$+ph6j0J%9QO{7#01Qr$k@+pVisdk4PgNH3! zlQ3|*q%zMH#bGaVA|3+-l_JV{Dr^3_hkJ&fe08Iel2Gl={16H{zje&=K$Lw<@z(*f z8)jslco{r$g^fyChkGH1MBkVc{Om74X%-OGi5Tdd0W2_l7F6Z;y2QmnfQ9v|@RN~_ zeL3D>6wBIAgB;!}X+$uO_fU|Mm$d!$`Zabn{OQB>#eX;@J2LX1`=QkF_fuICCVweS z?j4gl0<W(&U;s`xFHcS5(z7RYUY6w6V+%FECuLa7V_g;2l63m+SgbAKI7=?5#3dD9 z67x4xwrrqznQ=!oC)}189zqptuXih^R3E97;Qk1-1Y{`>$f&;D{qQC1vDfNMLSlT% z@rs6}X4(UJZg1%-4&1o2XqLTB(lpLI7@VW}ohoRCRcX*?PMvd)DZViOjyVR+lj?BD zF9OG3rJ}w{N~YBB!A0%=b53a?7!3myLn$L5mfkWa7Imlpwhm<q%ZbZin#<_4g?qJC z1AaK920lHHi{}@qBx6UMzx5#(uYOYgk9}#ouekSGYcG4SlWR$$2YJ5r)yh3%Ok1r3 zppt4GE3n%fY)CEfjz3<CTRC1>4sGN;y?yF2o4KJ5ISC@?nZy(uIE3e?u1PikR)6mz zom>z|bEPq-l^Gc*BhAb2AE9+r?uR(EZjCsq%uftx)=#<|qSKfFGrI-@dHpLm1j4r@ z6!4C)F0Uw6qu16%aQA%WMV+oY2XQRWcWNCnEfv5sXfOh$^G&`SjdHnt0ED-0<A)Pj zn&_=2s)2og*L&mvXt>;S)*3Ui!*=l{h`_d2iYbRghMl`LnaJtAZ%V>_Qbt7%=Hm%Q z1bIJby^F<ChNX-$z*LV>mVL4FA{LO*GsyG8_NB(Ylh<5`dX<c|YC;0XQ&Zp>rH$K8 zZ{po;dZ)g&tmHgnZhb8DSg^BDia?gj6I63|0UO5)=^oY9{y;@xp!R~_Sj>R~9vmnv zxHUFRwY`KlIWWH%ibjnas!8l^rL+5&MH!R-iA1BJPJ92*mvH0$$cDo@h0ca2iAr8D z9(1BufR!5+*a8HRk^Ppd7j98sLZk+Y^EOvt0}1gD2<-^#i^!k(b$%!3<uw4Bu4Dr# z9pm!-rE;T_TVSiUXTZ@Fq2*FYTn5R8cQ&io0JXCJF@mFcOuK&2FyR3fniR}>7pb#< zqW%rY6%hkTqZpuZ8K7ty)3($v^%i&LtR4b{C&iTZ2_Wk2D-;;cH>eAZ=8{X}50@V) zWlykwM1J;WI-jqlH(-=97D!P-)HDo1_ZWQ;hU<BTDHgt+vZFMj{eX34>ehc*Eq`Ir zVaqX)pgW|Z!EmHQ*s=b<z|pLL;;!+$2ojU~4USJ3{~A{ADdKO)&k2VBpgEJ5B>Q}z zM-+o+%cx(PJS{!EhrUXOork7U7u=~)XSRF$wWXlSVP%*qC56&$z+*N&PYa-VDJYFh zv1A`OnGoiMP>KpPXN^CQls9(7yph<7U{y>kq|-mQh<t2%u2>dorEO@#>V<XV2hZf4 zXn4cN>6QmmRvZ-;HzRmhG;XrM&v}aZgxiMFYp4GH#`r>xlKrvxnwyv5B28L;*+f6H zYr(<YD^#hh(vXBVHJa4vtm8CVqbrSsjMn3F)H`-1r^}&%q{Q^>i$E?q(^SY=#(L%K zGx$aaXB0K6GeObQ+C5Z)=3@BHctl)0yUKwtHfwY>XL_Xsc2gg#|F(oG<CZowx$ZFr zFTGYn8qIuH208B}CLI?ynmkb~reH3%UTJ|5xCZBvNYN~ej@b+*Wa!-uKF3y0Ik0Hk z%9#SOI|4mWpD#7+%k#28N5$N0non}`vRyCW{T%i+$x_NDf+B;79=~j+S=4tD8xCDJ z7}@Upt#&M?t&ubPVa&#sP=qZv`V;Q$Ii=#DH!YZgKV$siLzlWYV%W@IDMWVmLbMQ0 zqY2wT9J$cJW6WB_4Sx3Ka>o+-F%HEow$ms_ztFm0AZ(I#Jn3#p0HQ->J{Cl67Q0>k zu3_pB@lqR$k0J#-kM7bbQn~X_iIMrVL|Bd3gv$K&n|X7t8!-zFZY9_|0`Rgk>R*H> z&{4jK89Fp#Ce4VH;S9x>d`Hf|Z9P1m=zQ(u>W!A2rdsRrz`gzJjSZ0!zQ<kiMOfAX z@!>X}$Y|n@B?}d8idLq8zMro6yU>?CKbJyI&<_`Fxj<j8Vloe|vIHZ-nCC0Wjd6m; zfB%BMU<t3eUftUvfk`@J#Dd%MqXZS_U?M+D_1S}3^llO$XDf`>I=PZs+l9K7Z?@ww zukhK-(2{*e3IT_dh{20JW14HkC3F2g|7y!iV9Ut3i)Pdt4*D=|Iiyx9v%h00X|gbi z)sxt=x#Z|MJ)-OFd1#-P6ZMde*);KqQ@JnaELIYqu3;&c_?$WCcSjv+Tvg9Qq4daI zUuG9u?Aa*=*h`JSA0~31kU_p?ENJaO6Dojs&H~@(Wj!Ag=EQXWcNK)<l%MQdjLj3~ z-N^j6{YW8+W0mVR#saMW%rkSenm>Bi*i$T*XipBdvIm{%>NVqHD2=H4Yad(IQ+9Pu zl9K<9h;b*9m{eh0sB=`Vq|h38^*Q}ilNcf6U7Bck)m8Fzj%8d}5M)8zprXF56#2r{ z`LwB?d~83_sB{Bksy$zGH3G@lw^%_Q|5ByIU~D8hpfdhk@W<QZWrXccSt_(H0V!|9 z%{N=(bvYK5(n>4yR(|$qN2YDy*)Nk4$59O{uFjr)&)Lk=WOorL@{t-eBXR_S2qGp| z|7|kgP862+(a{$sEB+IoC)IYrD?kYhW~vw16S9jJXC4C>d4qa8-Jat(A}|T~1#~`o z-!}!N<G#$go^a1ud781Pv}(NIHb1+pxk6vKMeivOvfCJe8*1C^s<G0*%d-irM3LAd zQ`$CRsqLjDxuiu3t2Ri5C$vR!;&rrg7!EBmPRlQ5afE-HZZ=Cq4*LaqLiqNlHV(@| zB!z);(qP1>%8^h9N`2)%z^ciX4S=c?z(O=kP5>KBoo9=C4-Y@f5h(uKqYSBlBurtH zs+(X3#r}o=YXRbi<GR$Osn{5fK`00%W<8G@DPH2@yo46r*(vF3xOvL~n|gu>kGiY^ znjb(5|J*|fhfJhMPy3{{fo;nnGq9d=tG13D+T4-5v|XF`Qrn@>@HNrId&vCBQo+zN zqkbm*Et*MyR*V#({@eEqTqhp50$B2}(Ez~K@_bqg`k5&!D9KR$$>|$lY%<dD)z}Ds zA@@RJD#r~yvGs9KD*`FRRAYHrLzw}pzzPunB(O&7FS|zki44CnQmbLXLa&wSF8>cm zu|k&pZ^+0f&gMpi_N3thC^_z}X1q_VfFZD0RdB{sF^{MCOTz_4d4;$9I>oU4+lS`r zNdbx;z6%JbZ2m|Oem;&{uNYBrRa@18)YuZ9GVFB9sYg31f^lf?UgGApm^~1CH4l%} zpmv+y=O2R9)DP2MjswAjuukRDnwpwlqb@HhM6DFAEnof{FoVjgm*4MDmDUjDDxtiR zi2Q@SRE4^(e5EZ$t>-2-tYiBJGXiUq<vy@*v1%*^f`J5^-J9CS83JLq@+=)vU+4Wc zymvd~jQm)q0%rg3KEwa#57!U>wV9JF?-wJ!>-I<HRQ4o479!AXLKU5r3+7a3ZB@Pv z(WvWZ8ShK7d<CTF-!vgpQ+NycCTpM+LHK;;jBC#sUhqN)e<kgz0G^VjZ;Gdjj(Z!O z`7Kea>Pd@`6v6IZs-aLwi&$4Dgc)4Z58+Bgx16fB@ED3T7CmckV2Bild;<)oxMQUd zuR$gwGmBf9I&6>2QHoY8**4Sau}mSIf+>eiG>P_wlwi&;d>%l*PF2<nStRu5HGQN< zO9h6A4R2sU93$bIblG5}kW?<DNOJF<+4uM$m1?SY-LAQGLxATuaOya=@CaW^n$cQC zh2K%i6;VyO6Jf-xl4wNC0~#k((8$}el*Sx4W@H$D@s~vXULXIuPWWJ%G$C?8{aw_- zn|UC^lDOk`x;6g%;S|O!kdt&2Kf^XY&F|v$&rIfv&)S4dM$Rc<PRL&H)SGi2TqAbo zAzwlyg+SfHUarM6pVO8oP3iC=UDI_i2#!=L^&~DMj67)@IZ&bT0|NdP;FId8OPs}0 zlL_l&2}&#&xs<vftW~gg#5HJvLmFB&f$^~m(onP^U#-Xf>bQi^&bQqKMyGrRQ!m0k zqPs^7#5)4*{dk50<7$z8Q58S#<rUB^xV=LPbF22I$IHS2`{7n?{*z_ABJHQjZC<8S z%=QQSp1<u-3#Uaa)LwzJg?xk&w_%Pd1TB~R8h-5P1IwvgxS|4%PCUPnB%}~3!<-rO zKmsA*>)Fc|+nv4Cf<0aZOwyYcMvZ8r+F6qYA^o?E*8Oxi$)RREI!dKOPOrX^vt?%5 zC#Q-YZo=v(dE{vRC<%AJAWdT(KXpXKl38u$c1{Hwj3RsES^J0YsPfPbmm<l<X*FtV z+Hf%dg9PyPp44l(pK;-kW=K(a&_2~_D>r23*APLjxv9P9O0Hzt0IgA3w`RETM8chk z7BF-$dcocumQ=-Ct>$}QT~XNeoasn|uQ=aNbgONIn)&O-h~uDUw%p}JUs9XXc(H}d zn@SDt2_}l%Hb!7HlYW~+;dVEAiJHZ>pu{%q?JYOI7!WSzA9sr=k`iG2F7v?X^l`64 z<+L({kln4cHCpXhBn`BKt?qpm2zldRs^ItFIN+TClkv3|*irQtto!*dwG!+cb&i3F z-Gm)(3i?zvZQk|@KWr&XY7`0`bbOvB3TpS7?7rk+^YYK9uiOT8%gp=os9o*mm~_>4 z5~aQx^}OD~QS5DAeqk^ST2-Zbtj-AbrYF9jv>AHhpxHlc`PqdF-oS7n7b~5+YCp*w zgMXe_{hQKvi=WUS<B_CB&Gs*!rWfb+()AffM*K6b0XFXiSK>=>tx;8=;W_ny7H`g* z5liNp`RKs5UTk~|2w3Y0!t^q|DexMYC(jrkcSKFgg(#yn-Wy^l=zcxLy?=SOXBUwJ zKNc_tNptg=-~KhcP6Vn8j?(DD{`4iGuyX?2Bp@09+VEuqI-bL7-poHu;K=p~tt^2G zxWvWWY9+UwP+V@d1t6l@v=-Lx0ATLXEH<N!SgCy6#q@!vPot-mtBo$<mIR^1J@R4d z05Z@T<|v`h3=v{-zIM0iM6@)S;lWfaD`<TIe)&=UDWAm?h-UWV@Xu7db(<rOc6nCF zTcSZ4O=+)^!jF3j?-|?%l?IwFfpa&8w@#s<A{Ot|J9B}79@@#++KBZ`VQmto%wP5Z z*kZmJB5;Adhy;nTs0t7|P%(FJeO8P!J9#^mgnRR_Y;Okl#a{6G#7FL$RAts&)MhmU za#@%kIDyFp%~JfLOW?f!c)?T_YsbL5TUj|_MeR+Ilx0!&P=b&abMq%erJH?9wz*c8 zPnhWldM{550DyKw;QY<~o;`!ax@d>k?79g8ElUcY{=-4YnF@ck5WNxirBvTdXCC?c zLm5&_CO9*EjV<n+^)h-X$$=ApMYemp!Vz*H)zx=Ny8D2$76=Z;f;Nu6gEr^H07l?r z>^G=Y-g)BR-g-8gmgB{+e7Ij)_obTBu15o85@)S!eT4KHM0kS*a?6oUf#RX~=IYB< zph<;sHB1PIXNG*zYevEh+00W74Y=k8c<K!2Q<o)EIsOt}9naGqKxX(RkJkE8?qp6s zM;+F{FhrN%%Z19{$an5vo{}SMn?G($`@Rw|Z`~@jA|Ij_+Mke#k`=K3nDd5E_nHd7 zx!wWvC+dUip9O{_Vg<;6i-zqSc^gBRyH!b9l%-HU8%%Bv2xU-RodiD@qo0IC22&rA zj}p%109FR@tk*3qR+cQlyLZ6Ux;b*7d+mo<uiPyOAs5W~qYyCbeD&X^+7G)YxOGQT zXb}K!6lSQFJ}eV?pm8i>AU9f0OvBKp*BkGckZqgQOwBb#oH`JdmL2QcFYsJWtGmq7 z_HVXV-x6-hEfBg3s-A;F5Q$An42DpoOCs3nH%6Se<se&CIx00o(8E5F`r29GO!5DW z?f~87mUrh>SguvL4Uoa8NsCFHNH{$1zDe~rC&8|1@sX&^|Ir{{Xhc|%tl!B&bmkV+ zuPO^?ZgV4i)~*s3;mU($V?Dlvrw*|<-BYl(&T7=|CGwTKcqtvyVjWj%RfoRfv>2}I zcn~S@T&$uBK-z$~4)R>{@`9DKNjzX`f0g3XUqvu+g&qS-G$myJR?(T7Q=)qnK>A&+ zPL8+)xS4@J2)N!}a)sd*B`oClE~m4N;6-=?5@f^?G@+#&&--NYlP(MvZKtfO%<}O> zY7|z6sjs;@wo8oUMQh2`nPsK9CvbV$y^HHKT}5VyIctS{jq0!%SXY6!IM`?yszjp! zn!L$rFa>b1oZL(eoF?Hya<e?<t}Cseo&&BFxEz>-PrG1`N|Z0~p}%8*TkUJ96;h!z zrU0o~qPP-_7Nn^SOs?DK457&katL7wB#X5z9ix_JhoV~r^{-2ur_#nvsI03N<nny# z7PmVgnzY?THx{V+C$9}tajC5@izt_sc53i2#GVTbR#T-#FuC_O!`1U!43yT~yn*e| zZpv4mr9Xq*f)K|yb`)shk=T|Vnbr!GJOS2j^+n&|3ax;pH>G|In!_Srow#G)!#<C* z60z5GZ^qu14FAa$!ZbYy0agjEk*oaXJ|-6%EgFqz*4DzPL|_qWEgMG$0-GG|uQrFG zaw%9ab@kB$aJL^43$op<S<Wj!JT1+i6v<oUp|3oMJO{dKO7a8HhgGFQMQYhWG+|1) zuP1J(e);)FWTb$-)8f0@I>9qHDM~g6llOa!#b>9;DcVr=29Y|nz^Z+0*D^D*o5&Bn zMMz>93_fni{~_$Hqq1z*wO`5r1yn>(q$Q*q=?)30hZK;K29Z)al#mYT5|DTR=|)Pr zyHhEV?uLD`zA^Ux#@K7F_1_$G`p&^C_kCaIc^tpvxEP7<CYv~h%Q-7V9lnckmlkI4 z#|IMFJ@p7H{SPwVdG*$G&3zQj9Kk*q#UM_@J3=H>eg8hyEuwW_vF_DX-!BvQz0@~u zWLVQW1S%A44dMd(V(__WVj&Ie68#-dQOdE?;r0HGPQl4>SlZb6iju-DHrKxFB)I)& zwG=Kl`{a7Q(*{`*z!Ldy`WfeC6x*-4xQ=Qo-|A{!2RH^6(xpl+G!2la*h?a{)bOk9 z@X+FutznQcF_ukzORtLOl-!3&d)KRC^RAz90z;WL4_Z7Z+Z(3dZ%J+AO<@vs&v)(O z+V~>ap-!u}A<MLJ^TETo*b8Lw$2{DJodYV^ZaOJs;m1h<G!s}+-+pDxB;Nfg)(sRY zc$8JP=Q0;0AFM?)`K^Z6UBk;?W<26nNtU~TLvE5y4`L$IhTG<#bygsJ{Ev<51ggnZ zy&XST2dRaF=H}KuK=<8wnN=t+|2ZPzpIM82u4pUA<2?CNxj{)2V#qteQNC~AG<fuw z2z3^M8!-98Li6d*Z=*G|&)MU?-YXM{TMs{c&B+LO9JdP=nA;3&2b4NHx`HOgj*Fe| z7cwoCu}fa|9rY5di;9Hb{lzwdB~&KMwEl$jMj^2k&wMG5vvma=EdUYdw8NJx5<~Z} zBiUsp`TbfZu!{aj_wo?55t0l4jIF)Dl36_}q05~C5;J3*-?c^<Q0+andAM}f-xP_s z3@gz&zC38g;h`<Ov()huU`UI(g*xKYNJh5>>T97Zr{zIxEV}$;T5YjKrt!4{#BD$t zFtk>Bho@?nzeA0`D;j2Qh*IrYiim@uzHHrIOSHh!j9|QY>C#h6st*AcnSW$wtst@~ zsMbgYBIaZH-=UCu6^QbH&@;aNJOWkIG$!b^1U_4plvt>?Q&HFt!~?(V@mo$kODB<& znm;i1M@8oC-f+{ra5F9sinzhg$(L;0HRR=gw08@hACn2Rlv$~~U50bvoKQo+PU|fD zs?2CyCw1R1eDBpb*F&AzdK(H<H9&A%Z|&-0<_5l>^-DByeFZ?l$@}lz^UcEROp}<( zZ>8=T&#lD|ra)g|+IN*{(8$){M5oZtB|ApGF;Z4=oqjJkd2HK5#MJ#L)Yu58yD1Eg z*6p`0jXpE&d-+dOxMPlKg<xjx<r+Djt$dE_{#ndYgOn3S^MZJGoK-S7c#35_uXO0u zPP*3zFJ7#4=7TZyU-241>;drf+}jtdR&aF4pT@K{q5FnOXe8!BYAbmiNjogkGe5K( zyim-Jrdx*JactZS=1qv5p|-5_+=y>aC$(M3T=(W6c}i{>GZ+6KFaWscQ$+CeFC`o? z#*UUh8%mrAvH1O?VGst&X%H8T7#JtvTV`vrm_wx=LMMa2ICy~RFK-eqGnlc3mkxqU z6l}<X(o35O#;u)4U$XJ+(FY~dWXnq1v@}nu)g7ZO1-uv}B_vNh1LOI)$t4dcg^f2_ zBG4;4)xIJn0qy|-oqC_}*<ZTQ8!-G;R<B4LwrA*c_3BMZA!NAd?<~<Gx_%^tWeIfl zCCH)$xKAG2E2)^DB**RMJrHJc=u%WK9Z;ri`}KwA5QvD@BY2&@@NBa$Vbe|c<CWmG zTUK;jL_AsGqd7=pMO~8;;uQ()i<jjx<1UphP?cWZ<l`1ltq#DaeKd`mU?GSsK#I2Z z5&*rj&E^uuIPUn1S2NZx%x<j}UdyW87aS{&Z7wGZnCCxSQ%Fb0@`m>K`#IH|W~-i4 zdwrGTfyWOV2nQ9CnXta8E(~2GZgz!{ff&agribUQCz85%<};JR=-X6ko_#wmtTe&< zZg4aktZ|G=hwmHG;{~Iuv)P*pMMg>;B~w<iP|^(R2bLcyO@SC>ugS=|G5C6^W6*K4 zFKUZ6;{M4n(}1}4S9CN#`{08z%ZFQ{UV-t{BjdpvvqdN<SNku;MG)4mxakzC-H@|W z?{UiM;)IV!{><trNnC*Tm$<bwNy@QHuG^L9Ftg%050mpvAlDF8=fg}Vap%!TB~rFa zu!mHU7GYAYXjzUfxGksYZ{F-qLdd!_D-L4_zGFTS*+bw6)81;BJX)L==aRxhe#!{3 zMbR@jJjUQ)UmBn*zI!o5Vj&JTl#fhJ`I}*a=^9q@TGEG|N%=kWH8QGy40Mf=H=WnI zR7Q3b)!`vNF0C`jwh*++KOQ-CDvo$dv~S9SYagt@_gzc}wk5plFi$wr^d9?I`i?2n zdb}AMJ87*(mqRJ6Kz+p-mhrwM>J#zoHE#_Lg9b^gGr#*LVlWf9hjAfpXhh&VKDRu< z32ykyrix>Nc^Okpt`aiV^O&pgZ>}ZdR!0w5b*o9_yCUui$%n7DW@3rBB{Bm3ik3lg z17|g?F%E{`!qQ<zoTf4zSmosZ4rGog=n}L5MKYq@?)K33YXD84W8B?Kke2N5;G?5? z;_kiBgE{`1A9QL#bEY2%4-bJibIKR*{}&+@wiT-w5ZQ*2zaagPL{zdX04n4$iE0?# z5Q7&EYQ}{M<I33yB`DWb6UDeZa9rTtsIX3~%NGtfD&}!0J(qiLHz~s*bI5A9^a5jo zRzNg|`U&fZ0rl%Ij<A^U*)G9+&TZWZ^B4x!jKNM;yn&x^Q95?{HoCj|2`DTd4Pvxo zv8_rW?WoNs{C?;aq+ywdGFO<s8hk2K!D4jzEVX7y)H&1_hO|L@Zg63KTHTn_0H1*A z4&Q$Ob{|l2Z+y0*jfE7}t`rPcIIJ<wuS+rlG$)hsg-xJ}L`)J7yUO<N&{2+oW6l|4 z)Ot{L>E3ZOlT$n+C=_-j`j$A5f|<;>K{`%I^vI(PDXa&;5&6`hm+LEoSc+AcKsVQu zAS_GKmq;z9AH&JBXZKmL6a~3ob9lk`{|5!>qoc1fjxGf5Wc@mvG-Q8Sk4-V`&mwq@ zIR<u<&ZFsT3}U(X-;|j=>;(6B8W$Wa>8TvN5*qaoNJ_>v$2f|~slAh1&Y&(1ys?0B zcG{u%bPXLQ5#sM@jw>0n6^b~4CaY%*(_zR70BAwE4S4(rnZy*4`a}s%7JuG}1o@l- zVslg{$s0G#YS>h8!~ltcRFkoz)SEHFr2%mu1wbiqza%?L(8}8sEz7D!obX^wpJXfG zw_;5^NSc7LgsNbM2Y#*P5qBI@o9Wts-TmO+ouEc`IC*56{*trM<z}_<N=w6Nhj!xk z6_MQb@u!4lUUgCpF4k`o9KX>s0Cm7pEpt@yR4x0hm>Oww&><D;h!80*76Ms!)GHr> zudDKXWkc1DsjPWfIFsLv(YI8|i(n$rWWsw7<3$W+VHdfNfM4mIyWdosa~h^`ou+!* zAFv3jMN}v;{1(XxD(_60UwRgIh7Ojf-xNl8TZabI*YuFXeUhWUzF96cimz}4O`YH( z9p(Bw{xc1mu@JK~#D@wcE>D`}2B*_xhr+wTDEhfZ=p*TxSuScwe`N#nTMt#c7w0iW z$jpbqMP47;G{<YsssCWeb?vbj)aClOK|=2n(GEpSl4<0><hE78C#zT)6zr6JXM&Hr zZNtPbr<DEH?e!>Bn5;TFd;h1i@2V<P`Ja?vNL78k(8X4$(B&}(7G(fDd*5N?h3{Wo z<P6pAXObf?P=nlP{b^Y#4O@RCK-L&09%AQ*lS$pfaTBSSaDG)yuyFDL6ohOKJP-HE z*E}I1nrq6ezoJMe!9jCq%S4l|Zy+#q#Q$FH@Xcb<^kaBW#}M;hm+HoQVE4mlVQmCT ziH|v~bnNuLy2Olew#SHqi7`%?qPVO+VvTneb*lW0zD+||bU+2;Skrk3#l^(rk&Tig zV`#&KR7<=6K{>8+g66+yt_?Y+^Z8Ou)2OC-9&RG=3LMIpo6eKrDaF1)-Wjqyd6W@9 zO7OK>{!z~N7%oMrW!OX!Nbir=Qf5(X#Ht0#KA!N@F-d|Vn>1%NN&;faB8qRK=~>|R z;I-JRTedR&V&ZdBJjh&ni1|33&NBR{hG#<0sQn$HexS6g$|`U!u2$uwXW%HC{oEE~ zMV|>XacqpV{1RBq?u^l<c0=o~oltY;8bH>7Yr(UY<@iPPkeV6RkM@D)q0HshqskA4 z@VGy#yt)1Cb@=lS-litT^wDMrqt2b0fHBZmx~+%yp7jwoaE;sueEg3#3Z;n`^~bEb zoH)u4G#QCy_ja<0Liqca>QPkJ9`EUBa2tEY+HP!(51yM`b#y7hR4P!x_oMGq&qDv& z+B+HiE7kf0SOBrU8QG0hmBnM&S_w5fvrEFEz57x6tU~IZ#x11GBRj6dpm}X4OJ4i; zQ?HKGsvdT+>L=9YdwiEUY7BjK>mJx?V+S1#mg$xW(W_2%r4~1<CGSu8dMk5-ev6v4 zF4Hy|_;^zp+dg#~b8yqOQG=8P12}B1hm{yJR>dz9Oe<N4PIL6X-v}TPO`gRA9{oW- zLWyjC@JL|`J`^wwQfQ`IO_~ah2FBzp<tHW18iLRc;|4E~Nckw09JawE!AoM!xCb35 zQDc*ZvbPwGuC$U9lq<Ri9VS(JRuuuHhjoowl5W;dYgU0km#&Mz9mW5>)~$(BEAOb& zcXkbbo_|H~93dd|3_r6%cYx1Ui4D5w<d5W7fiqgq!&do@sPuw_A=D6RE#FgNBoXRv zN7#&?HeBJkJ4elHcpx<LpQg;KDutk(>o@J^PkwmQKs)8#c%+5DZK_*ga@QUk%e~gA zmFcmRmIN2l)^6<%kYHh!RiI+~{6R3@>8BnV&Jj+?QCQI}mk6DTyu&Size9z19j}IW zLz{$g<Q_gbsHUPBPkQ*cqi0$%@JY`7{nHTG0D6{U!P)IweX~JILKr4064jjZna?C= zirbouuZurnxQC47qxl|%p?s&>9%fP~t2S|Lqu!6LA$RzCsv1MK{F-|~o=+^deaKQo zp<{v3p$pP=`rP~Wk(NUN%AD|ddN{e`<kA5j#=hR6-c*!jv2M*%LBCkkZ-{4-Ee*q9 zA;OL!E2NiA@2oYim@u!DiFSYdW09p_HB33J#wiU3khbyDuo-%#>4N+^<Ks;aA0OPm zh$cG4e52J{Z~}hO*%5K?>pU8CH|-_ZkU*P?8gIrd2A<W0Ti*aj?tmnNf~4mTAHkGr z$3ee%S2|HKj(}Y8^iz196gX?$bOOnxjF!%Z8wWH0%~C(Xn%QM@`Id#jMNh?9`!1dx zL{ljtqwn;fdjG6ypzG^z7kU@@{)ytEjNWoOY1$Xpfn+-~?!`{_0b953p)$G2vl-t9 zKNeG_N<C^0-CDK&nZH>+0uyf<+iC2TnYZv_*%mk($-)ywj;F^S+}B_@;G;5}({Nd$ z72hW#s}-}D(taEQP8_jtbCWlm1PpGZpT@J^%`jNK#X`}hYN*3R>-=Zx6wTa%IHV#c z&W@$h;AZD@%^8o1*F>(=_NuLmdWp?jB;`-Y@nCKAH<xa`&SX?#jU}B9D`SQrC~RCD z1B%odRXDa96e@xO3TQMhUsr9Jgj$L@@oH~pCKX}t>N-p}GL{WH(tiuFt!0?@^dZ`& zNLXOeSc-d=>qKe`Q)T%5+^Vc6?o1wC!hs?`U)|$ZXVk(h6+j#CAu7b>dBTIj!ooS# zf1QD{Q$Y)0FKNkXu;TODuY0JNwKW6xo~LS&Ow(>$9lpY!-%UKl@Xk=4OlLJC;sTdK zD|vhgQ?6p*kCH7JC7mN?KWV{Loi*XVcpX~sG@|bQr5<_5J-~)5#vi|C*-~QJNWM5- zi3x}?gKAZQSSY`hxKI&2sH$Z#PyX_8Q!CuN)JV7-x#B`?{$JHlTpm!2<=!boX8_4f z#KH=$Me8&AjcMzaUqg(7<~gxSInh}Yy9fm>pCHjPxu9`<;AnUQFb|yUIwoUG(a7mC zF+1T}xaLIl4NW#2_Uld*hfH}6{_24al&MoNeO{4SEXWELFl(H-d)q{p#q^AUB39q< zLCJ2V^_VuSLauxQoL618T>H~_bw`Jsgaf4^73{Mxc7-W_F~$ZP0xU~3A}xvD^+Sv} zFt@~X0<BEUWk!^9d_`qP{&uh13@GM2%0-i4n+-u(9KfwSz(bRnzZVYM>P<7|T?lxD z-k_fo^7{6n=OF>MLN^`i1LR-JbU_i}+;b$;VPi1sN86>3;e8X-!tVOqiBm9u{&ZkR zJ2ld>2G8t%!eBP+;~>0@#Swl+?ST;0U%z9cuf+7yQ>M3-zOWK3X~Cxfh))PZMbjAu zA{-c41XgB)i`u!eWkz~g>55D5Pf0cnZ=U$<a`qMTK>XmIEre&mf|C`Rho5fO4U&kD z+t5+s>7=7<0r%bw`?5-iA8Ku%vvR|R5Mqg73_~Ra8x>#n+sT6ir9BCk_me&RYVDGX zChjB2cuGI5O!!MFA-%PK>SB-9N9kns(^4xy^)?9oz1^D#?wWl!$>j!c6h8#McCY)` z6m>sxoKCaE)rOK}I!tGB1Exw9SfPBw^IzR_&ug*K^&^29L;BiY<2xbtZ2;HBuob`+ z@vh##)7T(y8vnlKI-tFsg6O-QZKQ4?D9zdLW2-$i(%}q;g4T`v$f|Ro3{=^aQ;cOZ z9X-4U?S%d-4v@6jSh2wom%G&Q2P|-fc=|)6`3nW263yKmS*k}xs>wfMK4BbLH|x+J z#h{2!+#aDDgho$QIqnXom@BJek-g8dHQ`5O_+OBZ+?LL=Hb&~K0XOUJP6lELJ35KE zAEVBcsR+Y~A+@bHP((+nD`Upy?HH`+pzILhi@Yzk!6jcPA}-!{E3dm&Yb)>DF;9)d z`iNkpn^=<(A!aWZ`Io5f-T*pWoQ{m!yUF<4QVUD(6%_ipbi_u-ZU}8qKwhoqnhOw8 z;B<ELO1te#tGi}ZE=}e^NHi+{ir?zbAwn#*CDvWY<)H>qbD<zf`-%Dg;vFt!@sm3X zzCN!%DLeBxBJyypI<-qm*;RjWotlCbN1Lb4er39*h%j6vsM0NGD%gx&nU1(cEirzk zBUAf~B)~uPriA$Y0kfue#vh=MV@H{>3R3`U38KM44xpH^Qtv>}=Gv9aOxhi0YL7_$ zkVleyhAJrmW;T|a?NUb+Ag5a-uAMF?lw7DKAUwuR*sf56D(o9ZwsJG-o3ZeF>kP+= zYhX}Vf%{=+5pHqGY8uak-%7^|f#yUV+HEEF!4b@`C$8R4iUpi7r0R8r3^!bW`Eubl z-n_|wN}j?AAB#8TyVKWSs-6J<2ZRBQ8CtX2Ww1=%RwjSKfUd&M&WE*h{JqW?09}*U zpt0h~B8n$wOVK1-q}TDT^EB)=U@v9}s>O;baLV=I#OO(hCwU%$Yl3KUI=u{Nx2tKO zNcb6Q9UC++{e~MMQtlvN(5}T#ZDk)IPajoAsZxaFW<C8iW&&MdL;3E4eUcF!urVY( z)cX(#zNT6^<x4GHJNgl558w>sHdt8NQYDWRQ2fs2K<o@T`VRp$L+-hRwaHerikQpw zRwhU~EiN_OHxr)rrtz_mR+vb;D{#7cs_91}UUa%>A`teRmB_F9L3`Hgpa54z|FTov z%XY8;0iaIJupUbFk^EN19N9tJQe#K6y$LT{{73KB6fSjOAd7IQ+-CZlgSH5^YzDr4 z$@|n$EXU(s{xRko*<A+-;VzN_ok11(V#hmAeeG)AZu;GI=z-T8M``|yZl9-uD1RdW znt{Fs07RkC<>kYrQv={c?qMRxb3^1_Tw1MKIW2R2B(H>zOtarWx?%!LesKWXES*R7 z)zwHX^NWhtqjh~IJsF4~3$LQM-JouAs}SeS=~!S&i|KP{`D&oUMEpI-Wdr>}qgYZs z&FfWGG@#?ela17B{j0eWz3@K9pW@6svxu2Z0R<PY#=zLI*zC!OnXJ9>2iN+KZE+J= zxBK3`P3JZW8Z`d*BcV{n;SUUF6yOdesNpcdzARhw+oY3-Y5h?;g+d8cyl~|Dlpn(H z654A-+Ekslkm-bfL){zr8&9()*ia35v<tDRwx++zIoXaRuWz`~jvupWPAcOwQkNmb zNf}>zGEdzh!Rr<>-f$TnU^@?Z>z+4NSFT(;vsA(K9|Fi({2u3#9?2dX>R0zKgWp`e zabF0%S}QnjI!CHs#T0lTuY--yoyB-F{d@GDDRCL5+DsKIIH+g=!2}H_<w->cyMc!^ z69II~mD$&8a%61|o*ubsLvkGPSR6t`cM2bv*#gAY9@v|ZC$#1U1BrglWb@`?bw<cz ztbPoblYq}RGDv;S%0S?L-PD6e?>k)MD3f~QL3eGecANZAI1dYFO@So|*Kzj5F^P;s zeC&O^rx2Y|?FQAv#<VVBPMLN>3D%t<JE}*UpJH@0CqDN8cAXl=j*?*x68P#)fR$4+ z7yGShYT2lC@WQ1@kD&~!Pj!oR@D{x9_|1bg#Re%)C?FfYQ)}edX$N&F*S#fJ=L7-F zCsn)HDWmFe?I9lrC~-96^2pc!^kDFNd&aKem}+F;=sK&-awOJ^N7fnT`G>uPY78x? z9<=v&ZID9si|tA_yKK*xVd216b9xvKuv7^j%%5~d+LL7(-E=nKvT;oHFAM~4E4|kr zrKuUoc(W%|dH;iT_cZRHWWHe(+2to9JAWP!$IQ3^a=FEw`Eq+*Lt%rJrfVbvYY|R{ zms3B1NGR$Yk`xO+lnNy?`%YgP0Jd8x-Xum-7o@V-pmHlCcnX4@AQj`$bJjuCM?b!W z$21aO_M;IFOrr#x@{<e>1BJmiP=nRl-1Lf))$97;TPb#(642Okiumz@orwQQE?SKu z3kzBt<mt~8`=4#Ao3=$-Iuv`o;WUA$uOF>3kbPC8nN9bL@2{otG#YzZ-QcxKI4yOn zR(Op(vZl}*3&vcvBd0qgS6Jr!oUK`jN|I#x3W-Zl!x1wkJ<@@7@U>b$$<dw$8Bhc1 zV#i<^GR=R^AG*6k7;4?+OHI8!e~0a`xh%eP7IFrN5emm_mssewMI05vFOQ^2m6M7P zE3ZI@`qSE>@2zg#O77-C%1LQQmS$=oiDx-U9CgP04UTsMJQ<RUzedOJT;sY;igMqS zt$;iR2=ExEkL_x$`t008Rx9$Oe(6sQ<cp^Gm8BMJOCO_qPKpJ93fx81PmMv(4^7u} z8^*%LJ<o6+_#JYX@trgVE83V-(W-X!b{&-LqEDLgU=%sQhVS{OEMaFQmmo_FlRO7O z?>_&_lBeXgv9VOL-s;+N5U<vRq4m;aR}@&g4-I~jg2_(Z`tEQ?ona$jOz0dnWo9Gt z-DOlWI&O-`uQk=PgTC{{l(XkD|KY-y=Y2GLSKDhI`@y>%=R&8aqz)(1upvM>N0MAF z^zU8QJz3DVzD>?~7dko|2b+-x`0lP>bA~i0iFD3LQ2b&c?a1{I=tDPp$%V-yLW?3E zyAfsD6Q4Z~<dqoK2FUUy7+iT+4=2MjwE93a)1AEH`&9#?2KAHtp7@oCa|{;W>a-9v z1F32X^<>^g6;HZl8rcJAZc!MC0_2lOMp6sqGa2=SiS~&gN`^IHIP-&fsLi{wWi`=Z zhXPBiq(?Y@)xWZZGtq8((O21i<fu_pmg?#}swyOku1mReU+fK@pc;>Qu8{vWw0xLR zHB4Tv2)*Tr%Tg~WOF-03c3rNu#=r=dD916lX(FfE5zt<s+Bb2^*7%3~-Sp!cj5d6h zVNQ5!z=J(0tXzO5t)@NTm&8D!AY8i$)#j$3Blt+{jA7KZgVeD#u6Wq_-n#h_I0*88 z;f<i%f6(0bg|>AWM#uIjLp&K>qrIV!#q`Lni(dK1{{oaN*2Ua&i0g_i9L=(dLnh47 zU&u-phsKZfOkmCv_eezjGtV-Hh{aBGJ|R_&^7E?lP@$vucgE8-eFcF%?Y3N9^OgUr zKj^zYu*vtmO@+2?{AoYkc8-7v05lHrnNRN@M>V;ePyEXu{A{*&czX@wu8HLXdlv)s zpo3(u{PEM>{Yv&FII!fpp}?afYT?r#LDi>S)Rs|oz2ohDW7H~T2u4H7g9fWoxyTXl zLz&Fwy!|1I%H?u+?fgc&dn$*2f#Q^?l(%<u7wtq5PempD<1I=u5sYJwKGccbeRRgt zWrh^r2KzEqjpAmr7L!NMoezRW)ET<p6r?;zL!54kz4yMn7NlCp7YXr?i>n&GpE><L zI}h2#R_)$V5;n_3gU@RAaEKmaQHTCuvg$$P@oX@}!nw?EX8x&43JfM{F&0oWrl&Au z92<e*p38p+LTHJaNRc;wBypgDe~~|0?mTiz?wRmG%b=iC8Q?BM5aNx0*5y4PG|aZ} z%@ia~?59)qS>M0V8Ll*1!m*bp0vZ@_7)75%vuduOT_6<*P7-kgT|iWdH?1tR@LjF8 zADB;*%sBd~&Es0!`*JGx-E>f20ys65sv=yO4qbhV+<=wo8#_X<DxOwRD`V_*?ZkO$ zEA;I6@C(D`%oR`lR!x1w+~M4b*m-UJk<0n{+=bNfL9^(>2I&&%>6$x@$AZTi>3scV zApEh*zRSlLM_2GhoBgLNoSrKLdBC!Vy+?4hTh^tJ42o^6TouMp>%Kz|STg?}#gwxF z_<N^D-{4StobfEIWTzHSZjcVj@?^QcAvTczRPX?B=QW~*DdUFP4FKP6bW&B8$whsA zQ_Wsy+3OT8WP6(j=2s}Z8pJH@zx}ORx;$EjD6nrM0=M`UNmCfLrUDqESv~knPbNC$ z6yHJg87L@9;Bj8nj}uhV)=#GZaj-j1i_GP378U+B)47+fbyzg7>e8E`lakjBCl65k z6jrS6_%_5nETniWY5;w*DMZDgx)sm<i`|)*`kehSPH0=?5UO|HO+5#iM7b=_EmV#N zep*aSrhNpuSzl?uWAHb!esrehD{#$12%InueM<39c-sko!XEz{7U`)X@K)@hA?0iJ z+q|VM=A`kjKxG1|z}*wXYxMCUWC^EXe3`scjtn{M%!kgal#zO~9Zr$%UskkL@9_>( z!KW<VMt=x-s^he}7hdF%!ZYtHc5VyWEq%17bm}eB#sl+7aqKwz`B(l;YU8kf(iN$2 z8YRc1_JJRk+{3!M(|)tyQCMuZR4)I~tHW1N8t^Osd6clEM02(<QY+pRrX(A}f3e~8 zG`{xLx47zz5<M>h*TcWeLiHFtTR}Zu)LO9Qfp?km-1?ZT9!LneZZEnG9HDA*k{-I+ z%eRw1pe^9Hp_?TUeE6yjNU`q-3FA2pCF@7ge9IP<#LF0T+He8xqW!6c6Y{P5P+}6D z)f6Hy&!6F^@C1F$?{3S;joUI`?pN8MQv}c%L(1Vgvw^KJwgmsgEw5uK+6p<}L-NI9 zZXzJ3yD!4L@{fs^Udu2ZmMVqY)#zu_LzvEr)(L)H3<>Om_>^|v5VjjPIjVL$5>@x@ zKfSs|6tboI!8&o1ud99i<YboUU#z|=Wbh#AY>AU~)FkKBYF2Q}wNZPs`MgK9%cZK} zN}Gq|T!Sw4zze|qQ$eUp`a(UT|JuFQxf3+DnPdnxvDYjG9!8XHK~!fx4f-N_t7h8m z9^q5E%{PY9s><TC<&cdX19IR{Zm@DkW@eYK^ST#|y#2s#Ead$F7=<fvIoUEWwEg0i zlXZ10M6G7*yeeKWT*|tPOG?agurm!_+6pIadWp4zO(%EsMRj-1DHkoy7GTLiaWSay zySYP0Ou<8Pe9ZXr=hB;twyTP9kK?%&g{!Hn50{H67wX3a=M$mFCYMP!Uu<6;OI_W& z8l5}#_#<@r;ga!kIOW`bH|26`kJ<f6UCWC5>HoyK|4k2tSC-<!c9z;DKiHRU(bDz# za{L1nFkCW?LzOP~1JCc_15^afw8C`4@{{UObZP+f=eedpC(VE^8uaA}K7`mBmu4b( zdib^!Ed6D%NG!B?FJN`LsvuooP7}BdJ4x^jx((uT2vGE_#$14kvE))Zux;}>RtZ)` zlt&70x-u7e_s27wWqzQ=r?YB7G25TW`{0)bVZmApZ4L^ry+K|Z2<^utv=ZxJ+9<)1 zmq0#23y`fbHln+Ue8Qp5h*tv7Fi1S?B{%e9=yZ<AVF19|_y~lKLkZqJZcNLSoT%!F zu#$bZe|le(f`$!&f4;3$bl1&TvizMG0`t)MT6WjU!|LvS6q(~`HA!k^(E1E@;+9a_ zFrz{-75IsoZVoxD0>5%s9A7be)#C=%V7OphlI%h34Ee;l`lXNs`Rk~YUBugj=P`%& z#2=8Y!(<IBZ`~E}*~(Mre_1QiB_E1R8KG7Tz~Ha^#iHfuL%r-O>9a&h2?`lU>yo#{ zB<zs2DZyBQy3@S&up(gFdO|E}jJ~Z!4p^#6zfMbJ=o96!-T26y0(3QS?j||VBG|!l zQS*jt1%4^YW!mE#W-+7R3%KPaH^!g(E9I?T^Zd(63DA70+6_n=kTD=kk`py%SU=9R z>h>gD{Zy)yt2#f8^)2sHM!&(>p?#Cjj2=Rm9yzY#Cm7H!_)z)HjCKTlTlc!Dw`I<u zLnOmXo<f#keDv#Z>xyw;Xgm>jW7fs2=c{{&-%3yhJ(v>YY?~6g_R^<j@|dM2@R^ z(15sf&la#nD~QA(iE-K;YC%nt%v<qn7?J;bKP~M`v>Z@UK?6UwcAVTgG)NW2f$z1e zk)T}u*GmA7iL4Nr>>2V+x$SM>DV44}g6gbI)8DS#0Z9(Zrl^gx&R8WKas<`Qh{}U~ zfz;A<79xz3$#GPIZ?RAGk69lA8#iM|Q~dEvF*3i{Js?MGN~4I=4Dg)A9}-~Req(F_ zJvS7fbAnI{2g$r-WvTx8Xiw!4r6jVGR~&gJ@EKS%5YM4DYS7DDlEm=q*v2t?&^~I) zrGO^@yn8pU1}<wLvoM6fcfEar6g^)%sg65c5Ug{vz1bAet<`wW+cb&V<mG+Xw<~q^ zv2pJ7!^HzPVS$sWlN$F`_2cxbL-ZY*^JxXc|Gt^vzhYo_gp8scci_{VJt(=vJMyVI zyXpYXx0*uI%ZJ?D5wh>*(4=cbcNgtpSwM%4olz%P1~&gyK?mX;|FdzYJbb1oL@7yX z+weNAip2Kt`fb`r?qMjVt>nh86UloP2jE-W_KezsW=d21RT}9J`do<#*tHPsy~cp> z%@E>vNW<1a+`rF}yFb!|OM+ugCu2@11xDcGw?jWV)p?{)SXp3!dMmYo7Oa)$Uk$%m zK!~K9>7&67VVNHV#@Tcz+FygGAX?-Qmh-!cbZ`tZiDCP_n8QClEy>g4*FGsSgAo6O zzaOpROqtGa7R!kHugxd?YVGi#iw~`_%9iHii_u%f7&{!{euh2PY`Y-RyqwIfEhNeb zW0i4ex!(d!Bl_?A;wIRnm+i!Vr@=TmReI-6zhsk150w=M2kSzhq+Ge~BzG|FX-+sV zg1Nj<8Ex;HLmsDkF)7(azI>bw^tFnBov_`|tM;J~W1^mpzqRl2(6D}>g}OK6#%B#T zvW>d@Lxlgt5`Z#ZZtK=0(#Yq1K#kxaoj{dHsUU#00L!0d_nE4wP?0Qz#dB)EVL9b= zM}0y?ZDIO~0#D^xse@L_Iz}1gw=X}f`k<TZ;+%NJII_Dbam|u()TZ1h9*5(&bb@yn zpS@<`o*jT5{wyERH>X%Z@D5{8%|%l?!C-mY<gj^@LutJ&m>I9~p|r=((NHb}<ZIu| zU*Or(`L_u6bM}?+#5e}OYTaqLEypi-)rCMNEjWcULK+B8SkbbeQbZHlI;dHqWe8RX ziUOA8Mq62K0WVfRVsWxa=I9k(@U#jB@@Yj^sRzSYhw#|+cbRqB8n1nAf=Sj7#bUgy zE_u8BnNK$8j4&P&I7V{WbPdh^1(8MYcK0Ke=MJk@9AC9??hcFmOWT@cg=9;hR=Ix^ zVyX85SyC)IkeE%UTC?f5SD%0k_RPY)DN;_aP8FCA2`&@k^5bj}(Qa0ge{<Rw(=INU zGR;nFx%b?@tClE<<fur{DZzad;>ZVpNiPh9zG&tzLzNyW3I&q1`@)l2YtmH1Pxq8( ziLCuS`+)?P(8yC#RCC{T>~~@i^4*>MKDm>^A%i46+ldM0U8vvbJGXP)uD?P*Kk%5E zYn(fGxpcqWzaFfY>Y325eAO$|e|~fp52fl$R;Y42z`4S6-^^nD?^Un=6J&uQn)-<_ z{CIw`?CdVcpFL_2iR0Z@xH-=CkTy*il_DjRu~yFMrp!9`iBCPjy+9c~`UhUJCHi=s zL$mtG8_zZ(2C8wPeu#Y(ALo-A`Gl8S-YyjIGDrS~;}N15K+WK@1sL_{#A0(z1f#YL z9s%-9U@S(=XlU0!r$GFJFr=M2RarU4#kl!Z*VhGk%Kq=cz7ztZZ_#odoshJhF2v2S z$}f)<c^@{dC$rZ?b!rJk=*YVPX0~qVMNM5Y`0WdgFib}A*F|VdPx5v#N`>39KPEFa zN66WnPFtI)w7k#P3VJ|mch0k!G|WFHlA{qC^-~Sgb+;ox1(So+!i04Cb_RufDFjUb z2v@6vs$?g&_3!a&d1FyqduDdmNF^iMiDN2wq&_<74;d0YXOg3_`{a09jr%fYzJ1{k z`8FrG3@=pi?llaAV1yNN5P!w^6E#ae=hVJ7v<>G!t+>XEp`zHaZ5*-x)pHwqfS5+A z)W{dg@f&!D(W(SaG5#4M;GvM?fnwV-od@YC-9MOt%%7nXF-28&bIwVX6F$GaR<J?m zCV<RkQk6wM)q3f$;{p`LM1)+`P^0hd%IwE$0)Z@g0DAMF{(P3;v?e>6+6Fneact7% z4?s`cvrV3)g0f&c!&5Cevm$n=?FGn{E<ndRY|Pe(4yqGmX5f1Vf4IAwNpmEmZ%y`) zoJJ+2E(fBxtN}XiKl8`x+JX~6hUi{@#d5rBRM*+)=V^TZ`^|IHL&4MgnrQJ*-`*?# zW%d18_C!l!kdb(9!zZGm9RXlKso7X>Wp<n&nm%%G|B+Dqp2`93E3{#`^KRR0Ne&Mv z`vnyVZgadw`KJ2pn-Kxmi2s(DS0FWUvVWed!ngO6FRZ)~%qFXDojDB|nudr5a^LeI zOK_iIuEi8^9o{b;{-Zm^37hRahEW}q-$CfCxHEK29FLtrnNg6P4}v8%j;-*+?4!F5 zYsYdz2kV9l2P+?{0nhE<tnK>#>G$X0@_=YD7BwfyYKrf4AH^D^n#enSH`|{U%4`Zu z<U0bEC)Yy~YW$6e0s^)z<Qva~D()2TC%csTz~2i@Jo!oYVQuc*EueO9!u2Fv2)#J& zGU=(m>bqDt=j*!?yrii=?>gVTnt%6uoB1OByh~^s`SHAMiRNNj;mv<OR>?qqR?0c( z9)M28TPU_r<1ga~cS>>-;<qE_!A}sQ+%ApDA+1QA59R|M23lv$sqi>ZAR)Qw3#X>t zZ65l$ES$%2uop@oUn9}vM-umpw8{qb5M<)=#O!d1^Do>=1<#kc{?v*siOLlZF-M7y z&hoH=<Rpk0Lp#uj;{u9!Y?A*u7OclZXe4?3MlFK;-2GBo91b!+YBp$5G`XW@<~Mjx z_+`@0@cJu<udux+hCmzN^k+~YCy$`9TafOss3CPn$x?a3+Y&^m5r4^tHpb<NQ;aGl z3JoJ{?7MxQo~;=5Ibj3poK|0-jAoD)?oa_f3r<Q<gjJvXz1wH*hyJPtzgliXA=;)N zLzAai`&-$O810EN1aI!6Pq7YeIx4hM#0)Wx4rq$Jj~hN=WM&NVEWiRT2vXkrNyY<A zHf;MI#V_P=(ME90#Z=r(Qn_?!LC^abHWkzi3i>%3>N^kh3~=@xnxNQ2p6l=ZOH$PJ z`)mZAztd8Kqh%8q`eP%rf=93Aq?omrJVi|5J-{!VaSg!HH?h!i&&#f+MZeNvp%jk} zuFSHY&GhiF#0d&ox56oH=z!=FR$Odnj<IpMa#mm~d1#r8@J8)<I8?a|-g2%E&(U-v zOB?qkVH#l#m7{uOaIa=J#yKTZ4A%?#Y;7pv-6dCbm@8G8G=1fFvlqmUlBG`&l70Gj z?X(oV=H<=5okuKYQtT9bd2Ky^bZDK1dQrgKoefqLZ#7dNmf(51Gw(ah8d+^HLVZUt zz{%nes<@MgK=I=kC=R`0!Cck_u^=vW^4)5I^x&H@^G7>m?c*dbnjvVMQOvLU#sdFj z;+%NyIR+W2s5_fP=<C!B^XCq-`OUk}Hl7h^1?_L)SAa?lj+9&urqHI$Rs?c2?Wx^u zT1XOgd}Yue=zMPlSQfUA`M~Pw8q(J*8v6|aHki;|=j6nMVT^_u6e+`Fd2U}`mRrOH zZB;?n@U9l|T&PR62p%w~IyqBya#ItkVHWhVw<LTsp)HsRrmFbT4rl*jqP4VTC$6?k zx?R92&CLi7R)vF`pd(+?$GupE2-@&j1`U>(1_erSd4Qs;VCboDtKawFI2X7Y7iyln z9J_i@zqNHjb4+@L?GY`sTX2E$E_rA6fU#hfBsT!}r&H}>hl>KM(C-!ZCqw^zJo}P8 zo_R}XDdwurgZXN){?PCE&*iN*SN1U}WHpLlvnnT<VdSZ?(x_h=&Aco_BKU589nOpo zfV>byvwUp#zashp1HV)A8zOr;d;$}GQhV$7?Ciby0@^{BC~H#nCM7VI&wn~(^i6jX z7S){$^Dj!}JXyxflJU%D>C38iy%ZxVz1>Wxg};%?>}j-7mhJ&ORBF?MaMugDLt*Iv zWQfpyh(50=MCOcUOCzr<r<k4~@4oU~h2UTM5}j9sehvp{5rao~cO8#0(hLzsGKV^V z368JhZAWgE>|Y>CkP0plKIV_J;s<<4`z3qG7ddXrsd&CrErvE>yoM)#wbr#}u<T{e z!qslzuo8^_3H)5ztXp<H=ChUX1?@6Sd(s(kV9EqEW>pnK_X@_NsE$z#=&=JHfaxJv z^#Ji0&}CT-Q!?mOdJ#IwaM5MpsGBDU&{=Ie-&Mx1Jt*e1h+2^^j)|#DAqz%n;MEAi zqCtWGiuZNuJ;D)5xUeHsm+ONn+uM>-O1gP@hVdu@%EFLnPu^NVus?IrKw0jzR>m*T zR+myNJ+SSc?+wQM8|hXfKVON!W|A4%6I8W0D<BJr+Oivyaj+!9cAJroDvJ=9<C+{A z{Wp08bLmq^O6@^AWfm?eY?>9;zY4e&$cSwT;{#HW<DVmLaZBbloSmREiNG5l-gH~P zfd=5MQUM%RAukmtOFT)*_1yx|jwpgIHv$=Z?<uGl`Poe}B>7$ll?U#hu$3MeRd=L% zonNiLdaHW|Wl;Z4l%o!m4oxWr=;z{=whI`l&NEmEzY`6;Q<GXi1g%+}`I=RNF>15w zuxbF^9N)d;X@Gy4^<zxCN(FnTd;Krc7lLhPE!gli74u%%v%j$Xw4NQkItj5Vr|_N( zk{9tq3-uq;5n?|;xwFD&pXii$Z_QO{3PcEK&JdSGsn=+?)#=hLQ9xl&TdZZ5PI~uQ zMQ0a?p45CoLY{lj{O>xFr~;h?j}rLMRBB8NaL{rvvrczngRD<pg(GM2j(g~ii=tO- zHe}hZuK{u$HlWQyXR6l{$WmmivNiI@KMM;w0qkjby%4kCgY*BO@^ieWiEwpw{oz{i zn%o(W$8T=BUgoU7>ji(_U7%xME!Urt7Nh^Fxgxsi^f<0Le(ipB<KO?VqIP-Q94b#% z5OiyM_wx+@a^J)w!s9aZlJd<Jz0RdaH(c7lP|v{aa$3DS8_a`&q?qwb+*+;xHS(4a zcsSZ+=UNv4059)Jx{EyR2YHo92AEjo6T<60g2xE~Qryp)pbY6V23{8iQ!#=yC+vxC zE}BqY0V>E?Wm^jat~50OnG3zC{Z>E(Vmr)1tw-BRI}{#^_b^VM%2!qqVLj}PhDhJ= zddJrlzXLqzz1H!jtg;0jA57dM%JS5(PFcp~HAQtoe2p{EKTLY?b1?+)4YI?_)fquF zC5f1T>lQR~rreSlvqfJqTV;{ZO9nqkJehAbc#(6HwB@+E)WR{9zfmR>nl^u$_g2{% z!rcl?4~^RQ{tg~mi5JNn^wgH_{Y^`i9@WX@hjb#k4*Q6UU~U22aD;m!f$X5XrnKp_ z&h43a54mxrDfohurqFRHGZXNh$eBj0EEsk+I0TA#zIn>hM`fd!IMTchH||O&#rlYQ z1CLT~Mb!nmam-lvOB)FP>)I_r0S`gdU6Nplq7N1fx+p0TV+#^oG!*zhtvKL<4p=Lp z3<+fA@E)GeP<Cg^YWZ^<Tu=tQuSv0P)i)_D=1hzhCv67&9dhYG$7&3%l&MMcadZ`` zPYw1>&A)MY0(H6)&_u!edM8KV);9zrbTYYTR{jPuT1qG_INroeY$Us(48NU=4gOuB z4JkMQU`nRNtg($>mQaBq27!-9KPakfOED)?rWpG+620<4zxEd<hMPq`L*v)xT*ewK z;_sEhx{5|Mgv}Nq*j_;FDoV^CNC#zS9bePGpgBS_uva&$6tcZ+Vt3vT7*6_{Rtb3| z5jYRe%RHNixR)YN<AFsXb_Vyt#~R|(Y)dC;JZ<Sb+*3mWIvHbq62UL==i}j~0LS7C z_N5bDr>;*#1Cm|8a4}7_9|o4<7_>Y=t2OE~S+$rsd(VqO)@p^%hQ)X==THdb*!ccM z$SuOVUO<>x&m0^5Bf*V>#9`Kx-X2L$mShp<(33j{cF<G>&xDmpmJ5%1h}e0LMLkY5 zFsy*EpyHxV_%?K}BSo)ea%s}aLR$^;Z|z^9$=83H=)3uE7<>Lqe2#dNoATu#h;Xj0 zcGx{<GWrv~uLJM;&R;24-8aRDZd`S3368$9vH8P{@}+P|kDxi*(zwrq^u>A})`>y2 z8`^A}9<l}=+*k8L2OoBtJhll=X6morEf-v!%(d0CT%_!VUT~+R{oOgcG`V`}v8`}f zd%ih$c6O36cNRK$`TL6VYGcdv_>0id5J8zX6D3mR@w~zXQpiU+K<N0^)%@6%b<F?U zr!sf*#L#0sbjQWLZ|mfg6n(qx>X>w8>zwcE)n#+aG2YBo{TM9C|Mlm0@s>j`iiBF{ z_PH<Q&)2R_>w8I$(LLtZQf}(;Cb?gP)~Q~eT+MH#I=;TltzQ7W$z$K+`Wq8fa1~W= zNqu2=*>bg+a(qhq;e=I5=7Q>I`LZ3?of)3+zGdjv|78h(cNtskT=+nsDTaWpklX_= zCe~8>S192>MarlK(Vb9T41Dh{Yxq({1Td4;HNd1=ei`0o^VujqEJxvO*EZV*4i_t> zxC5w~$oK<O<M2aT)f}U!T3KZD&)!i$=*yF+`Uy_plAcfJx^jj4<M`p!G6FlbM0+Cc zp`lOGy$Ky;^cKiA*tM1>d?SLHPr&b(Ei0ynI{ScjAb&m>K8**aN=w2wM{q-Cv@zN7 z26tVX!{OE2t-f?CdE6TQZ708XlY6r!l`A2t84;Z0dSXPDexFN4Zldeovo9RtV5iR; zNv)lf_a=Xq^iKxO{sDDcE5omOt`~YYD}vGGyP}10BF*mJo+|zkfoLM`t6cd_G@E+$ zajrHOA$><*-za>mVpP*%i|1(5u6K5Bwqn$2cID`Gzj#wQ9ye=&T*?RI6%Ij^L<Aw* zz*Au<^=M1&USffT;AQ{hyL=UJB_?N^dB>oG#<+J)N03hGc7VnJzw&FD6qaZrrVSKQ zFD8m%>?5O>>T22vicOQ@oXpSEe=5(V?Zl@}QfzBHlO^J!gp1cBt#P9Yh&A621koDx zNL&5wQbct%^R+kfK{+*-4Ooi$$MuDUKSsC2|6Vb(?C0AxVQ8U8-Wl|YFP;>z&^ohe zxK>$Kn);H>N9%s`c}w(LOUjqA8?W}yr0<U|6k^Vji|Aa-znuZv9A5=R?sIvb(FwOC zPZP^6FEdV6Hvcmty;}RJx2DWnY@El{=srw@@s!S<GsG$n+g-5Ac!NEe1CO^@aQdnt z;jnCjd`F*v!`%wSC$Eat?WTE~qLt0(m6Yc2R{2pA<A-`{uem-J$O$z#lr14255!PW zdn<X-d^wtt_<Sr}n%#87hv0KA{=W0Ckl?iRamk+9=S%$(9s*7oj0ILa>=<L=g{GTZ z8ISv;@THu4rX6ucDpusjJ8x)IC9>DfE3uP@9xjt@A~y?a35M<n>ZZKsj(cx*v&i-Z z!WuVy0GSr9Ep=9jN1t|d({dGWlSXBf$z(-T;vg=Wy-XlqKE<%sV2zEb$CI)wlb-(b z?SA|EzH==%QFXOMD)@h!NekoLl4Gu95%V=~V^Z5;vJ{~v;!O+j-H8>~pnlKnwDMq+ zT172i&)iwgp5^6{LsNiWc8nm;Q^CT4bDX7NeLwEd(ap|fdn4i=b9wxf`Y46icoLJ2 z#8!*a!c<*tH3rL=x6=rmkwqeY3hO7_+FYMZr;Ta(C0ykvKkZ)F{c;vzzT_JS4eh#g zIMOI!*_k}S)jejNjsI{_cD1bHeigU710b2(q{q}{)DVNy;c-B<hu>LS%M?Rzz-qb) zqRC~N<ny6#--TgHitBL`sry-tmSLHE0+-cfso7BG|MeeIRtMOAtJfdZ&$o1_|GW^h zy2LhFQ+{=@i<0j@uZ-DOwkj3aW5XTCRwjU@*|s72F>G4#^r3tq+Z|2Hh1t27MTHk? zs6jHn(|cAvN;$ryU>KE6#Qi3Br%On?w!K2=;={=uh5CSc=gXy^TFH{=9Qw4M;&|X! z&^@pBc~mztP*1|_ci6AJqFpZKN-=rk)d%puD9ZD23OL^<+pzfbPA+9IYx<?A&x$5n zRtO(bWvU5oF`qOmzaPXQI3Gwbn2Y}X{=ncr$+JTQbB9l3nnq3HSUeuds8k}im<%b` zQ-{3Pvio=a0w%eSUPYQVZjzf&-_1~{^gj}#dm>YC-zHmg^cPzgs%5?<imb{MA7O#) zYa6LPX&;`3a5)Z*XIdC*dz1TBEMoa`Lc?GGab_qScbsyGl`XttGbGOas$TwW2ldIr z;$`syvR?~>RC$(OBD<Bzdf~U|OT!#WUyltG;!nRaM&Y*%iJP#Vet|ue60u$RYB(Md ztGD-3mfX84zC+KLWECGb!h$YEvHEivHp;Y9V{ewF+pq4=jFWncFGCh)&EIU&ilg*t zX<%uRqNIq~Slu#WBdj`;*CReM$u(WWS&TNU{o}L#fVhI+&s=utK_2eW+i{&9^u!N0 z6uL3IOstxiR)SY|oZY%3jf2D#+Y1dR)Em_V24n+n>zR~ynH9f?9XWGT3e{V(<zh;w zq`PU`_REnl_u%(?tium6?>{4}?#^GnXUBBt`z(f=R9VCu##d^y!}Bz`Ugib7LqEE_ zRf&FUdbfP+2;MNP)wAaNshiUOQC?l`)>LhljB)wdqcZ`|bp&B%InkP%-E5LT)5n&< zN0vIR-Ht`Nil?6~rrMku*A7_YOtWhZ^0=R_;q#96ZPt&<aovCF_vxvCrY&C_-0(j5 zXfe&$+y%ijy#Gp`IkvAzjsJeM&qf$lleD!Hd2JevtfL^p{DV=;ps&pDHRFcRsH4@6 z2+_}C1n<;T{GR>V?OjhatWC4U^ttV)Xl;3=ck2$nx^Y9gv*?m2e#I?Gb1~v0>m!Gu zGWG9isWh^iYi1mFR0RkVes;=;%20s{oxGT*s}6;OIx<q9$MQ2aYzFR1zimS5{&9PO z;_dgNOJiIyi64=g=2rjC>L&#OHf{uwbFtCm`h2}Zt$!b-#U<M79DcKiEJb{L=SmWJ zxANjwApa4wu&QTJ$Hj^e`qK-f`?|@i%a*N*|Lgty|K3=k^j-S73zyf~r|e|R_2+C= zma&seW5%9SM1B|x`OF`*W66{CZtKRQ=2rS?x%61{U_MZgQX4nzke3e~q~T{5yBpAH zp{%b_rMK!cBWwD{c(KBLmtf~s-P+pm)dj9lXb)*!+hKi8*DkKm{H^*E`jc9Z6Yf2! zH)l^~O+$*LjY`uV=ucDz>7M`8{Cpd)Y}t`b>^H5OZT2thL)FHnQ^Nc8vl;Z+ZlX&M zs0Uh|M}wROgDCIb3mT3t!&d#7<?Mt)>T=AXM3irp(n)2+wth$LRompCVP?53#a$GY zA;Y(JA^T6#I?8Mta}IP_0$DimANiPk=R*0ZmV&Y^v3i5VD_97P6v?Qg$y%YKo2#&M zpM!v+fh)9uY~WW>`D3iEFIsh&kya_ljUBRDRN>!`+leh=RH{FRPxc2MYHo0@^xO;1 z*a@iG=>OOvy!k?jev^uO`qi?fcE}Evm&w~ZyhXm_ZD+P=Vm@mcKdM*-NXGE;DZ*Zl zdt0#U8KXB(Zk4GC>J!j=CgD2%>2|<9$h1fpP@yuz_{A4fY<q*GQP`Si(Bjp8L>*na z0FBe6oW?kgsAs_Fc8RgLf=}n%#l_FLcTXi>vo{o>=<uac#OULW;#se_+ltXK*iF6F zzw@YEmilhg5I=kRrwo^8uqw}DOnWdtl2C{`t{ifriQAEw;IW%pO4&$WP;zT7TP<>U zymxUxfi0j(@~!?$RBjxLU;MNov10(cnE~VbMuq4PVZT@_X3!OJB-8cu?^v%=)oLuA zC+|NWrO%fqWfc8!B<^E1?1WK;S1Tfp$8|rNH@;cjSXd!CG2wof=|AWB&VA$p=WtA; zYi+v8{?aCj6}d(mjdO?ij{ypl!Ku~6FF0?S+zBcU<G;+#8#ugYBFe)xuDO@|zLe1+ z@B3_JBGFK~JtlgU;hJ*s@e6;A4Mv|8B{y;MCU<+1+^9QBk+<zw&dLh!ro|<^Y>Lwj z!|M99@4He$A94^t9lxkDCDB|vUN@~D4$n1#adYr0xlh(EW<=o}U+_VP>=b#VFC{S! zJ_b>R9!YLHo<6JY@7jis5^rEAYaLw5(=jDJjyT8s5cynIJ?u6fPHUx}?wD?o9VX@D zy3k~Xs)SzJKVEmJL>X-ggH`#%Qmfe9cy~^Dlw_%$o4Oq}tGAtVLE_MO*Z#I?G$WD9 zj@n$}O;pgZ?^#Dr)(<rIv*>>&&K7%BSvPY3e<v!uvFCUDk{Vs+F7vrk{C@5a%1+B? zYA`pw{v4xEG;E;wusCxUGp5J0rh|j<E!WDgyZ4T7n|Qm8sq<AAi~srC5#X~?=<t|L zO~n~Q_BG5up=+4+N4M&d_dVjb=g%taQxMNAJ{2ba>F{l|z(4Z%*6cp@nAvT6tVOG< z(5iCINxLS92(Mf%g)<%fh1t(#Ip)7z#DT{r5A=BkA&sXNG7^u#P%Ksu^8T*p%SHQJ z`t7H^h_;^lQt+?1fith4Hu{mdvZ(f$=kCkTLUFhCXi!MJ#B7AHr=n54r5j52P`ycz z_)%l_e_k1qTMU}&=_Ux$$51XDB9G7*y)Vjad1PKZZA9t){99m^{nap5@B%|zo4I~R z)#Je!zRfId?F2!-80AyFfQ^mrWQJAo1;@wo!@SlZ(SnVqdWnMOA<`MCxiZ$4EdFqo zQOJ$w294T~TYSA8RYBwIa4hIrsu!&O?3ef_R>H6^g+_ylE<HuMwrMf9$s&D=CgIds zML#EA!&XROg%J{eW8hW?XJ7pNXd9iZ!DjPW8|>gem$?+eReI%_iQJSALpm)+xdIa+ zP&H<U{vX2LIxNa4T=yQ7P66o>5K&@48VQxw0YP$TMnY;x>6DZ%VI-uK9%VqfyF(fQ z=@6+wI)ra|zU$k2pYPiH9RETu8JPE7?|Po+zJK=`Ef>lv2ek%@<Eb|g%LjT^PSa=1 z9gU`xF|!&T#?Hlb+OkWXhl!bd48>&NDNsRr8mY_CxXu}q1=cRj9MYHYn>Xfg+QlA5 zip;<Et8M4xkT%xrPFsvHaOKq>O%Ua2TZri|Y`lj;jETm5NB?0AkJiD&%1wgxTFKyK zgD-K{5XEZ3dF=GZUFfxqlr*x7&%RYrIC=_gg>>aXISHiV!?Z=B-6Z(FCy2`Ej3m<- z(+ueFxBZp<W=zEwGi6auRQec-SR-~XE3Osr=&^R;Zo^%Sknh|w?mpjz3E!bic{}H9 zI_$|_`)WmqhwiuQNphE%Zj=C$+vtRHp#D@E7TT$J(fEdlwbe!>>_n%rRJZ!WER@?j zf}L4I(ou<kL|1vSsdOb7e7dZvo4Q_#wrozUXbWefBI2cl!}7sG2czi&>FOlO>cb$P z-oaL&Y>O83-dN#sodVZ|RjiwIHAPzl-2P`Gn@H(94=2+-W5^($c};3-)azC4V3N`n z=vhJBh>|wS@~d1)G0~_E>9WJ;8TX;4h>^Ba0xp_~<{2)<fIS^0h4U>6EVy!gG!{a0 z4(Y?{2AG-u+SUGN)y%TY6ic!;3qy|8Ze_o!+#GP{U?ww6h#>5GB`%k6Z&G&t*?PvN zS0S+u7i^YjvViV(u9EW2FKoQxb_Hj!>#TsRjppGT+wifa?mAnRmgIhsa%aMgXSyjH zSNR(h*8u@ErBmH#dsaJV*lpIg1?=0Lnd0q`(U7O_G>%duAvVVldkRg0^3SEu6>uv+ zrKn)Rw<WlBth*A6*rBmQ<%GPxT`hky8&r#yw=CKOUABw<w>NkO60~322j2XsA>F_; zewm8_1K$|Ra{5+`()MJyn*IZ6u<6U5e6eUvFgWNvzrDg`tnbX7nh+7z#M7$?3B95I z*nfv9>rccv?eM@mwYlt{b?@KuP_&dEKZ58BcvZ?;uE_B_6pl?uuvKZE#Gm><l4)t+ ztOOlY1|1stbcH6Fq?$YQ@ti-mE}i_eJ&oscl#@;P8_UqRiEb^Xfv5b;<gFUWA9c~f zG6mf7YUq3Lz8H$5Hn35J+N*?cQKsba-Wsu<Y;(@llMtvCx|umnoo2oIbCe`MUm4n7 zS>?`PUYWzm8)gfmU08_7-$BZ7qsUyR5SuPMrDd`ora3DWDfzaO`9I8(Lu6=nnbZr5 zWHfm*qpY03{_fi+EZoMPn#O8}I;hF~9^+P@4zIL*_45#v4=~o<sXitA%z9Uxka7UT zG@|afQ#56Ynd4>}jY}8DQA|CpVY{IbFwV^4pB1^T!PMZ!;72ns(lqC6dBMCX%A&v2 zNH{FK+FGF&Vp-@;I+5~~kD(A*_)bUax2K?4086xXU^}<>Qy$XV!rF(8H|H87e3~Kz zNmpaF;Z?FS%<oh}5%i@8GSPee*t$=lTy$h$JVR1m`v-R%e3~!@bLxm^XUW6^ty#;p zHoJ&B(i@)%(;K_JJADoc=AP5ur7U*0h~b)Up>9+n?w+*#oXeg>R*P<LrP6sAl~P3T z+3AfXjfbIDn)UCj-*|>#^>CudYOQP1Rf~*HWn(C+_Tb2x^cSG>X{_<EZ|v|?T%+b; zGjoNu9oaUtvFp!fBpA4&^(1g%QwZDo1_QkMMo!+Z$eL3AM8n=7f=x25S(yrQP;jTj z0*|n1h6&GMG&sNW7!o_Xf)A`zs7<*~)^`s!MThgIwD-$qYogV43+}dQ_|SZ1s$EeX zrdT*JT>1O@WOChAokVx`|2Jv=dnV6r^lf72XBQ^c7c@-#&(>~6d%kubdb0bggQcZl z@PknZ+i5u4B*~;0g<&zrwy=Y7*P5Z2I-b*Ay*YIUcwLYV?n_?Or_hzEOf8>I@xOmf zhe;NypE{D26Fp|3>v~I7*tbL#foYA@$^-v+^4RS3IPOXc+(qHWJCv~|b3S|ug}<4% z$Sf<G98}}J!1R?1iwG+VhDcZ^ySIIxZ)!&C<?N2aCY`GvQqsn(sg%CNmGH^cGn!>h z#EeYGwUl!6>Q<R;$|;r~MSkfAGRnrNU6*%zAD*528gZ5EiavGVhJs^F(m>6_M)~Be zByZJCYLhSOwIVl%(kXT3GzKk#_Y+fhgyN;FoCE%R(W!N%BW>&Ay&aoMG|>#U%~1Zr zk5(I+=eFHX95#C*BMi(JG?N}_7`n@X#rS!o?WbY4F$0eiH6rx~w3bwKAQVmM3EoIa z{_qeN+IT3Gfde}S%LiWxwRKZBTHHeR&)5wmnsx2$Y|cE0)*F|#e*xwL)(?d=F?ydz zoh<Qh=dPa}M#_!9vF!8`w%EL}Djm1D(Yc+`G?Npua&#Ut%1tlOYtjDb#+p{+=Qm4W z`lvr7dTjF3azm50%FN1#K&rCzc@;D&8`-Xbl$?OsvK8x85>_EN_=X2Q)b7L+wSR-3 zc>`%CmyTIE%79p%hg3X&SOdw>agGSLSaY$T3ny!tCAh_~^yMH(U&NY3-&LS?>8W>n zk%0?LKytL?^aI0CB3S9HRj<EUJD8;6NYUA%g4M`)(_O_=Ij|DA#`<`0XmHXQ*y@S| zYY2V1ZRJh1ojnc{fv6T*z{FdhUh}%4T#`5d(qJ=ZbkAVeSl{LI6heGDFMP|<aeUIm zIiGG@SX=5jirMV12C_Zhr6S*TL@+wO`VEnvj!SXyAc+$)_(vL%JXFs3OH0x%+ms8J z@DtE`WHEnD!tAMDGP+53AeJ|#+2jg21yw^7JCQS8ybktR+Kid7uacU)e35xu7-t4W z^at|rM<QBdD_zH!{qJCt1(PZ95Q)`2X$rg2l?9S;K6fa5%BG?)?kKHk#<@5}+k|uf zgJ-st4GF6_^?dqc%fhNwC3n1Z&ub5hP%y}BYP>tgQ23zr=3rLLn>0EiGbg2wV^D7t zCE|gu!l-^2rnjYawSTPWU>|2UyD@Xj(7Dw(xWUa2NB(aT(EnR3*GcX-@6ZKMn_jp! zXO{X-P5J6N7PQwpHb;m(?)=xpS|e)9{b-%VU3VW*nklF(CTXk`iQR20k5!swWz{ZY zbX_Ax(;ZsGL<d6QUt?p)swTk*%9i0r<Z+D>KRL9pOo)-!#YcC;-r6&pJZrd3xYFu% zIFxv;fr{y8==j^hG^@PGP{>kCnxD2G8GiH<T|xGE{KQ#aYjLwE(qnDd^UEW4l;}y4 z-8<25l~W>=(I&I9c~f(+0#cpA(YfIFGd8=wADCAn&~0HG!K?TTCH%q3x(T-+$a|!Z z(mXE6dS-i>Io^XAP3T8Fk^DWfkAwo;wu2gYu>BW8Qoia%f`_k+omXgtXDzpc+-384 zd4(7t8XWd$Niw%~8GWHiCZ1AGEL1M9Y#!H|YG;*4cHNaJ+Az+HdZ+HSRfka8fa~lM zz}@NX!FCSz$m{x{E#GHXAs=DWT|eRS(<Vs5^<VAx;P0s$t?qarlt<m@6`#}|JSd&w zHcFM%tTCf_B`J<0vWGL>lqo@(Qnd53Cv67L-2HP^Mxh4hTpYG~pXWx6nFoI1_)|i4 z(`3-T-pzbV+ET~eZx-^rJvEcf7A8LOo6j$@Es;>3N3~(0Zf^Pt5v6Mm)*y61Fs(r} z4+fthuT-Zm;+L<q+;P!`#<euvrMw5J^c)0j8R!(gz?=zPemH?gP`A8=gQC8QWR@&> z5IQ~D3QZ|X5qoXxbC|m%S<Uj|DDg{w4NA54<A6%Y+DpHXmIE}ySRB(=Fh6cm<7OUM zb!hCwJ2$^s5&Ak12=q8BsPA<V=Fp-Oj^wbeik`TamO>=O#<yR)gRMzr7JJ8=1vVqJ zG41b<M4}ThdZgwwhciGh%qp+IgBfDn85pCeWToeMwySuU^{PPY8Q$$e!5wi_(FFtg z(?=MNrxDx3Y8D_0NQ%q5L)V04-KE&ved(&QBjeW6XNPg}*UNJvkAAq$veSgUolA_m z*W@2&m(SVe`o_v<=`3{3K`4ri;<)NoW`qer$s<<j9*gPk$c9&IF1V~r2v=&;c3S5P zH;PhaTY0^dj9)ZyX`kdjp7yP)Fc%3j7h$d&-rxz3<q3F1Po$*oV7vSUbau#x*Nj4L z(&pGcVvbh{jX8<<^oNK}Oq+Di$P+nZ8nrhtRAfZOGuOB{N9yG>-;{TrIzQvPOL=fM zck}cY<oY|s-&=BoO~-c4$2$R4|DgvB(mj#IzNNq>o1P^*28cu0E*A;Bt}hmb!(|V1 zj;~MtL*4a{JZmA4ZMm2~k!?EhX-1WvrImVJgyYc1C^-g9ZSWrqiV9q>U4L+^T~)v4 zX7j!XpY;tRWG8<t>}Pk?*4@lQZ{CApvGE4AGr2#tkSrAKHK+Qa5a^%!GeJfopjC>Y zm<>_T8uFwWc*2}Vv2Li2|84jtw|D3DQI?;~NfQ^5PV*!}IMj(15nTCOD|Bx1gFn99 zB2~mZV+QSqSgYdzlLMdmgTFO3S(~rOim5WY!uk9CWNe^}V$gPWpq<oOOFT<iBKT95 z@3xU>{VmjZaLl4t!=YBN9bR4ZEQGA9Xz)i(hTJ6Sc&v|iU*(Q7@|=FWbys=>_9&O! zs%U2aQ~d=g$1i6UR&nz#&}f!uCp&3Fmvn_*v#^hd$#rud;qvndeAeSLe!3>o?M<_z z6BC!7<vPnn6Gq**I&-+$@wZz>f+TQ6>yr%!+z-z7P}2}>=w7y6;WO)IkztV<E5SB3 z1mOk}s=jm7luv#L3+M9kx{usyDhyYV{+8dK``}cvJ=|A+KmH@^%)%{dV~iJQFeu8V zAE%!5rJhzw4Z<=T+$B=?r9H+p;?jtMsmQmu>OGN^;zl@{BO2XEm1U((4W#qC_KoSY z+c<|7&vt02)Hk)1oVSE1!)kXB4btNZSw&oW(CyRR!GYQxL0zU>IPTtesKa8>sfD7v zC|67T)%_=JO<nG+TYlY-0=quK7>f8w4C9GmP&?W(B`In${kgE8Y~(d!hz*G(@S3<K zn(&mWKx+pv=kNmup-;ESP*rhlIUy8~Z<)+@{CV1}b_U!xOCapSgSS}7Mh(3qqTNQ^ za7V%TVTu2%CcPxY9O>#^Y{AIu$8F03DJ5}hpl)1`IS+|N*M50DfJ6zU^>|faP6%#R zK|yoOqW|(tg96!bmzs=)0ln&mevA*F%>bPXqepBEMg4c5BryoAduB~_{L!wzE$aj| zpHPE<uH_zuD4%`!Mxvcb(Qpe1e%X~2O<2*+AES!53)Zm|qSc8QS5mV^1rndrqxtAB z3z~Zuue^IJcV3=_aO{5F^?2L9wFP8AIbY<&e%(!=@OTMJYro~@2-H>f+%cTxliR~i zua!R~X?JV5Clk~KV|JX`yD?m5Qil2Hq*m*sHer%OlwK+4d0xJ1yeZ6@W=>Vs+}t+h zh1LZ!Km12f1UbPA-KrL<uf1RSyo}iPjl4stGUc?T9b#()Z)U<APs#Q!l^a9_uGSu7 zA2eU9dL2DJ7kIqWj6}-%$zCo|H2*dJQug1CvxCip3~q5=n_Jf+C$T1;7vVDvTypQ! zy=FIl|Nf2LLYewAgp)qj)`QuWN~)#6@5U8#>OwbC3<R~M#Gu?XVW0qVF+ZQy7~`>f z?_?w*Pg@my@CU-DWb0E{{k{ztV`<?ss(J|5Q0t&Czmq%icmgN25$6nT!LYl<<sV|Z z4ynu26L;d`fE_|ix%jNmg^U({k2FG%peMb<xI1S?X;v8i*$y?9%#~{GsplR`AcB*5 zV{Tfu*7}yG5CS6$>B=nrXA<e9Y#V_mcBJFW=vQ=GJ{k>%IhY<+$#ozO<?+BmO+969 znl%O$or`Cc(7^4Z#KC6(|2hca=QF@PnDBb4tZR)(Xd6qQ;cNt>X1~?DeW7uI5;8-& z?2~Wz<{qo3J)}}rPl51(<6$&*JwM65LP&vEiB!hg`aRc68CfOK&6HOd`;Pa44%zTG z)>c{fc6nE~_hJ|CRd?2@?bU$CUm@8;<Td%@(}e(<$A7w;-m72z@YsKR-Rw^kfK6%+ z3aIjnRTYEZbyR?GzUp+^Im&TxxAmEOw$8l8C7utw6YM)P?z&|S3Mq}8z8c<}*+q@( zs>5E;#$_NN-IZJB(d{8NLk8oec5R)cm|&{BrX`WF@omm5$T1+0)Iwo~f-mi2%|m}r zT8^7&)oOItm!08we=!=e6z=e9{kt0WMO}W!w&L%LBs}WMNVnoE$m*kg*?|zyIJ*WS z#l^ObCuNr!&!`pV2w%Kf+v>8UFOBE8oavUwLs_*53%_!x2P4Ax8=HpZk3aB0$CP~o z+fbF$B^5YecEiJR@UO*l4pMGgMP*%SyDp<toX487Pl(kyNO@7_4GNJ?A6YhO%qy2f z^pyyAz#Nhc`%p+GQ@a9;Y4NfuPYNzrR=K-m^4K_(*#h#bmnXN)$?tBNk_S`sMlye) zZ_uqAp|i?!T(;`>!iZl{iOKvLZNe|@yvtu9NlZ%PHcJu};It$6`7Qhcr}tC@yz=VQ zcBtx#U*%4PZ<whAI|Ht3V%}(BLlUj0I?niPT6IT3N|@QHhazsa3qSC3Jo;fs%x@!+ zZH{S~5#D>=gNnk$1WHao;Sp4@EEF-B2}+n@eX_?V+r?U#VU;`OiCbXX$s!ZAr!Fzc zD+V>suCh0J!Ri=5q2&P$L@w{Z1s*8Kv)j!l7z@3$V=VQwj@|4x4qSr95O6L|oWD=z z@3ClK@urHgSA^PDK|8%WUrOHwIwzwDxI(puVWV7Ge;lbHCcf^DNZE}Fv;WqD4d@sC z%?gU)b@#&6u9#!Q$(7dpu_X9&d7g(dd1U__Y80p!qi2+cQ#}f9*P8heOQxv&xh-84 z{#yll#!`kNvP83ojobl!Hsy<z=OO)8JxoUr!6MR44{rUDOykY;+izlMF%sAC7pC;L z43s1ruLbtD_=XwfP%wc$LkQ;+Je&J|Z9gsg6iT1H;<8+mSKRk0FDR@rti`Z=###u$ z<K!z54pJ)8B!+^bGJJ_;^O%@0!{A(?cD{jhkoRgJiyB|8xG=JbJ#qcv1QX!+#k<*; z*k|`VE1L-0@7WnaKKm_|us#x0TY3SnMoFtX)dU*lQA{WUIN#E7efjdl@ApwwJt_{V zGpx1t5@W8Q1@LZ7FcBVMsw;oAt$b`DID^X?m;EQLz^Vg|q%R^f%yNba)SzBGTj{b8 z51P*7pYDoL3Xc{XbTJ%smL2zJ6p$3>yc)WcxujS)+M@T<%lZ^&@TXQ@ESpEY3d{W0 zGx%bx`ZN=OKO5n6!>;Dus%mix^zSiqBL{>j7hqv=1+mlF2DGo(B&Z&)Yb=p`_XG@r zmytTTd*M@O^YgiBXb@)a0T#%Thb#9=Bc?oQ?6h<$IMi2mw~9<OB?q~Sg}<sorpY2x zcXC2kR7%Oya{!l-HIMc6?u1TW;4d1wQrcNCmFmyDnEp&d7G-VESo$io%3{YQS`Ut! zM<Ug#HM<6$PLD)}>Li9_bqxugQc0btc6X~CQP(jXU)-*=)SW-xeyThJt%WJh;L2MK z^Q3((5^Q+M_RWo<)?Oo|&+&n@y6W_$pKRl@3c(%Kiu)&q=|zH`%LhV}?63D9J{q;- zOB@aF!)lbURH<@1Q+sV`I&izPeiqN*Itcc9^o<4d?#f5FT++Z9(9;F3Y!Tsb0G-<F z(6!n_#%G1>1U2P;R0#4?XCK!?U}LScAJoT-zH^cYv<`S|8w>8v1B<~V?|~$5DxS!X zvdp94;qPD}R|9_dKBMti5*G*SuO16QBuy+R_-OHr-*`pVzreS*a_H9ul@UXLv6N)d z`y@Hz9*lPXR#%ZpcE}p+Pj~dhy4sy+i<R<VoB%{v>*Ub`UN-U$KKl&~8b73*=$|5! zQ9Z8eq_dpm>ix7CUVPhd&Ze)0N3EChXSXTrjl*bD6z9CiuW2RhrI~?dn!^!2fA$`< zCuPRWiIx21F%bM`n^e!UeEXW!kXM8G|AWEfc;_P@TpcM}O<#KI=@xdv0bxx)`1YrJ zPCXyqM!ryFk{A`%WfwaU`Ry*fw(D$+PHoN&y_Hk_GfwYf(&YEh*OW_xLj^#}Mi5Rk zMJUkI{SHWel8lcqF2p;&gKpo%u9z&zsbO|3J&A_7^#)V}wOO4pO*d{6iY+q@J|t%H zt2SE|H34EG)Ik4c<r;TiefXoF+=KLct(@fP8L;$j@4<|ZF!IV8&dQjhW`NW5Oy)`3 zbTt_KT!xpvlnAr!|6&0ODcUGD?qq|t_>1wh_?+Gw6A}58uPy8h-D({k1;h6(+7(J` zllj2jkYM19*5xw_H?MrPNlg4wSQto|AAtesr(cd?;VA`Uy8?Z=`00yWQP2gcs-e0E zLxA=$H27|mt3g<*AU3&$go*EE)N18=h)__Xk=P~nkJr_v>E(|M-;Uhp;l<`(z8$En zjO4Y$-p)%ZWxerTE%hZ@@VT;#J_22-i)Gk=5y4)t4gJ?tv$`0L4$ZcQ-&mfb;-k(7 zWi*+xU#jC7YIc8A;b(T6+a#qm2~#Y0eek;X(oB?>xpK-Pmz^f1&kmqV_%5(bYM|Hg z%e>ANN83{(U-c)L;9!ls2a8OUoHoE*3@{8KhU`~7gE>}}+_0fHfni#+F)3z+nmc`w zIWtb5Cl5J4oDhQXH<_%mO^e!H;)E%UhUgJv1~3{;b)`S^+L@HZC3wC#jP$TTX}=hY z@u{yT6hFbjNtkxcbzJi4tp7Raa+A>$VPL~6BVMp$-;!rR)24JEtwOd01_KKQ=~uWy z?L8->acc5_nxeRt7|c>juqI!bC-D3c2Qx09%R>2smVS$d+SjBH)O;N9Vy}ON6sCpR zLrRSWqkWv^-4G<dt!E$I<<)btycpo<sedSARn={GMC4cbX`eBofEQNhOi>Xpnkv%p zGK+b8rD<kg&fQJI2`C)6nI9=mMy}2>p0|&>V@&>C_fI&CJYnsv;mU)QDH>XUM3c6; zXOzaCtUldgu;Vr--DDpoUBnHR*4ziyFbvaQZ@-|HgU<{}y=L)rxrp0?J1^$m%f95L zLU_(Z|ELvlxH`rV+Lk)0Xd-H>Wbj?0_HhOb1b&sU!01%}$Ouy0`r%4LA!~2n6}Pj? zz90A)K37C~tvd}@=HJ(b=C}}{)I6akss0T=v30&9AyY#H&RgeS_OHJA{Lf}=h0THf z>Ke*4zw~)s`Kt{rd|PF9JIxV@#yf2Axi)>Y-du-TOO%y@@+9d*7(p+Y9m>@PA9zdS z$2}oA-2L!B#I(I-2B4^`4s#j>=9v(O5PWWNr?O87gj6Eq-7q>h4Uqva0@Zynm+?S4 zSKrd`t9SPbWNu?N+fA|x>fqc5Z%0vh6%@Ig8E3Sfh{?e#_ufW}=gO0FYF1!D)Ize~ ziB^NBSXW3Hk_Wp*IW8B7`BbAQrO6cg3i+#YlkLvZM~ko{DmL+_dXz@d<Fs2eQdwOW zV)ps@ZFlzJrSS8NQLbBCro-v%j^o@$GfzXHIFSQLx(9Phb_s1SdoVH=wr<{-J9*gm zP=r-IxP5VhArU6ZOp@9;DY8q?gb^E>0ESr2m4pXzdp|QxfeUzjd9=3ow*@sCaGRA^ zOC^IA=WCrAixkUz1J$BTk{)T?_0Ub$31taf(C@}<vi%MZx9yKGNmR1-v^@93B^k?! z7fn_#^p#UjIn;T^vIQ3<Ujd2%#BED6kr3NuOP!rhe31?8urdacS)%;=#IWhJxw`l2 zlhtxxL{ebFq%<93uNijMEBSx*M0!<dz_MJ-+g#gk4yR$B{Y<u;URKLr6|!&1Os9;% z3?RdEW*#OQLhOD0z2yFW>-YvNXwPUA{cXnn$vg>x8tXREtbY7pjtHhN&*qH4BtMeO zr3s$V#0Uf7_fkSX1iu+eGn>s!S`xTA<%;c}87B0Hg%3XDWvcQHx25BgFa6$@^G_mL zaS-B+qV<8w@7O`pgMZSS(AB9T_cY$3owj}3h6;d$R;tGhaF?%W_)L)9nEA#iW@kIm ztjW8#<mkbv)54@PK@HQ1pTIyoiLlw$X!}xx%qlD-=NS0?X7O_{2jD08`;zO92vQu| z1nw!@4hqU<RY6If%yPd`#MHG5&y0Bvjvr&oG<_{e0Ky3NSfogb{7=U=fFSu|?5Poj z8C~6dd%`m2mLz{p4TN-=fNe*4qJ6VMoABMm<O56G35EVk@IDkuze@;>blA0hM{yCQ z7<#vY4Y9B)JaS!H&h<gtiL3H3Mf${z>Du?9{2zWfnR?>x^<};EiJ@9La&xE$b^0fv zCs|_A&eC$q5!_K_nf)VYr4>?GS4_EMYWnZiPQhKL*?=>{^kK>WUTFqK?J$Qx;~~`~ z$!-Bo<`;W%pMK)rySiPvvVo08BB0Mb){wEOskmudN@2C6g4D0gi0OCsrzioyW;~D< zu`*ir`B;Nxs)&W)@zLcx$VORcmmLjHpz&#MEt*A50D;}rh?t2>&kjZZsM*F`R}&!B z(3^vng?Fk{9Jok!^MzeTG|nJ&)g!-t_p@}t_#z!btawqv-(<cH1}aDZK!Td(n9~Dl ziT>x#_tCtEb}IIKtHATqQL5pqsq)igs4}2|ws0-=Dz+yWuq^HYxz|`<s}7edD8hrm z?!yVbk-ARCJ(BZsQfyzI>S5YP^<O<2gLUCeZXx3Ba7$n0xvCl+KOZk@3{|gD#=IF4 zhwlo)#i+SwR@+952v>-L%*(O}$e-cM4uQo}PVx!d{%Nio=_C!fHZp`5{lI0P;0c(- z)yw|s>uEjE1b~sS%tZOLR${y=Y)cS$Md5YJd1O*$#N9jA0r>r*z;dV&@=K{|AL4@F z1!#oUtofP?6=E|AQ=)$sqK$v+M}iI{%2|1eW3xXoxgTg;)`*vFEXNP7cQ2z(cS{5| z)Elm%PRG>!*#p*o46jJB`qKm)UG|^BhMR&My)H#B+kZrX^-niQs64%5q_`p(mpuKq zX3VbP^PjZWgYS&zN(K~Nr|Zcyj0J^_|1pMkyIjJocc(_+WcXW^I|)%~VB=NxR#Z;` zBPT&Rc9gWoGA6q6d!_oXJ|2kn2&O70621%?5uo$I1e`|hvX+od!T_f@ly_*+TV?`w z>~O}FkLtl6dF1~d_N~u-kd?3G{3nE&)9fb3P=w=TpzgL|hc1JPb{<yBs8+~d*ecU_ zWJFB*KpF9Y{_#{+mp7%#Y(oo_ZmHgAjvH1H1*Pr{yi(ol-`f<Q6zkUpft5FY*kggQ z@k7)2&qSvxY0Oh1rYc;{G2Q0_(LrjqKGI*~?l3lP`ZMX`%^DLao2H1EygU#2Na9lu z<lfqJRUp0*_E=JvdcD0J8;iDScx79Ef5|I;{yR!)y()@pdl&dyKxmb1jHEqE6K*8* zsjKRr4ByyFAkA(leJ%!FS(#vf%`WLv+g1svPIu9IqEXti4ac8z5$GxjHuUOOw8{$Y z_LChAXJN4zsVUi}*t=~m=oIE6GT>I{(JdV@bw`-wI5mtgC-i=I(dbE|ZoC^6?lt4< zKN>XgpUA|2C7RCo%o~<xLipQa(Sj!B2M=QO_>894q$XhAw%rLPu2QLE9Wi~iJK4?> z0zhe5>O1tBiSAWs-?12a2H0-mEiSFuyn^Rf!53_nM@ErqT*V?iT}zcWxX49YOo)wm zC@0yOU_w8a@)plubNLQ7#_gjS*cA(Bc1nco>50RSsGb$_h{|3T*1VI7RQ8U!yImqH zYR-cKN~e*?3%#%J%($lC=8@b{xE0+RVWg!fj6{p^8MltQzsj>Kd<OtmF=ro*#my3` zn6(CmeI-9;`w@7=cEjg*@WI@;xKj3}*HW6ZkWUuV;xd|cRg`rf3(dY5r{NF-$?-Eh z%q9FN(I5SnY~3)pEs4mrP>SqCPq2e8F?0)Ck&1Em3X#Y8V=;<x!GlfZ920R?B36W; z+mOH+yVD5P-mc|0zT5U8i)!ON(x0O=D7Wz>_%Y7};YYkIR%&$eg;r2wIlW}GaqA2q z5TC2-N~?TbVYP+44K38KkIv)0Z!EV$qmTqAp+k6|vVyS;O_7d{OD8H7@1`{AgRC8< z#TND|P8S)~1G$tmy`_A;c=rHV>L<Ez*n0hL;X*G!IN&(oQb+niz|>;D-XY<7_lCb- z-1=jw{0lX_U5~h;t1;>{M|#(Tte+c>mrbSvY}ZNG1Wo$_SL9bEd)E|aHy<DOpS7OV z*OvJO%74W6;nhEyI|<9%T8sx%OIwBD4K}kT3b%o-@WIhOE~9kTNtjiBKh)u~Y?hI0 z8sD=|ZuJKbsD@`~DE;x;%b0kJ!)=49VgY6FWf%jL)StmiMrUSH={2rQRkFqv@M<t# z=BXEcT%IF+DIu%>vyB})@^yS)@(-Hf<@x)5tH7tDQQt*r$P7`y7p_Sf`i>je<jl|o zj4iC0j%jKu;+xy%4Q;hh#FnNAIa|!UoEQ+BQ+LATahype&aiIDvWV>GDOK5rM4A#W zj!z8HiZ2M6Dl4bJkNxK9Q#qv#WlzR`TfoWtobC>$MayS!?u~wTFqg6|&GxI()LGV4 zk#LroMoT}-a}g6x?Co+TYP4B|Jkjtd?NW<MNW71*`-Wyp)#4oavyi9VQ*8?Ly3m4S z;;r`MO$EpJHkL(48jqlbR1?8>1QKoLYt{|X;jlXJ8-D38^li&y5EM0zJ^JI6twac~ zk5<>NK8^Sdb@MghSpw1;i~bl2Q7sB_Yt_K>l&zFW+4sT%LQl4&S}e=wf5x5^0bXJG z2JMe*$d62p(HEg@XU%G1FEo<dq0t)a^l_dp$oK(GukrB8)dL0UqW67-(b&JJg_?SD zE9N$t>5P}k*_9%0Ayp}Eeo1>~@d?6bB6ud%8WYq{t*YMIT)ik_{Lg3Pn<t5#_zek3 zg0syg0ibEjGc+Rml}!{R!bonDinc0S0Jh6Db~8gl^B;TsgZY8<N#X<YRygukPuSFN zYB8w%GT53x%{SI(5!1s1<zZ6H{)wzj(7uGWA;{TOF>!mdw0xMF8zp&;$_-taIeuVV zcs!?6$cw#Ha0}O_7o)r{X2KeH3Oa0Hrihq49I?{{Sr5%R%0p`es2F`T;Kfs|YlK>b zpcZQP7%MP9s8v-HFo?Dcl*;Y$YW-%_F&g@48sH~#lfL#o>APCDCRZx5H&sG{-#9oI zeclY~9^txy!arq~uF+nkIb>~{vAQMBOqSzb!3pGrZvIBFpD>}c&O#7#hGY;4`UDnz zM597S-6kX}m}a}-iBby<+E7_p*Mehv!WNO*BYI;PkQy9wSG!SJ-Qt&x3oTifW6f#J z*FMdWt$RTyS2^4b2g9-}+wFQ56dOJL49niJHTrkNY0B;6r%1-XF?HlCJWe0`TjsiZ z74y2`bVuE5FRNzh%y9<0`q(eQ@hqu1<@)lXIre%t*|ZBt>LdRW4q=9OKf>*16GT16 z9z<XcwIiY@MmQ^To+60ctJ=Or9ak#G6Sj|r+nE)*J9E1O^^J|E9E1aSOg@F8Q)jMl zM(J|9+7X|GW2DlVP{8dWXg}^c{E!OtUw9|6LENIMfCOxPPOYFp+~+w5pN%j18%s|X z_)JC~FZfRsTjn>e=t#%O!xhXa%U-#o+unxJjq=vzuK)ZYtcfsRa~K+U^DG2dLaEkH zgzud)esSsLtFMV{SoQF(F>F|M%(>%uHp=2;^R`V@EEo?iyVge6=Zb$F7M%Q}3;pm1 ztSO*l=T1pynT(*M?q>1|OBg99IyL6C#dn_@z2&AMOP&IO5LPkeeXNr8O?W-?M!O$e zS<8dsB@XBaC&dcbO2faRYqC@~`&nwOJvG%mD<4_fv|nvMNj935C7EsItogE$QH<v$ zEuG^80le31_l~wOvf0!fjzuh^K@Vv0fP4^2INJeIJ~N^1<V%wD#r-$GSMGm*UWo7? zji$KOu%E`+Xm!gjue$6kdvHVi|I!@G=sV}4RF=R{P&s(!>DD!whqf1-<DqMr15oI? zrr=^qRWNOe&nB7a$Y0zD%(S(n%tLB0k~Ij|e&*z%t!nSGln^)*XgYP=KQA4xQC$)W zotc7=JS{Jbuk2iB)X_KkYJE-=*KDxw({y?vIl?O)bWroK_KhSUwpWB4wj{wD(ZN+< z(f?MCL;l7hFl5WxiA)=KkT5-`&r^pJv03-`fXEe#F3ea@n&3Y#@9^y8-lBH-@jXhk zEP^mUEeii<%w}1Iq{kShKr&uRB$h-NJSeYwZ^SLy2wQCgA*##qcu@x+lp!?9&)xP= zm+9SX*p1;QyBva>Sd8p?<?r{E{aC`-!^kdPO@@Iw5U{9cX37bR3~1)%1yGQT{_-u0 z+@-F==^DQ2f+uTkxZ8{?G|wf54l_Upm&Z^3<Q`>MUhlIi)-fGVywN}mPDWo}jtBVI zR%{Ak!|k3f&aG@j@yx;b`n#C^59v_qO1VX^#z#x$6Uaa_R!;f9<tWk#at@7A4(;l& z8O?TuFR5LF`s~@I?u3-Kjxs?xa~%7hM;AFh?DnPU70>!w90j7TT1%JeuX?7+FZfyJ zFRp8r=S>5Y_9N`zUveI12fy8@ys^hl!jzf&aA_rmXwQ!Een0lYm}n^6@5dnR-*YZN z$`mx5P{=HwdN`b3T_4l^Aq&{5#-gCji6u2JGotRbNKj_axb~8DmB95gUM;_{4%Eqs z6qOFw0|1v=1HJ;<1FA6Cw<cZ8ZOvS%cRQE-xCE6U{t0sVIfu98rmyT6$%~^K&uRkf zvhHA4%O&j-W8DOs{BW166Y=CcRp$_mg7OZk0`#LMPUh!_<FQ?Uj^1u(-J<c+*X-JP z6|wS6c&VHL+ku-j<MnJ!WU8vWeVve>5A;9#X;Pcf4!&f<A;UisL{mxK`dIW`bM<_k z_d~$Vh((j@daTftj#q<~jNg*Xz`Q7Y%Y<677ulH2K5koLU7p|Ol&c5S35WVO7K-e4 z(R#qvkLlO1A(zpAsNH(+I^yR~j1=S6lu!Aq&s8JjI^i4Z<HzJ=Hx#~!#m!cvk`jnS z>j5D^JZ;6SHWFJFG0&XI#zL9>nuE_+e;*i&b8eoasvs9hNJ-8;VBYD>Zabg)4>0b- zgBbLLomdQmTpM$yBXuLfM(WbSEq!W>+FNM5`Cgk7ufE`j9pwCCYOVUiO7|meaVcEG zEEc|1brQW3rsC^zP=;MQd}U7{^Wi>+;r_qEZ^>aRO)n}PufP3gBi#h~^OnLlu=KL8 z)c2wu=X8<aanHrVwLhRXC@Mh``2S;<53~jdWU)B&Cru~&jSClzzJpV~gR_rGTdYOA zFY0AWd=EddS=Jf}WeqP}<z%HqD{(4)qTKV_16hNd>p^8g=hM_p!viGSh2m;%&LNTh z9P3UO+b>5WcZ`ILV5Q96%$%8W*BofgaoP)9T-Mf4R&oMCy?~)uuF8rNdwq|rz`OVH zd_#-J)mZ5=IP7~=5u>GJNg1OER~8<kNN%BMp2r59{h@G`BAQC*DnDY7LJ3y0WU80` zsC!@E8x6=tjrw4gN7XF&E_69Yfyq)?n(s7%y&k8!Abo1!Z>5Ee0oqu(c_8QAnY_93 zsq&E~Q(ukcBhkk8$=_0=u=h?tM_d)6&*7L!gq$QXF_xyzKw0$7SMcpA?IM9$G94t< zn-O6o?AlsvI1`jfY?y%prC3`AXh^yrVL(OXtOOx6u)L1>6>;OipbJ1%K6?T#=8eI3 zQoW=Pm?wG52^0081#dQSl<*AI5<3}xI^Zhg!RQP57u=3?E<q%U$eXT8E05@ojs)ge zA%2)O`rZv2Ur1@hlgZ3{?$g@q-p3oL=zwUZvDeIdvwSzUV$n`2cX1x=>}@6U(*KJb z9mF02ab)Bak|5I>{ZmQ4@|LJ!mdn^-E$W5j2<&+lwu0f`li_sSdHIvVAAE3Y_T9f7 zc!W4MH*{F;6rGrnS}>^KbhWwQdEx(b@_RXnnO{uDca|oq&bf=OURs%7i3@wTCe{$3 z7dE?d+l=2jhUvES6&L63)gSTG9gl0A=kWOiBe3Q>xVH?YRUF7qT2+uBiiPv5S4eyG zJOl(HV02CSZ|BP2u-K!YsfFehxYxkh=i-$9#E>Z!P{odh+WrJ4sjZPXbVH>SltK{5 z;D&*07IpwBp0*R2#pigCdHDmU2PF&SQEOL2phW=(htA_&GDaH;xZ)mo>dy!b&un)z zGK?yx{8U>&CBzaTC2bpvH3?BepnzpCpY&LUS^L8b>y6<ElRrv+17L*DrIQfw`Xs5e z<QZ?$ja)N(Zg7`wFrHvjv`7%p9-yLck2e`)xuB=EjoP{_K@;~mx78~`e)-mW=#qkf z*En<M@81xQ7}OjrU)tdw{Kn#&{jGqR=mgJuWwA3j>S>(1VjH2`k=i1Focl~zTAd67 z1l!rh+RfMro?S^4+K6&b51>FNV-LDufF$#L*a!eshfO^3syG6LiUb@ZbO+R8FnRNv z3ov1c!fhI?awo@4KAG<v_%C=e#r#h0e-^rALM6M=1>#4ve7bk#Yt8R_fP}Xk@o<Cz zyEFJIpVJQCrGI8EheyBk^hn?;37Zk&wIp@@z2Ndnc<pH6@Zx{RK>kaMa8}L#U;nl_ zs7?p}`%C$8pL_jU?M9|N;oDn}8x5`JeHu<0uFkg(FaFYgZQ{=&M>k#m>7V=i*dJ?V z!f)TIvD0HI&tk{O)k+FRN6t!snOh3uwy@s^)P=4DE+dSGOgvxtu>&3XDs(%GqgT-t zlMFBsd2FM4bF}jHDeFqs;b-3Pig+|xiO+*6)7`W3tP37fkFD^{?z(Z1t<&Q&M1{)0 zQ6Q270a|EG|Mc1Wrn#3F8W)CMAkJ>ynYVGan#MG1zM<v+$|L+@lZ;|CJy<85Se`Kl z1OW#PvyE41m{1SnrA)x$8;yPz5`(!1$y8-@88IU?HH9+jLX}CndD6UZ3<LdPg4Bud z#fmJi<B!>fhcY0n-M2<xDiIks29|tY-C%+VphSeJpV$MvcK<`4nT)K>y>S!Q&vJh; zROB(8oM2trknknCRd9i<5o0r31Q5zL`yxSNFoA}#d(Qpr`(@NwPqjb8**HhE@*dxs zb0poJ3}pi+;<T>{Y1rxAe{;gKA^(k%%e1k$JE0r!P~))~-rJcm6epcsmY_T7Tum!* zZ`lF|gUK?o=!4J>*oi*=ueG)G2+aLZQhgD7KQsay!wUr9Q>iF{b@_n5{k0dtQls3i zDk9@#5_DJT)+$tmb{KMRmWKE5N^Am)HA7DJuIFA6H9}PwuE?JxwEHqV`J#!FYo&k6 zJj>!Qg!|yuw~1E&qn{ZCd+FG3%~#!L6UuBk(MKi8Q}*^@RIy+BRYG#&2NAp?C^FX8 zKHBJsw95YWqdSZtp436!xB!!+BfD8?ZbPDE8>J`|Z|FT@>pL0!OX;SoqcrQ*M60#Q zk4s3?g$uYu06thDv}6-iUh=v_N@57INg%sYwdgLiF>_d^0$ha#&7b+)u=8RIhex-C zKCIWG^=EI;l!Tltj7{bpT0UD7<z=#WjQ|!o@SBhXBfDf%gBoEs*?fL^!@zbxlz-S{ z;#DX%qDyw~*Ryg9t2Ue%kY%C?1BU<r{sL&%Pj-5i{pzbam+WRA7kEJPVkf^+#rD~R z1p4%nP3_-$%ELER71sg~ll7|pp#oA1LHJ2E5comHu1b<()b48Y*lV{ys|sqKJ7sU= zK218=HiBv$cWB6Wc{B+Nw-cfhC7G3ECjSw9CiBFPks?fWSyV(+W;ag@GL(++H70X+ zR!<J^b9x~6cfV_m)Y6m8eP7Z8CZJyvq&;0z$z)sSA-laq6=Sr*)x2UH5Ldl^){MQr ze7_Ko->{#4eGss;P$iZn2_DocotFP>82$s~1X;o!ms;s3IvdQBGg*`38_aTqnE_X4 z0p?-bblxW3n|U?HwV#e7n|L1hwar+DlTGklwfNKHL?1=Iok{FZ1KfV}Y>CgUZ{n@C z1%S}Uw~dPW4(<(m+6P7SuS?{~HBR%!--Z6EtA#7p=Jn>QTc+m$*M!{y&8>O?D-`>G zrmjSrb|)!>b?t!qUb_>LW+?EZ7I%flK;k)@YFA9Zbpr==*l3;zxO?Y_q?gke#rsTF zUztda#@4`Y`(+pi96S!htXo{HPpKVEmoT#98?h4rvAj!}QgDx1;{K<#i`{JoW18RM z^2Qj;+)03bfp}f;Y8u!Yx@|+-mKyIQx6;>_$!H>e6(xGjJz_56cb$E@bbooiP!VXk znXpp&e`4_Zh?(1n2D%YU^aJkCK5>axf2_Irqaa=ss!MOTR8vym`_g*|j-0N^=pMxV zC*3rzf;6Yw+(eAe=e7fquq-n_ZtcHmUvty$F3QwJLneIQtUVJW*CEgu;<`}~JXj}5 z?R)kMfor2vC`3b6gaPHOM(i&Ht1vi2!)G*<%pjyWi<#n0$Go-i1_@6#_Lu6r8lE5k z&a^Z>=MJ(fQ|{fDO?y{rm#2FdKN_$f)m7MD$WQFK(+y~EJmK|irXCn8C&p?MD(K@u zeltt3$yWVr^`+b%6CpZk{>U+<SY#6eRsb{Esw!DbI9vuI;T#qGQ`!_K|l-u~Ltn z2G{odV;>(5HotB5`kM#bSjPT2cVL}pHD+^eS<~ui%OY$@GDSJ7plhiN&eU12FT7X3 zz$gN*;iW2}t)9L5=v}veA>28)!VGen0TcH9oG@K6drr^hQb&oAe#|Fkq&sM&tUA;} zf-hv|a%Kdz>j_(elk40i0ph7G@X%zR>xcP^L*fmt=YTIz<{?#2Co)7OzH^d!!0c5q zz@G@>nOa<QR)OqK8bh~2w&vfYDyp0pN-lRDQ?`9Ocwm?HFw%5E1qrB;Q8$SZUI3ye zhHM-kY|?a<cxHY1arQpTu;GQC4xuza<|&J<zz8bU`#zIzKaeT~5C!N<=Nf_WrdN^; zDNv*E+8rmPH=qoYtSjax#^5rnvE+O!CxY<^UUAA4k98CXev<+pm8;vfv&h7S%G9nB z(`rO_)JoqZ<OjlteKgjH)Y%ulWNNivHne4@`*Mb+Tx{_9kWV>CU1t%9cDoXe@lFq& zP-Q2FF!){6;G!9sfN?9lw8*z@($Z)aV`}W<Rw%Jh6Ad`|GMT{krEsyV=Kq2J%ECz< z-XJJEcjWP@nF*R0mi1#Wvt3IHwiK&o;Y&=IS)>GavvQ2^66X|et55KqPKCiVp$Q(4 zOB?eKiCkyRsbjvrodM!}stCayiI;Y}cZHjBPo9Cq$P({G)+&nan$UFQ!U7}PXu%?` z#?tCp?AxYazF2!0xsk|=rX!%YAY8Pyt>;6AOV2p|i=s<eaM&j}7%3^^pMtY6rfZ^` zK<L%1ZkK;V@sg25U-+9b(DmLdHO<sy*v%>vDXZ@kHmnyjV9^YChE)A!2Cknc0qhD4 zf9Da1NJ!uKThcp4;GCBnFY(loh%CpIa_q*6*!uh(sBzyX@1Te$#RcxIv{f?mg>k8~ z<e{XZ%?7wCO>PLigHcjv6MS$2FLhWScSa#i^-=W83f+1ir;VUBv1(%w+LHeAFIBoz zZ~JDm>;Zz44oejhZee*-;V4_2_KrQ8F%FBl;%Fa+vLYH*ZDg#rgjki6oJ{pfR*o%9 zcRB8gfg8F8tUDJ=d_Lp1RM7c?KW1tmAtj^3Qe1r9(S3b#8SHp=<~x!l$sMpJ4SBJ5 zM{NN&Q$LLDh_c@LBl)@GZUJKy+i_5tEmBbXn+SbL%-dqGZ?e-qJwggUpXlJ#>kvDY zJ%>N=6%XI!n9Jn$B^zQF<2qlWslGmEn!CK(I4!*%x~LTj)>!xrLZ6Sy*K-+OX?$*r z@94JuET%dh1_W~>G3kfYRZ#h6JfnyjV<57+%^htQCAtcKcEQPgE)B>N)~Ek0d+UbP zu44+(32<TsNbpN#<vM{*SV92s`k^}=!9-~>{eU?i(V!@$=n9W~tu9Dc@672&wUu2u z0Er;6$|Dq<yi?>W$DT%*7HljVpYzCb?N80Dfh+P{x}<AKBgn}bG2JCk2Qr?(@=rBk zCf6_$y9tt&wx#llHDg9;ONjIz-fxc*i^%S1D{>x=l0s_4{2WxXNQ5n{>HuB`)U|RM z2XKmtM0Y#c#ng|=e#r@t_2-#%;vO(U#SDLMOCW657b=J-wTZxd266z3U`zr<#!Kg( zmPa_eGFre~Bud^YEc}RB<e`a>=s&Agt1<eXU8mb+Ca`mT23cf2MVo%Q&C0|ZH=Jnp zd-o(yier0y7x9qN-%y~)2rx_|2@|c~1r$7G>>4;|QdC8lOK9Y9$0`K+u^B#gm#@!2 zZt=zckXvL(%-TI)P)7}SZ(Pa^_6sx*bQjM8myt@HgYP*UObNBt5cu?s6`jJpLm>w~ z{QkmtQTa-91W6Ut(o+5>{}VmkZKFuVMHyh$t+?Ed1xFBM&Exh9(bnsl5HNv*Iwr$U zEZZ>UcoCR47M=W!Pn1c%{UIWmT6!w9rtpO$W1vT&kbB5dUO;zE%$dTSg*PN3&}NhP z-Q%ogk(*-B?b2h5PS;HuzgqJhS20R|0I_l~XB9e@VSr5Ll1~dxs%l>c`ZkDbx!T}P zrYXSjU6k*UF`@P=7`g{1`GX)f#FR}N$%7!QD~$yMtcMkyy>TSfF2>Ib4G<2D7+qC+ z@FD(+D3Dq2cz^>Dglx!L?xS*8JvZg}?I40gyy;+D7}|*+<!+c~J{VU8(<a1;60!nh z`L4tEd-;S+QB(QDrGF)_qx-W;C|N^dLgWd@hei%*JmWB|DB=(@CNz|Cz-0V#CX4O( zb{>{=eAg*J4M`FD=?^0gF!g{-Qq2M`w0z~Kcrv?m0GZ3^ClFIVX@Y@umKo=hDx?2r zWJl(z#lw%~^}?#e)m!nlA)8FR)6Gl6V@<sGT(9a#X_`h%WLh*gZt2`iM+Rad$S0Z< zSslI+*LTn}U0pU&!QVL<)(iRaJ!>)O7`#!}xwIk+d$NT+TegFrN4U-(d=YLs3h;h> z?X>?2{m$XnyGSi?<^(v(hESRbwM6NOTV##h#{jJEGUJlH`tZh`wo{FlKI+5dC#jJ- zjbNDliq6Gj<cU<Av*A||9M$`p9W7PNYY3uGz&p1?g>N)a+^UF}vZEBw&=Y%I=nmLx z!1>rBI>G$FRys6&hGi7eHUvZ?ZESLX?WfnP91v3qX;GYxg0@9U_}x6%L)>=~qlUY$ z#ox=edNVvJrC2PDE@g;IhkWFUHL1|ZQZEI;CViH!cFyNDHLnfID)3_T-~tkpKzX@c z4u*Uxgfk&?B1hX#fI~4X{Rw3N2b(01Z7&~mv#W$G0mf56cl*UEJ{KQ2QUMGyMq<{8 zUPTsis%fmZ;@tC}OarAl1?ZKn|3#cX3(XOLy*LWeYFvIHw4z&{eVmpv_ez6++B@K# z`DSFz86$b%YB_sE<;>EP!L)=K5RugMWWK@0oGPfY)U(oc$aF*m>?AE<1h5_Ze(HRr zZCLK9(bd_wX%rUV_<#1S|BS)}M&g`4bJ{&enKdrMzu4q{(eD921f<1N0L1*w7}WRy z_Xi4U&~|rQbzMaB%Uvfzmyz$3qA)#;3&?E<IQ#|lO3zUkcS*p5jgUIa+OtFLogpz& zS*$$XI6MH{4eB1eOP>v3HVk21vBe#E%l(-(g1~cKdex97UOlrFildWTj=56=*;3j} zfP}2<2iACz5#%#UEztM1_mBz_-~dcnnvyXmK_GBcdzkiRxTc_h@(!-Xabf1-r&@r2 zfjp(T&hIi45Cx1dNs5GU(|*n7g*kA+@SS<ff%#PanKLM&&Y7Xn+DB3#h-izd%O#l8 zULdoOD^=un?mcQUI!f(h?LzA#*==^7B?|m)W0_7W)q2jxbx{0)U<aU!;n!2E<x3?5 zk9(y8HcQ@{N9f&1hc)27Z{eaUXurrHZ$@=}t1Fc_(}_C`{Tqje-ENyV-wCGV#}e3; z^TO`g4w6uM8mG%fY78>(Mm?IlhMLo<{gzSq+PH4WcJ<01tM1FScY4hI4#|LiY2NDP zo3QM|;#+)^@TbGg?}xGwb;4V2jYP9WYBzPrRuHE(WQIi&bpGJ!(66q?zV7E~880Vp zsd%_Fe4oL;R3{KUFF$st?~y}U9d<!F*n}X^XW=4b>T25O)RiIt2e1)+<QlI6?y?60 z#U&{Ua#rDVAHmQ$^E<EKna~2)Oe#z0n=z{>burxhCyI*|oMEupy)iP}%O*5p=gnhe zO4|!$$=srv0NL=mSs{b9C4;?Qsudbul$KXahww<cH51U(Wv6GK&57*xfQR4Wel@@$ z?=u6X(NUyZ6&VL2&x9}m-KTr}-A;s{hOc64g=}(d=AB>!A8G>B9%=r|7})yk*X}*A zXz!yP8KCefY8@p%Y74^}BoOw;?0iy?fRwvEXskK&ehh-pE^2yVkDS8I?s#ZJam+R} zyS(M0jOXDuAGB(ShRp19TSZ4y1+d#Ws7{AXl*Rh(v^DKCy%3*n#olQoA7)=#z{QqZ zQR5swL2fEteDEy%96j8aLtM&F-rBbY_`ns*hJ0HPBAx5(3L@Q8ygbS7y3k0?ROFoi zCmg6sA8O<}gKz5W>h@Xt13zFU_q^*IaAZ1g_4^9dSb1i2u(|v9zo$lQ4j9U-L%-T% z3i+1J9^()Mx|v^Cl<5ki$YS)+EBUsjDFiSzrC&*e?R_BImDWT&`!?0yQ_r83M=1f= zbUX#@LFqGgVYVKE`LPp;8)J6o<qBQ%-9ka&1gk3ON)ZD<wa|JhOFyQW0n)hCb=<Qe z_WKF)p$XoH-&A4_&DC(lB(Xq*@-*9_39cPXg!Ge+<cM7zAX3tr=E|IZAf&{$L-B9@ zOakY>xBNeRy>(PoQM4~iNOw0#E7EZ24(U#5qz@qtQlhk!bc29&cStu9(%ne6bid^t z@80{~_`du863_5BHhb?i*POpvzjgq5vS5K<9p#oPy(H)gT32kbtvDFd)*nP~JkjRY zfISVQK}2OJG*!ZDvohj=_?O=P60UNkXcu7l1ITEq?P38{`!;W?S$@8^f5T|V{rpFO zv^8?WvkreN7(php)ze|MvOz;EHs9m~>aq#?PP!g-?~ypm;R?P-wWz0V8D^tzyBTO{ zB~3khswm9NyT3MTO|Do+{^*Eq9~?hu0C^Ct|5n0Kk-^+Ye9s6SoWJ-#s`^|lT!0JT z0p5<zVepuSyg6ybF$aW8QsVw@@VO|lc^V@rSbau3bT@^E$ia~>CxmVxu9LslL1>&m zpj1>7-EBirxSnofB5veHte~-mAnsc)xP66DrxqJm#!;N3!4hlWfX$aDaTr4Q{x#ye zn~nsDcq#S`O;ELjCL)i1@bm8L+fQ5@X-`+PT##iG_+J!w6j0-xda`0``=o>sn+<V9 zSZ<@Z{s27WN~3Cbk_ycRYD#Wox5f1}ai&z=XYz8Ku!6s&2M7%p8zy}WRb9<jsdXd# z<0aPdf&f#VU<8>DeA5a*ElSl7Q?|o1r4W9T-j={zXwWr50D4A1EP<*x1WY#R`&*sg zM5h&AWP$}ah#0-b{0^kTRq4Tt%me`I+g9I|oZ0dvFlOAp2$w<|S_p!kFlfiE_B?KU zUaE5EZ?c}d<z5MarL?5cw9~1g^mX`&EYuHGQYySyu{z*v#$iun&35g4ze?3O*96mK zFSPV6EcoM+q|w|c?5|_-;`8;7<2^g8ZI<t3;+8yv&i<+@*u{XB>la~&I}B`yB$syw zwB-kzLOm<|niQMa<;OYi%z0LkFMBCR>dk?8t>5uH3|w%aVQ;ct__L4!ryHKVF-0@l zfHZ}BR?L~VJeZ1H$e8jM|3{rxn?G09?~ivEuT`={wl+34j;I{YD>(jz#5Kh7`!>-M zWb@2=4(96G2+okHo061ZNY(+HtIWs?|Druu_L^mr_eH?r3)r^EStLBS5A_uFlF}m! z76aBMms%td{91p@57UVzhLFX&qrDnf&G4>q5S}U@K_=N`90BF$9#fwi@yCU2?pJr! z=B9!`kT+AnZIpd_u@$vo3j`96uE0-538WYk+wnN)hX-l|QDHzt(?Sc*_Uc-(+5)ku zBkWxZ3ydIPph{Tr;ep6<U|}0@>_8#l#W~fhJjI}ET>Zm2^<UbI!bD?hqdN(&QZ(6Q z?gcESsO{S+<r*jc4^#bsw+jI(jxsc|1U<gH>K|7Ehd)sRI=Cjtl-&w3S$)4=0u8@& zjt=@XPgfC4Uq({A$a)Kj6Xi9@EGtMV)0oYBqtNFp34|KsQFbjG9!t;O4-2ao?SFT5 z__VL-ewu|TAt=ebNA0{=PVH|W{;Tk*TXdsg_4yuXQ;z90f}P3QD4Q%wdGT{Bzst|C zZcd;#az2`j&;$&=k*quNO9JJOFs#dI9Q{_xH@t4>HsjMZ@A(oH!Jn)aOn)vVNv)GB z7JoNm5~FETQHTm0b^-`;WapOa8ig*u5KGPLWGx#>yDzpuwfUk#fbIo5cKo581GX=5 zdj0%PnXpugswA!zOZ%`bRTp(>8nWR<`LyDf+srIy)V{I&2|7Y`Pu3m_v_*V?4t`@e zDt5#Nk`PQ)yIhKi(9J*kTSXtx0=}&fMBrpQ0r^FNSLcicvXIrFkVuvg*W$XV%Ww_D z)bTN_weitz?;-^dJCvSvRAFi@!4a3hNKwRsJD+mY$8_N6pL4Y?pd7d*$JL2f+Ml@q zY$7ut;sk_G{VUlisesYrs9BbLbb@im#A?yY;A}9=OyvNXU<1J!3j7M&$(|!tIi~9Z z=u?TH^3!D+a0|%>Sm+J>n*u7oL{Ed{72tdTCNNwTNpO0sCRLR)KZpgT2El1X2h~pe zz?yIiBZVMxSS;WD4p;2YviVyYbjc>*zX#J%q5HZ#(Yi@z8-tH=oZ;;Y0^{(0XaEvW zeMS`m>4(cAN?$$lDL+mk2%>XVGy6u@^*zwy=&vdZIo2d-(kaDN63}zyKC!g|u^))0 zN_w;2RPPIXiyVQoPGJSKq@dtW&;u4zb6iYx#&!aEuayXdzg=jOG#C-g<`b1oSH`?K z%Tjmp8Ss<5G`{+OOq_7T{UTQ!Z3jQw!rLz!o(P{GvYuVqZqwRRKHS%T*!=x`EBYJj z`4mgzh!=hF!FEW2t+j{y=^L;@S1nXJ^V_C5S#*i)EV%=dRtwT5{dL^yelL>93e^Xj zm<La{q&!e)6@*Mz$324x6G0_ae9>JOrPT(6I+;^(s{Drn7Z!6yih-NI(5+kYi4Nq* zDliig0X4(`Uz)(@<=j7YrQ7c{2p&2JJv9(FMi}#)NAFrq!T<&Yu#D4|K=|+hC-9vt zSh!jgHW)0NdT5xAb-kzkvph?6Z6U`>S}&rTXlh$!3H%6YB49MsE#p_W#WgL=rB6fd zUf7;88jm5!DjWr(qA48DfAYP00Oz&3qT=|_>DE@hTHk$J2#FWu;i1Jz)J*PXEjl;d zak3Ev|Av*+GzD3!12GIgGYs`|Krm?|XW4@-gHv5!-R9Itb>ME~PC2c{l_E0*2mJrK zO(4$Tl@QheZQBpeu9N5MCx+*O)hqai!__M@pFQ3O<dfUr=)dP}XIXzSp3kmNC)gfD zo?4&!F|}$@sXT}vguwm?I4;iA65oG0rSM>yQ&hqV6V&zYG(u0S_I_1cN%3@p_29g6 z$q2ounJ*wM=nFQ~q=qw}zEgTr$BbivS30g7Rk#nMv6)zW;vwPY81rQ!o2Ic8F0`!J zB+*ED9eP)^SS;cH4fYs{p#IYRGR-)tYQ1a`#aM-6-+wEk2FChaNVkecVnvFU%J^@& z=xzMT!+Cok)w|W`;G7K`t_?Y^?G_SBs7^)h=chsu)I@io(@Hj#qk*q^APiGZX2w-| zB*XkIwe4M1@I1V{u0S>BV(Cq{`@xDqYuqpv;{Jj~ywe*udoG|uP2{nwo-yK5Ckqv_ zGgi=V4wSjXnY9#Sh1Mbq764ox23V;21pG%}m>^0^Rv@+O#S2fS24D%3(lvh&FfMa& zT0sX0F92Ov&;jmc9fhdd^vMrR$hWThtpe}dxjx7<%46BUw6B!>9SaB=G7uMwc3;9e zg?v)tgyalF)j;EQMt^Izk|2V{P<iC&@D`YEk}Ul@Hvhq-Aic%j1*9kR+HV^PdBT~r zSng;5=Fpd2JP6tHK$?rrb7kEPnlpo>YXdMKz*}_gPrsp~+@S{wG6n~YkZyE%;7sE1 zg%-S<CqIx599oq0t-yzEBdY-Z;3&7k9LhZm0019xdKF8d{>~!-^~NKP#J6sf`JLmB zuFfdU)G@{HI%map=eM%|1C#_OuchU)dhJVvMJ4iQ_OaQxpVx1b_pkn^gAZGRZJUBO z8lU!6&On|#)t|-o$Hm*slUqvdlB<x4=jKh6m*up8$m+Hi-f`dzXpC!gdCfJswG_ek z;q6k-ujNOEjSTa?Fui|Cw+1|RhJ>F(t-jZTSw@+=%XuD5*l^#vvUB5f?|>5tgbgox zMG*!^4#6Y$fF`J>@ev8s4FIpWz6K30sG2I;ODZ3*o%&tLva=aAS43?4emJF7oux(} zAFDNkM2FqpWr+iX0xxminKKdle@=1m7|y<ep;DLt8X>BdL9xQCNe1FP!6#ycI0+aP zGX)?a0d}kl<fejH7gtyw;qqvZiC|RZFzML~9u5dIv%_@DX8Mv2&_bZM+a+j-BQeyX z4%+FvnC}7i`{=Y#<o%9%J*)q0xMiqhr7J?x$hV!i5=mbt<Am&|c{FF7?`xxZu3Ei3 zGejQ@<&6{m<m7*Y$awVv0~K~=CKC|XZ}(k*z_g|$#gD5u{kIg1&u`k_|E2Yje%5*` zkQ@nikGlwosgR7{tr=b`5rZ3$X&gX6=vo}eNeAF(W-?>-EiY`vvkLp?0R!#`)l*)} zPPEWlLpESN*vN-wino*bVRVXIiuh~pbe)u85OmxdYSIVPHLuVlrisC286b-78~A^} z7oKj$JarxWH0gIqS&BlX;>xZs47T*6Ic@|hUaf26S$Cvxi#b~htiZTa{>eY5bs{$| zRGUa`J3D5o0M~7y1*YCIkn#{Qg-F2iJLK}rw1495x9tt>leYS4>Y~;SH7<|^IpZ|x z2|6;ZkBxplr6?*Jp9B9H3<*FTXLEoE{#oa*LyCc~qb0()j@|35rYxpNVJDZSt@{Q+ z1qJ>FgqD<-Vor|&zGYZ3DMRI>jPpnTOz^(zy%?&gaKFe6@+;Me7okqV01S|kKpr-R z1{pL*20GM4^1h|##zZQsm>#J1F9C-!5k0e$VeVBq5q<f!ZArXTXEe~1vdoi(dB+lY zTy_<H6a<ihwR_wJ*~flG4!lod2(%v03-zwBfyY!y-h1(ZFjYkLe23~uBBnp;t-rLg z`GXIEtFsTf_EG3h406A&ePv;H=eLwSFyiyD3NESK!())8{R_Qz*@K|Xni7aVO#BP% zsr+Z@+5VSMeWU98P)p)ub2onICX{3V7*1diWhG^R`p)&P%#yAqQ-09wr|TkjuN0;K zz^frTN%k_3uchu*=YI~j`zPK~R#v`=Y(L|5etvpv_>_F>GwSi_+T%Q9^)}<*vNyIZ zf3h702yz5rRQ8hkN2Mc3aHWQTHrZR~5Xewd0HN_Cj~BtY*4n=sS#BCr9Bl&B8teJ{ zh5~Mz-AEE<e{`wd1Ns%DP68!E;&8WnF_T)C8vn>I0%AJbq#Bpkdc?)nS?=b&AjUxj z0jAkS4yLgy<m;%enfH&Gf2@|n3p#p`9i7Swq;=l}QQv{D6b!~Xl!~$%egRRQU>Q?( zT5yTM(AMSAf}D`#8`@ndT}~SSK#Lm9V`f+fx?6<dX1<xU0?AbS^jwSGGCHSH6(HXp zR1Luz7vR`$!I;9_)SCN%5BoBsn7&50^`VeoVr|gep8)8~s*L^`ctzqy8O&U04%$?U zg_|^EPDKGXY~7yA4-ir3-%>XusZ~8R*GL}H;ThDEn?wJzTDs7X(4tTl0uSuTca_VH zP9&I}V)n3r_+`rn=d*$As$G*2#P5Vx4AE1m2}5AQA?=qc0}dNY!BRtI;{;E><S2@F zap9>=N0jvv*K2HehzAItfL!nO$=#K`e^LfBah6i0vTqFHK(Xcx;AENn>%RE0i4EDq zSXxuO1TZq+0t*0zy~6oOLl%s7Ot{hOI=f-XRl2f%!`<NbwW3I!ACAbI*y1FJ+ZCTe zB>YP_yT1EgR>prItyxxvX?sW7)@M(mxHuTP^Rznq5Yv8R3sO`7d=`Tle9=be{iA*< zEZ=mK0H_sfNzQ$or5Vs;PnYHcCNi1$wcp4mjl~h9a5LM@!MQt8HGNH(70_;lnpVjI zwQUUSaER9$j0v9UfRrRF6fiQR75p={mi66DBp_`RAA|}4#V&}Cw&?Ay{JAGUzIW<F zd4K^BT!4LmDPS56WW?ZIvZ$L@I<>n2&!VZF3u_weSC~H)_UxG&He<R#3%u$14TysC z%YonnxO?*cQGI8HDIib<4GUJxTbx0WFJc2>Ha`Rx7V#g~0+SPjj)Wat#q;sV843h% zlptXtJ&hW^4p<M9=UMA!0sRUpSPwkdyg-y=vkA;<vIrhQeFm2eko*AqzX4BYgw{_< z`WvD=B4COGbdX?5jhl@RI!2J4#8D#?h?i(vP-~`}=}1}{=gJ%^2UscyQ*~TYvdnf8 zBPEaRQ!uEtzymQcxq(0~1pIj*>g^vfD}wvGiG(BazDVMx+svYcCJBShJPAy!abDz^ z@S?q*Cs-fspQb1O|Lst1Vt;8x|I*@1cLMF^Q^TiS<AHx2_<6(g)#`TEL)@poS6Fqo zueU*JN7qL{Rc)C14$E;@8<i<LA#c}9GGSa_MpWr-;sDs2AXt$H%*W-Wr$#1fhdy6r z0MHy{4Z_s=E`W^Dt@OOr;SOYP{bCG>R1Vwh<$mx7!Ms_eDp)_i=qJ5z{p07{z2xRN zUfPnERB9M?_7$8}PysA{BJZ*$62K}$>EM|$25njm#f0!-4D3K&7l`H9E%|Gr0L5`< z`9P0`O2T7mTal6qV+^3Bt}`EJ0$VO`Zlj!_NBq;+u<c4S(&8@xa`or03%tUR!2axF z6AYGF<gE32W7ZOo>Kdf^6>`?YlYc2wpbb=}F-I3O-;ofu2DzwqjsMcZfxqpw)JUuA zFYohyYg0+3$~QCvhcu^EnA}rHI!67!H$g_}?>rrFaza?jODCtFkfn-IG<Q}Y$LfOu zWWI@8(l4jkrIJ|X@=KT=)tb=}WEMwia95mZJ$Fkt1VDPA^aPd0@PSJ2|3iZN(C21J zjvMiL_f2~sQF}KvZ+51RVp69-0`5L()dE7}Yvf8u`1k2KlVClhQCcSW61SUVw{;$O z3;)`8SC%Xl@$0jFFXn70O5t_$OHcI>t!-JjF`m3gpGxD`uYSO6zMNho7g2!gAfTD6 zh(u{1_{0XqGbwkgl9&s;TTdhT?Yo-({6zKO91IN!pKk861<4t8Ln(`@HNxX$=&*&x zi!l9lmE12j9ZPwL*=&$u>S^Do;~XAO(97cRs0h*|=fMMzCU~}FQ}-D-6)v_g@eXqD ztLY-gt`;x>a8hQDv+w7GbUsD9TN2y0l)Y)>Ol=Di7{+_-w-ve1_@{blu-w)`sGmi5 zwtoT|*&v$!sq{P-t|{=6fmdi}3&g_K`;Lx$0~fW6p{L7K0ce{yy<Ft6ZRiA(AWZ#V zewNzD5vel1=^>MNZ=j$V@8TFI<6)gD{IJ=H{bKz)LR8kOF9D9}1!IXmNIe<<wp<x0 zI2DP7#3Y|ZnQ4m&IIC{f<EN+JQlRd{_T76K>yT$^RaSQLC3Km!c6ojFhiAv|ZdtEK zeaGcN0WC=BCv~DH7fb?)$L_3$nrwDS6G+4vs32|K&hVG4z2}mmXDbSlRhMZ}<u$nx z8z-kJnC};CNvE=_-@!-{VDYp-{@<xOY~LPsqn};@Y4rWd)A8?Qs)tUhKeSZ0$cy%Y z#P%X)D|(SPGhRI<B_%4iZmb90<-5{cYYP`Rz*PC83&3)37Q@}DVrPp1^-dqwmm0~S zZ+z@2<0VeReCek$1z_voU-a>;Q!#CVpZa9&WB34KDKP`Q{lgKB9KyAZNRv|^JHw2e zL|Xxr0S3YVn#jZ@x?{*OEO0dM4VrX#y(EBD-O7PAu|NY2{iNlWOVj>ITH-;@C2C5L zJUN`^&v96AydHZQTf#843v7?zd1p%%a%L_n2fh?YwU%2_T<X?|yp|H=#nLaUy5hBK zb^lhi=xq7(!lF<WBcX{uau)lu+};<+zb1z<rFU_WLTq5dZQ%W*jXxDh!)5v}1Ti6P zvNk^NE?|M0K^XJ?F$?Q}BD04JKn%taI*BYt;U8VG{m>O|y=YhwBF`6~%M*77lVTsA z_Jo7sThT9kBYu)P*-~?03r??ES;GO2wqK0HcGo6^6$Z)-=p!H>d<kgkw<|K9g@RWn zXnlpy77G^*VNxa5&Y5A<2w)C6Urv*X9wG`7e92xoLHPdK;-(_9uL#>z1F%BwHaXM^ z-S*Ll>n9R7=Oq}{k-8_CpQ4y0(eFM;j4Q(wc6qnNcgolC_>A@iR=ieNeNotlD4UkQ zZcBwFNl}TmSoQb)ub)qvgCCv;K8T~pY`Ss3U3ce{35Uris((r3=A+1rSNC?!Y}zie zWAht$?H0CV*L8n>sap9q2*x5{e6$3TL92`0vpFq-x=90WT71lCF_hmQxdi-2O+=6c zNll;udmj^D*mC0po7HvEVs`-!ytx|io&6sNyAU-<*?@b8Y_eO5`FVRi;`BNKOYGwE z?gGXGzHu1yasp;l0gR?C=1?#EocxQ<J0BT$aUE?Oo)FaK33}5H_`Q)w=TP5Y69gf% z=`bw9z^wHRLKt**S7{850hkFGjjm%!Kw>pEl5K62e)l`>Pb$-2GSRo)Hz5{221NA% z(lmiPDI{jTg-(>kEO@QdL`v3Jp$YQ<5ouj}$Mv4XqktDAZ5dkQ==R<1#4N=QA_nE+ zVL?E+qb(UGunnKyt>q@94F#8%f=nh<H7fTgU!O-NUuT#>-g+P|o4bquyu_gfc$%T9 zE6?iHzkWmQN~haGf7=hsMs_j@OY8sdqlW&2D>_H`c5q-Tkb&9oVb$+GM8s_7077*? z*YA0;JH9A7wQc{=7P6s#fTN<UjM@HF|KXnJKceeCql#g?48PAzm^H=vZS`Z$Iv<58 zO9~sWo>Xf|tWFjm?4)uV_OL%DRBu(6^`*j{33(A_c|>(pC_AOfIE=D`BK>7mn<}M2 zpN$XlB}@oE`BRA)6Lk24P?y>4SYEhQ10H1H#Wp&3`N|72C-Ok{I4fdr6UpDPz-1X0 z=9zHSP8%0+h*V*{E|nNq@W9RuoZDak9Yw3H#39xb>RdCBb{Y1R+rncV_LtICzQm=L zh&+8MF$QFBI0TX;5u<fOx{d#+-b5qEA3BPfb5yP`h)aWnVGcpUjp<wPL=_gZuTrIm zPdk}Lq~=rrgdS*C${TTs_`;_}1PyySWEliFR=x6RLEJ}nwxxRL(&V-_Jp;-TZlize zn`u7Y;6DUScpz&(M1JNGLKjpJMerRQpOup7lE{pC+20Q(=>*0iusaFNC`V5PFM0*{ z04=N{_rt(3EY|Zc!B>6{@BF_-qF`4~e)c0WW!BUR{N@zRG4mJofO`Cf8=N=6tWLj5 z2MNPuCxo+`W_mCxa`cwUjkoUH{^*~tMPNTG@Zj-@Y$arI?zn4}?LdrcpHyuTIZ)|F zHwGzG@6Y<Z-iOU?=*@XH19<1w(IJbRPcFi3n-8n>co=m$nye_0Drb*M*aT#P2@yTN zx>?f$UP{tJ1DMb9e3lHFJE^+&UJAeA18WTd=K67tT&?*J=nT<Ah!jgxC=Zkx9egUK z?u&c82B%zK8%i*cCe};tb=x;uck8f<qo{1*ky3#$n|^vLxf@c0rFSdFw%N{nVpBjP zTj35OdHUWkclN9_MrgDGfiZ2}HXX`aSDLQiy}m6W`?uNq0;Fl+xS&1@FrWoofTVr7 zAnHy)9OGlk6xJOLz?8koGHL1Y65phc)WOFwI5}D}n7Ys!T-erRrH%~IELY4To7~hb zD;xvrEX={kJ+)^1Fh(Ls0J513v^&fQpxAY@fXoE;Gfg3w_bnUX7>G^I+RC-=&p5Az zVjWG)pM_<G6m;0t)-OBzQ7-@;nHCIP2Pdr^%&dZQ!*qVk8pWB62L=!ou_KwFe>1s# zuDRY`ueLz=c>MvxyRb<);|z28`bv?jNIZKShUsOF3AP&T26lw;7vhi?ksD*K5e!VP z!Wf)xrhfC2<{rTyPasNvLwtdNlX{$gKWZfc(K#|LyL_zDp0-bQu>1ZQ=H55c>zKdJ z<ERLFqHpy)bKe$XfkzM(fH~X0oTGHiEkB2K*IqQis7;_-rdgz(C!fHiRs7#S>}iN0 zAtBk>+b=)webQW9Tm+tldr`x^+_4ef)s~1F^3+r$=Z<_zW^caPi{$+D8mom1rHt~_ zv2P?4{AN%*ayS-d+@TI`N937HnDFnktu>yM?~P_JvBPp%xzyFz+3PHR{AsfZN;{&Q z$?N+0=W2)nDPK<5U&v%n;G8;^*)#)&E^63Ddpa<6Ku)?d<GgGOoX#dy{iB3ImYmE> zcAZ-oV!7=@REW}$LXap+tSl8`fJ4EYYl{)91!2HtIQ+S};29E?I<AGcPkrocZQEF> z6vIxQh!OP*F(hC7b2RG;oBoiQC-Xk7KkcNs$^N?W$(o(q>foy&$-tF?DkUc|ncL*q zjOuQV<$mf=3%PY}dx+Kh$-DqN5;lX{FzLNj1qdxxR3ijpZir<w$d8c{6F535t+-Fe z_l)_AP>+}jr^M&?=KFb>{Lek(@mveP1efF)=O=t;E(Qb*lzth_Z?E`_uo-U;8w@+l z_wk>E+73jx9eF#_N1gXV{ZD99ok!VP_if0%N2IaDCwscbKkk~0I%DzY1y-MaQ~!GE zb1Ytfk8F!m10xxExuz+Xj>@VAhaVXbt|@;a&mx~}L0O!LsB=E5%bRg)|4IQ%v}URQ z26a8VsLoFh_j9ixlu_fkMct3$-SN%{+DWR?#*m|qtwF)o4i3%Od+Rpu5O2RnffZiS zV~Q?lUsF#1n3s&b;Wlt>XJ8pqEZlKE>4h||=n^yVoME~UIVoP-{6Z(%Xw{ht#2d#! zRlrG4PV@4IPvw+E5$&MCL104fu`VHL3J;YU9R67FlaLUPCX|4Xg_&xAw=gU{KNaEC z-e+^m*0{K_Wr1o4?mI_=YnvhxR0WL@$@Wt5wZbrRlJpY|GTJI@)5P-quGf0bqXYTq zijlg>Yt7dV9w!1irv7rB`ILc;i?3PuC6Pm1-p}hWOO`qrTAI&b2~hWt_2<xG_8X#n zdYoff<nF%RGW$fk@T<Q#t#TFRX~}MoL<wT0ftB2pd@dbbq(nR)pIiMIpD?{+gLauH zW5yoR{nC1<x5=;)=OdAwh9&n_x=Sw;QvTq;&A@Jz5`S6+CpSd<GMO2DV(ztoxps|C zZKI}Zlj=n>Kb2@(@!Mg$;U0#=#G|}!<3QV$jwzcVk|O59A!c&2R~Z+qcZKbTl~33# zh>{Ox(ehL^OqF{7-xXOjQQ-fpT8b@)PgG(HjYu~y`kh%Cy9-AF-fCV`XnXoXV0X3L zI{waIt-JgvT-KgQrYoiJl*p8jxf#hxsWn|KTIU0Cc_y@NRvMR;CRdTAZ&~w!8fTPm zpb{$gyThB~IDII6JnJhyk*(DuF*YV=!i5xDA4UaV6m0m;T!y~#@6;re%K6iHJc+@6 zJ!%)H1rcA<oup+Ye3SlKsOL?oM?j=~S1*W3OjXA^b-)SVKbc4CW7v9M)%E!-YAig+ zqroAGBDlW(g=k3q-Y5510*I*wmaZBersVAIo@aFATCDyoZ68Bk5oi0V=PsP1DvwiC zp0^vJfpOSrMkS_o3BL;wR|7}T<PwKylv`WCrD9uOUe1v6xT&RCFay0yD(;|=7}X}7 zI$tT?Q1YB^yaIbO41M1q{RRIkeZ?-T_v`E$0NXZW{qv@$OBGL~_+o%NR7&ocCcd&Z zJ{mT2KH24#sZWmQ0{b=dn_q%tMBm-CqHRj{keXJsFGF?X(?c<F_z?3uvD%;c4IaHW zVdMh5HRY-H$ZV*JN@_oi&aKfw8pm&{?<aLvKSCoyzUztqL{X;+Hp5b~a14fS&1&IO zj%_zZzbKy-8^k_(gMGBUb<4;Vnp<gi)IhEDKszLyp75STB_iH$MQ{J7k(CRUR^-VS zH@!RJb>{1#NE(Bh;Bb7tInQ(I_KQ0<OKGLVla#)nM7h{9_V5y6(sE2bhb2xE@PpWB z$JnyuR^eL5gR{cP=!OmQ#5}p3xT&|8s&aJlSPKE(!X7IeKeK~-a!f4EcrN|jgfG@q zl!aw`ehLz;%?ilL+!pGF<w}jK;k6sYO=xLAIjt(}V)P?BICx%5!z2Zr8~!%r?+whH zl8&=FZXxqtuV>BZ`i{+qTF}U}Vj&$_6qb%5Yz{ROGr=ZLVOW$#3OC24iL#o(>cQ^% z>F)6hlTe)I5hg)A^olZ>6eFc78wnY?d}ho;zn(amG*82BPXu1W%-S|yc6Ee_T!ZXh z*`RBOP?h>l2*r0c=_@NFrlz=WJ-xi9{B68!6aujb+P5ax*d^&7ImnO22nSw`5zj^! zm#JgMWr5&jQtpwllYSBg%Y(adfib(ko*^8@)i>*^%U;NZ1Fqr4tqTzcdH|HrsjCE9 zyVM|`<r(JJe$pXh2-C8~@<ANAlPmKq;{Lb(e=SI`GgkN>*?#Q8%XEA$fc1O?(QYo8 z=j0AQkLvGL{(B3(z}YQQ@nvdQ@p_};y)bz!isJ9k;Qd_iq}I9(saQW3IXP!X3w09B z5cW<KJZ=miYFR_L&U%qed-3@q!b&LM<gWZ=!$oAr1$+}G5C4Pr;-cp^SJua8xvX(q z2_IED_70YYrLIV}8#B}bN9D>Qq{CDm7XAXpe)4%l!ok*CQq&=WGgE)>F2SGax_!@j zFT!5=Miknp3J?gO_$Ha^DDkr^HABC;t&D65YGDvIx&B}x?+4QP{N9eK*BLo^J`YE| zK0#W-8=k-vbV%GMrw1J!ep~w|U5XHSiSuhiNq$ex_YbM)5hs#MQ}Ck%t$8j=8^m)0 zkQf)Hl}(8%)Q)0GCy#nLjnTbA5_pZ=g8o0sv@n}5Wb#3szT4H>$>p!BRCrkyWMK_0 z-J@oKTswC6f<oCbr8`TjJ(b*^W!%|J8S@p6?7Q~r6hGmm?++`!KAC(u5)&(5lFhxJ z9~yFCeKi<ygCDC0s|r=<&;_NfNH7+(H2%Vj{DhKrgyt|fyUVZEH5dE#>~u^GWNf>( zsL-Gu4@6bvJqnaZT$7{<=n=oIf2;JTb}Hi9s=rZSMH;2MCtool<VqNl?HEftDTXpM zxQqN{(i3|l`#wJk6LTFR{2q$eM;%<3%MhUy*%ZE8`1+G@TVngeZ<QbS+viD!-y@qt zGW5I$1b$bRQ2dz_lwG!qvYrvP8{x!KJ?|3TKu+qRbQM5)gyklqbVYR{=@FosJfI08 zRto5bh)w34o)d0utxWF?ORAd*i&3Zuq1*GeD$J0I8Y1(NdWJFuA{9Hq6zkp3!iB<o zsu@0!A-%t35i5!R!}xQKYH5dFr!|V}mb6b!x!;?Zu4($E&#a@uh);a^Wq&OzS3VC) z%q*Tes_3Z+4n|r~C$jB=AihGutMrgqv=AO@)W)K1J0inW=QdY*RuTRC&b=1LGR7Q} z<M%59ZNZEUD>9!qGVL;=QaS5TASsht8k`05EQ_*B6LP{Rqf42jHOBQMf#(2^Po&)S zBJ%EWJL9>}m*eVamAW~QKIRUZ98ULm6|K~Dwi{ZcP^mnjLCe6iWiY;3Gg)K6^b<UU zsC3Rszn9|rqr?lO8fh?oCOz*3ao3RonbS+uZ)A=Ao5HI)o%E7O%=9JKRCTp4h!5z9 z!V@Z6>B+n*eU_*C3<yp*t09;}3^A{4LLBzPdr`^8VZw49DaClFBf$QsKQf*pWy&8{ z;ljM{Vopj`JAx+Tqdzjo+T4@#BhT_M!Cv`oNIIKWPY$|aY1D+AJbqrB>-39oIvjeU zuLKM;RKMSbMv8J`1n0k1QSqteiVchWc!u#Da=$<Id>==3aUZaE*x+{(^02DC*LfMt z+p_+oqGeL|pY8SDq!JcFsrG*riMzSWFvOBRV!xwVzeu9?o8DTzvU?Rj)ylhngjCC} zG@I9$eR0P={K4lArVh5Y=RufKrW4fkrsV7*CmMklVrEUWqT8?mlrBLcf7IvmkROBM zVD`MA_yQ;zbcvaiE+5)P&k9v6ePwpK5K`YM(I}KhdCajbg5S^}?a)z|XYT7=5;aY1 zN+jrD2|vS-IxEwmdzkmPNNPvVzgd|2al)dhE8imd!5Vrom8|VKGB%TVT$Mk}$F79= zivc5Ld=iiJ{b<Vj3~)KVUSU;oau%IaeQh7Kl&fS}@!$NQ9=$5|j8?GV?RjT8WYpPZ zgIcg#jG~m{RCGA;jpS&Ix>>`0j%C3Bhsse%VB>w&m+t=XD5Xdj>1ZY4wXeJ1YI>O< zDO`0ZGbn-n32S}JEWSTJXm}AF_|3mqTQCm^9%xc6cT}lwdy&Y~!`Pqmqa>el;{|c1 zzLNe3@nU>aq=Z!Ed!^{zG(@YvTIEsKi7%VzcMO=C$;0pdP*dJ4n5SizNrtK;CL@Iy z(ZZAs-<1#AZcya2uKTR$H-A;>LsEcgb$oTDl+iq_+JzGqd-A->wzgorETg#7sExrf z^8J<58<w8VHRstPY%!Qzi@kL-a__Yw^Iaw_%CB!@JfafwqW{`M9?zW)bG>Mfc3=(2 zski61kd4b81-e{me49cbe>=vf-}iw1y+I_{6UFiX@+#8!gW8P+%bFej?d2=1)<mbC zkvr#mLzcJZK_NAIHP?9sw=*ZVlJz;T;EimC{_0_%%Q2C}8Z_t`yD=ICy(lFG3lizD zgb-V{;N>sRtbpnu>?l({55kvDI7f@TZeYWA+O>5Uh*+*}eej`3K^(!hT~z0aQjDY3 z*fDqQ;aJ|u^vO7?mQ)x`$|x~}Y*pHUE>lM;q;@L)vyDmmOOKUa1A#%K`TPO~1tc4m zi~RCp9Il;fdXLni$h|$3HL#eZvS&5X6zJq>OjU2%z{o)@VNgbxSe}ZF(ybP{HCk$E z=pC|EOd5le&0&{hNX1WHPKK+n&Yd=HvPWp7hG!QlFw^DOwmTkALfDyjticxvf0r-L zW$?S>nqI}eT1Zq7D&Kw)fJ-j&OBlncFW2!Yzj_V4Xh+onJ=6hjnm+8~D^GqS!Bt@P zT{;==<4%Zvr7YbUW5bLTPM(6u!xygc&LsV0VTRg|A2+dk0;`8(R3?oo^{wMHp)Q@y zTcpE8dr~l8-2I;Lo6m8L&Hv^3RM&9-+fx-mTU5mBWu=}ptj>R};s5wS<?G7BHZL1> zNB>`!f1|W-zU=E>4Bn-Vw3UnedlfHL;SHSVwdR9zZ`DG*Jz5=H1GA*B1fX}uzQf&N zW$?i9*h!m`9<}7|;2Si&Wq^}mR?wab)Ph(-%@Fg~H$|r-q!Q5;1C)e2_*Spy<6WQ= zGIpds7rV-Pt1=Yt<#$*&#<-o3Y1CMkjcL>F%0Y?KDUEF!=vIYff7tJ-ri)qmoFLfS zb3?2jWMQ%&VJE*j1COpfY&h&)vkB(*NNZV13-WlSCqF-gwOrooUpzq?he=9aP(>Ql z;QF^3qq?(_Cx0~J#w2&wy9TC`=kO_-@dcs(hFJA^3#CZD^5|Ep;I6%hI+(DhF(sKN z9a$q5N~;*>b<=ak?4X#h0<yb75_w$)22*qOw>%bFkzqlg{ipUnNWD1Oai7o5&3C;F zB%4rZT>EiQ_?qkBUa^2Dn?dMXm8XXR-LS<j%`k3###by^3vryKFtaq8z-R#kIFo6+ zLRc1l_?IrJF=yYc%r&4ij4^HS)lzrFnsgduE;J$ra2vA8m8`4$@31mTDg<trl^^%W zIf!p{mnMvk6(|&i3Jt_YU;U+zkoO|y|J_2ytt7-got*}WYQ?L2*A3YpbNKkG1i~8m z@K<`*iU2O=-bibqY>1-J=`h>6)xBwTx~Y<dlp}Q`cJB8{y0J>?&8M=TOGA1U;thC- zX$FX8qqj$Hm@ig}it&j9i0{o>=XMgVm2cTj9%(R#5KE}lJ;1%gp<or%5rp;)?tc3% z{~OfBKDoZWfbmpjS@SUbsOu3Gb`Ko2(Cm?n{E~d?`q`f)z7Y*S82(zc)MCcepjl^z zeu*ioGIW)b9!(gBy|;)HJXb=@?<*!{%NAWvRZZfbWn2V1>n2oI;f``5b$GBWx>N** z0+h4tA`Wgy#CcX8nsjt`HCWLMxQGE8%QbHr-z=gUR)vsH`sz8qWkyelbVQafIL5O- z%-$cq-C`j>313;$BwUK2GAr2q7811)mA--Pnh;G_F_<2F%F!`{ay66~t>(dj*_le| zBCtYBNN=%g*rr+fO>l(0v5$+0qy9A{#f8<lw|VGs8tr9UxeVA{Vw9Ya1)yJ@Vm(I6 z>1uGQUa74MKpMcGeB2np^?gk~2@|iqyjmi3uOG)~dW4Om!Vrm5;}zBygzHd<z8Zxd zQr2W6Jv}<5vIv8*W+B_w-NaU*-$!ZNT$#=AB*en(c7=^@Nzz;MZcgj-^#2WaUC50S z`E(KqF^m3N*ArH;BKI|-X&&wO%S#`3GOn{Os23I%Hky9>vZ{DZ#2t$kO~@4KJ2VAV zDUmG3OA&Tvq`Y(ly@UG@&x--mFW$D~8xq$;+Kw?^j8k2o^Ma^rQk9kq3i=i8zPiA@ zKCISZ$DxO#;wKG{RT8F4KroAQ*5pZ476>{~G;noJRK`K6i6|20#+aE7Wm&d*j~k^J z&~{c{6eGvaiGi3unr*|$^V%Y`6{4()my}@yC!;aSk3)qU9;+p6)aNp4H~iU#qag-q zXr2&s+Ms|j_!d~xpmGv9aSD7d=tDMebd!r6Gfw{XMR-$uTbuhkwM%Inr~%*&nChkG zsr`|+U0R4z#m=38R2udw>D#8KtJF4kzgt#z8Am<JCs9#3mB=Q66$?qMl=;wMoBD9p z897wOcavtyQZiEkC2WNBO&TpO?q4UsywIn0#)>*L;3bpW!GZGfhhv+d)0=(JdexMN z03b<i%Azg(M1B6Ue`W>_n@M*ZPd&y3yV-Mg>RU`14oY_-rDx%`7-D6ser-`0IW_rC zxRJl&*M^pTj-H)+5s6vEq#dDiD(kX`bNP?FJDwY#64!4n;Wv;M%QvA_9&w2lq4#y6 zPspY$=)vEAczlVnq;%X4LaNQ{oW{fA+ewLjsVq?djb;9+WAkx`UG7lOB=VBolMk*; zC_Mp}BelbBJ4xs6)%zst_HyY}XaPlft&26p@hBLneCBQk{uE&qQi9dT{rvq1i5)pa zx>CP>FAdR<pBig)%KI-yKI`@X06!P9`x_nGqInzIL|w*zHs1_`HO0V#fhoV5upa_J z29vd=8SpcSBN{@)QHF-SLN=A>*TMFi5;+gxNn#_M_kOeS(O-@WUkmeF{@neGb<2^@ zvp#kcwTkc}QmX0D&!L!KSlCi4lAk-0J~?Y4P&VEm%?_+Nq_vLPIWGIFUpz<_aZ9hS zh6r(G^hbC1IEt7PeRJ(0oASPmO9is=;KA3Yn|=czWDngRWf$od70F>I>Y00kakC1$ zxM0@ZD!HVyK~hOVfp`Q*8j+j=AQ*V~jtrs3-E#Kt?xJqda39OgZ7j)`U0<#O(<f~K zw?&^e_nIf)szL#={-@=`LJ~qS0)qZB&8s8f%r8`NCVg=B(dxB9|30Ucw6f20=`iSB zmipph-+$PH1@WMMCVGEZb4v1Sr_%Ap*Z=ArA_Yv1b+Ol>1WgV&9+e?j>+i+oqW&LU z^#9(0(_My$i=(%8{w?i0MfFyrouRhFp~lM@{o8}~r-OSHqkWuc&lhYy>u4WGT{643 zx3?b|!4q~nAK?X~%*;h-eX5gvOMs+f(P3=p7tn!fwx}?LkA1e0mF{#O$G{wk4^z^e zHUndD4+9txZSV6(l-F}PWOyvF1^8VG606EREYc2x9eO6@cyeKN=)Fr3`AEWI-)zFu zn9i~J8r1g0gaUNhQUj}KkQ^u7v_D5A%}Y$!KQnlkkA&(a9Q(H}R#+(wi}cVafQ#W1 zhM3q*jAb#&S$xJkk5ZJEw2;as`>WY<GP{lszADcbwMTnA$P32@Le~F?Yde;+EO{2a zs#Fe4R>LZeKh>yXubo2wEQuzmql67x47ymUL>P4Y$f#6xKCEw%=P`reYIW(rh5-Ou z#vDoIw<6FvfkD&x(<qaj+(4ItcayXXecd%~koP|iS-qX~p~`gf^%wq{_@F$HcAL(d z|J<$Asn=E0&~vVLMa&wUh4%~-Dox<3&k=c%^oL*^)-9##!@^20R2{JoUYkm7-}{40 zLCVk2Dmi`}3MXcP4U7OX{@dV`kfgYxkc?6B)VtNlrX?3>#EG(!S*YX*^qtoLN>WDo z%tu){M;})1-#*dB*p1pF?L1$<zY?;upMt9;SP>`f_xs4oEc1p+m^lzBN9_-_UCEwV z_%#-r<Q$#9US1c^?WIQQP_$)tyC08?dEO`GlA(hU$@HpN6XrK3l&3Wwe$*KJ*YGHC zH<@$zkrwTC<LX@QUom|(te|F8_g_u5qQTYPc`g)2J9T-WmvAWUEr*bKbu?2}6M3m{ z9b_z8I7-Rn{3z(NllFE0>JXaE!hUnjOMpPrxY>{+685T*<}W;%b3v6d=x5KKe8MwH z@xo)PlqAh7s8Js?;U|$>Gc`8GeijF<d(Iu}#t+-|^xXJTC6fkCMkvXzPQ_$v)H|jo zrcwuCJl42@3j@=c598}#?;$N#LPJX)2^0kum>mG#hMi)rPQ32R?~Ad=M(bXZo{~^G zghOT%D<TXI{%e@uJyzx=ax(tyoh<I@y^ki(gUDQ9erio||B&)N?PLd^9L{J`Z{27R z=BD(ga%{}co1h5chV?iLECB3}1NB%FiH}hijiW#1oOPurl0(-07p6?UxJqQV_j~JK z{22UJP+{V0cx|5tk7FN!j+_v|82TU$Q!!~dO9<G7hWpH^;qC(dP;TT-^p_T!{T~Cd zB37N*rSQo|tVh4B*4Ebh-&d8z^LCt+(I?NY|4B+s6x3#(r|<Z532L8|j9d4ltv*;{ zVqrC1E!f)dq_rGcuu0mE&{CcuJG7j=&Aj-*C`?zV=T<6GNm*)ksdMt+L$fX}tr7{! z4Co?ciLoexdie$iy!x%y@m+|rD}k<HR<iUwie<;-JzjYPR^oUY+HO<v+aEb=67%}3 z9&CK?y`ld|8on@bXE3K$+R+4=0r=H0L^95~NOyhToRP0nTN2-4@UxAxTZ_UmchXk} z$4+VLg$Z`f*Dz&kFs<q*F6LxIzNGW<P2sXqa+b6|Dogh{l2D)L+c^aQ#w2_z@CJ%Y zo}M}lL(6;VkM)O)k1^4qRu-Ik^dsjbAw6wcbq<59sibkSr~~5#^?iOXz`bcnal^mR zPF^f0VansXka5+Ch~Pgsfn6v~ElX~WmuhPfY|^jOa|#%V8DFI{;L;=I6TB?Zbx$ro zpynde_)eTGz`~zfwjE*r#f7F(tp;Y)XVq+*+bI<4@QXiS?4;3=kuqLnw25NL51?*L zF6wIF9j+?wi+{x(3`%9uE@xfXD$ff;$hvyf7tHazFlLezQqik^<H1W&?-h?Y`St9r zt_*p{5K^@Kz<0ZHS`&hTGG-?a>7#I`@sy3E2e1X2E1ju3EA#@yAFWe*C?`g_+Dl)3 z*+Xww5GRj(cu?DQU_mt~2umKWT4w0tUwz(}h(Co3Mua)s4~r%|j(*^#_TjFIr@UgQ zT8+{hd2ZYFhY-dRFP2ghRk)3QXxH@nv>A$K+&0+mJAN`Av!bQ<GG!qURNJ_UaWyW^ zl6hX1ROiuPN@sJ@DT~omQce#i{~f%(8Tf}0YyS?8nw7m~KC9sTzO%yih_Ti;i+`HU z(|%Sf)zeU62z%gEu@f`0%Od8tx!SO;WrUQq*}7HOAq?nFsB>BJAR_PhpO}thymw%e zYziJ`mj%3I7_*%8`e$?9?O;mBs$JhPx3ZG_2t|2?5%BTPSV^lATtX$seRxBNskv=w zF%DjubJ1>fv5f5coT?-MCBEBvSrscKaSX9QHox0BX|)XXR)@Gfxq$t0DlmHVs2HW` zd^S`1;c7`*mvQbZ;*f2OXw(xQW6t-IeDv<Mz>mAa%dE`?6esF5Vcq_TpNlk-_|4*& zk!=1b$02`uD&4~|i<{7F6KrBYv*e+{wQTYYJMDM<UE8Y9=i0$g-NQHN5NgDlL5B(R z5$8T_K2+DMpLOkL#t<STMI(u1)p1!r@r1Tx&)CzNqQvS+Yr5(#X7{sz_M87Evo37% zL*TSm&oi%86X~P9mp0c#RuN7rki0XoxQ;qAEB=#yzH=QfYgoCHLn=YLy!Rc=6dp2R ze>ue2yv$mll4WUcfAmx%Qpi+!2V`26UPCMmrvpR}<D5?ouXo~K(X@D1W^;0{1o3#_ z5Qe#Z8Q!Bm#paX8m$3+lJEJ~HHR^=y9plE=PooDRIpC#XBZca3&<gNMU>UD+Cn}Hh zM&5od!b9nvK4V4vH2E~Z-N-tBh0}n%;M_Od>lzS%XVPxx;?~lAUt_lP&EWlNt%RM$ zmrf7y^8K@kJU2}qiHItC57JFKx0K0vF2s6FPsZ77n=y?z7)7>E<<W|96LNh#77Eu+ z$fU5N_{v;W9B-&OFU#%XFoa*?wqad;w;P`{a}VdCkF|}Xu;j6{(}>y=(ICpLBA=B3 z2&n>+0W<neIKhJR+dX_+ufX1)>Isz!h49#DSZeZ&d#_eC-tqM+&wpOa840*Q(w(~I zsLYmu5Yp?s4LM9>&>&;mOb0f7mOW~_V;b#C<e)riu0EbT*Vv|TekL+SyRJR+=&sjy z`N~T8BHMExk&bC*w9phJM^l!q4AuEogc=inw(Y##@V*vK2WwcjRV8$bCf0-VoK?N( zWn^mrgzdXpx8Z_xZED*PH=mquG*f79Hd39<hFM_T+;f|M4j&dIcc8sq?Hbz!2T$mC zV!7I)JvF0CyYQ&t%1ZMIA3fUx?O7%E>0?FA)j=(0x@eyQqn&Us%SM20k@2<A`J!!v z@e159T)km;i%&;Gx(^-~85kw(iUDacm@&^G00sQ!=$3Glw66fP&u{*Z?o<KtW0D0- zQb>O1QeS!mR%noEgI#Xrk80$X<73}kqGWtQXT0;3l9w*2k!x|o+(*{X{6Yynz#~au zt@V7f^Z*AVg@e0piysdK4^iJW5!)C|!4gu$JkWg!I`;@XYg2wOr(Gn=#%EXX<+J+k z9K6TwFQ!!E3+i&VP90h?58EvEOj@oEz)h^bsBD+2%DbnA6Q(ENM-1z!GISr)1u&ju zTyXiH_^5RCIDVORFG92c$uW)GwI$c|*E4fd@X)S)OU5oi{&UCSXvOZI-2vx@Xp-yr zW@**sGP;Zah~4Kj&Ri^dmFW8$$pSCjL|VzZ<aPpuG8{MLq+@yFag6LhoTH<d^j_DD zY&_N_pVia^3Tl9}iJk&6I(s#QfhW6wVc1Se>CP6p(ua-ccquV84jB|U<VAIXx)*>4 zvHW>>N)g>S@@XYN`T1c;boUx*GUd~wFxB5r`guq?2-<J{Q#c|5f1%p34<Ijw%)jvk z%vql**`~3sgs3bR;DtXe+EYCQwf`3quA!ykyRY$F0at<*^1qid>Z!hmFm;bI;Sk?o z^Ki;yD8PX?)v|(zUuE>rsOnm>=2O><Melx?^Oypic*;90{seaXPK-Lo0*jgM=K9o_ zrcf=&Mn^4iT72rTq-!2h6=w2We3eoo!^&m3TtjG52H1qBq=S3mm4Yl*xz+gepl=QT z&{cya9TPes^QAdCTsmoG0vztXm^vT&ajs%`e+@Sh?2=6ybU9LJ-P%(HB;=pa8dji= zUa!~1HQGxj)wrAid2+=rGneNw^U?{qJj^3`A+W7zQqu)LN(vv{jv@$&vx*&5bD|-F zUocU&oP6ApK9zlv>#fzj?&B7QSl|e#Bz|v;@W`<sJ-(y$rZ|Ox3_)qZ9=<osf);71 z%&MOK4%^(2^?NK0HAj^;N-xraSL=mC5t{fdY=Wa&XOyVznQcXYal`8W?coNd|I0yo z0I*fqxd;gWq6(R{1>6AEl}<Rs6FQ^D_w5H)6<fh+NGnbJY2I^lh2Co^cMck}rL>5f zLzUC(wB8v=IjrNMk8PhaI4BiK4?bJvV!qp^wu|+YVfN=}Tt^;vKv=U8ZcHB$Uc#sG z|Gg&9g4#ZepsMunWLk#Qs7|wuz^d-24-UhWFsE03)8l&FAUgDT0M@T|;{7F_nC%bY zQpk+xYT>O})trd`c(V7?WnIhR!KXBCu||X*Z)5lLFu6t=ku}BozUe(yxa5%JMX7i| z!33C_Ljfd-^(O~b7=jr!0jSP%iUM8ScVh_}ql7DG4mjpKU^+Em*5)Ij$O+8;Kney? zqj`z7L~I?HAdT8-yS+O~GOW$mvCH|yNtox2HHpZgp@<kcr|eBPlLwQ~%)k8}#G?fx zYXgyA7QIYt6%~I~?S@t<fytHjAh*C*s7%y@D$Zcdps6~d(cRNQ#c_bO+;CAkDKk?w zY2H~?cJHAn^DA7)iGAkWi!ckrXg*F1b4TCfB>M$ecUxw+6esIcSmt}a3nk(21q}Gg z;IHP{Tm)<1?O2gC6zvryEvWN(!Dau^4mfq#lquNZGcKLbFvC<t+w|Ef?(FwqocI|k z)7SrE)?8UeiCvk49b(rQ{80xgzQ?^N9a5iqiw{qiGWnwuBTX;}W41y!5!?%GzS1}m z3bDxBRNGa`sA8~KMMa7`p#RlaTlrI>>b8Or`QyrYW`oaDXPc(z+__J(4c5hjeZ%tA z_r?F*lZ!8kauz?dx5AZViF>hE-u=B62`Dkc(o#>M4S>I_v~yIg=fj~=Pa@GsQx)iS z0PH}^V$JIva1Fb`l<lq6O0<o=U~*O-Uk99oEb%IVHK|m#U@fxnSK2hr1`dEoRN9Sc zbE&_p)Nm~v8h&PNQD8}IOZuP{og|zduogwSAkcJaLMVnh<g~n_SQYH_<rN<_TX5*S z>`mKTVycsQ>R|$l0Q4=nK_hLP*L69&>r^}^-!hF_wZ3~|$9tTZqChk0$obblWtsJx ze>=>Z+D+11gBPHAnEzGUlz9|xR9K{(R8zz{`5fuU*y{e5aAp^rpty@#kH_OA5s})W zZDevu4aNinX-6W~JBEfKOg-H@iwrH{w<zs~v}y0tB@kzA$o)SUS`J;m@<`1jMKW2u z!lvVMii`tSLOc1A06~v9pGO>ZwJKRq$<Pwr9%JVPO-H(1X!cPN$Gyc+e`#>J{AVDY zd&@wdfMDDCC{TxTl18-?ZG4MA^L$~1g<<cXE#bLa7>|^JMjsXpZ{!L<CViNBJ+CHx z$WZHK&AaR0DiWWdMxLIpUyx&ng=Cpw$-F+Ev`Hm+@}L)9G7$T1iRakJEk5i*MV8Lc z$k#PZ^M|`*vecjM@9|{s6H9t^xP3$CC6uLnQbIR89P&QVTh=Zj%L*rknc(;|^j2y1 zJV^AGL8QPBar4DbixAy-@>E2i#nT@d$mk3Hj0d)g3cKu})@U?uv14we{II^UNwc^4 zeN(+t(#n#Sbk*kVb`$8zy>7yPI=F#IBqe;FWnn4VNNjx$V$U6X9^~;$*}mHKf3fw} zQBg;Kw?7Dq5|Yy0DBX=ZAPNo$C?Vb5-O>#r2m%8L2#6rvH8^w)-Q6ieciiK1pYOfT zUBBNSxO6SW0p@egdGGz&`|xyR?@RS8>BI&9q3`|;42HGPRYtNX+IaR9%o<}2Xq{$p zu<7{@$s$diA@3*m)T=*Fh!Z%M97!J}{K(p=b@}pjv4?sl5y2sR{P`~;Q_)t)v}QM0 z)cT)g#m%p(#c7<l!w*5Tw(4@5%Eb**zWziMgShO{ZzOixV+8i^Zu0Ln??I86MeY;i zOh}F}DGT0~%udt}00BNXmER91==Q-p+j0dnlDBCZ@K^~Rv`Rh|8|VXHWe3fLV+TWO zqpXu{BP8J8py&WjRo&+V8?vJ6^Xc0J%-L;>U_*KE=j+fPCxS3JplUf&m8n&OMTTnV zbDvdZ>HJ*rb(NhFafbijzqdYk;y2FtghkCi?-kNT&^|1h?>y80KP1Zk`y1M~HM34Q z)?RPbklpEK7TeU{NK?j0l$>?FBA8{Nq)Gz3uEpVx5slK#Le7M$qCJb;Iyk;T5H%d% zXa^HY^!bNM^4>PTmYmXoCZ!D(<97vuSii+{U9;<iX{k{Y<S1(&3?=S@3<?Y=s310a zY0Ym=U9T7?FW-ARVx7}O(E8}3W_2%M0l8ib|Dxr?rzss7oU8ryiU5`Z{W_F1FC|ga zY_EciFI&m0LqX&8bUy#LnPT#^?i6Xq8<dChqi54+aMtYAp7TRT?IGfIVIXQIA!}~R z<(P4w0ZJuMlY}}dmL0aNI>h2mSU1MNKfzn-id?mRYonkIB@|^e1n`kD39LDST`cYQ z@H=UvG0`^*g5klr_S@h@x5F&nQdk!SWNKjDo86Qh=)!0fXp*3b`%Q7?heC9&PZhaI zq+;J<#27AkkS%wOgMs<${NL2@z`_+>FRR_GYR*kedQ_HmWSeRzQhP@-k?%FK&#MUT zNS2Cc|D-5)(8}YS9fE03eX)fTmXEuq^suRLymg2ltxNI@ts*Iqr1sClnkILOVQ!tw zkrel~z_9Ep0xs%$bzc(u@FOk-cq8+{O>rwBc@R5ZG40AUl$X?TQvR_y?N9D{ZMF*h z`R4luy1NUE!kQ1;B!h<Oo&4=oDdAkm7nTnFlx>uR@}qmRD`$JR)DJq~bkal;>z5{J zd9Z{jAh%g|iKW#K%w0TiCS&@PFa(aY3?Vr=tVIQc3Yz5v6Ek0&y}SZ}O!RH!Gi`RP zErJ=X>M!r$qK8XcNOq@$d49^bU`1216%wSU$PafxdD_}Xoo(mnnD^w(n2@A}MZuHP zv8k7F0ex>wx@o5PU_q_J@|*MDbTGlz<|ywLosnul2;Pi!V?Hl#>;RPlmP1Y$nE(}E z#ZbBV$KdY{_*rSp<*S-5vYfc!y{Fc%sR2QqCf`!)e=t@b3kNi!+Yr#ig9Jrw$u<^r zr}C5wI`~Un8C9Hg8)I6Q2;SQE&0Y+sZLJR5qG%9)yogcO*#vvu8bYqE26LKwE10U9 zKT1t{+0DDV#*-#ilaB2c74v%QjK1oQnCaqQ6diK{HMP*{?UK*k0i*Psghf-3G?Ceq z%-^|=$kaZ^=Y~QvrpXb|YuA~MQCVa?t<zKK@A)7|^Oh4AZ)@biKLLPS<8rm&Ug7_X zQ2*!gJSK1f3NzNA>xG#Q*YQJc>R@o(bH1Q7PI#A0@gPDDIDRi{O>Nd0xeo^gwNw)J z_tSyGNMN_Qv1%dx&Zbn&&EX+%ibXNOQY#MyFk^3VyPSMsT-tFla+pJbP3r@bs*1tO zxAu@e%kF4J)8w1-cJCwOMr%KQS?VyocC-g2(fI6;w`(arF@LiapJLn8Hu<<WzgQSe zwkyA1q$}FRXh=St*!NF0;I8k3uvt_)oQ8NTsfT0E15`GscMLU=2pRdoV%~)&r>4a# zSmkhSXhm$am2OwiM=_OH5Yzn|74QMwhG3oRrLq;LLgZk)7w6tcqBCWd29QL!yg9D& zkO0*L|NmS$l!V?(&9uk@b=#W`eD9Q~THz@(YDNw48hxVqldKbL>#YI_9!Io?bXi2S zi#}O4U^7t?c+A(L67JUzvEls$0h@}rRVbu1``?d4f8IGJEc2t+xoCz*z9pB-FRPHk z+*(oDb#9%*+(&#Zxp!I*@ul+xW*uB8jK)=EYhpBORTD7DEb)z_hFkm1<{<qCeVrJc z(-LZmD_K9Qk|mTKC*5eq)qV1RIfoCC@bx-WVb<H;)n7=u6x6c_no47Fl=hSSXye$L zptGc7nYA*galf%9E!NKUNh~}4t`%)w``YvT8RnF?1UVbU6bS?Mj+g8niSLMkmGQI{ zP;@E2c{zLp_rt;ZEHPvMX19i9hY`f$Niiczvw=<*A@`?cRIIXpar8K|J05CTNWqqa z@hb0Cgb_eBbI^sf1`}@ugq``oTPUc!d$!}PEztuAdGMzK#cvJap?!f-<L)sX<vQYQ zUrPZCW%zkFnQLAM9vD>q#u41U1pZ0)=BFo8OE(vQf`3D4a941S#^KZHvQ#P4sZ-gQ z$AJqKJ3~6C3?>OwM?HB^-R$x?uN=H`<dee6+_=`?z0s-rkJV++n1Oi@$ggPIdKk*6 z4l!l)wK|pPQR^GuE+Cxf3Yh}v<`+kW!`u{yxT5)PWCrKJS6LEZ=*Y8@(c`jGP|@`_ z)4}rRr}UYe3DwegtN6n5y20B+pq&yNWf^r^UsZSDb+gcFOZ3*$^1Dk@)-ebGQp~7q z8LQHQPLcCv8wxy!@2bOPDV9^3jzpe_bwuQ1jN|8pi*Zu*zFx(T_YVL6fYif5PdBPj zjq&;LLnZ050H6Ontpo3U`Ij%GDR!>kt8X!@k$KmAJ$-JvWCWW`RBZ1VHr+DJ$Yt4J z9){H7NquLPivIhn0Lw;nojcosGVJ-XMYq_FSC`>bi#Xx;wC}m=U{s-~Cp8y7wBsPr zl>(r{x2bROza1?o1>bl4qIIs;T<H=dpJ|itum1)Z8(N(rAi);q!Fnfv$z&$@Jzwf) zg%VH)`74FM@kKs&Lj}QYi2JAAicoRT24-NRI)3tSg&CEesfj3fok*hOWZF28dKlk~ z!)u*>{JF;pa55TD(3VNY_vj}3UYO&Tv;H_0@i%H_)cAX~Sp^}FA#~1-zd8UAu#=!z znHW}Hus>7>ZdHGZ1J+Z6RKYb#SvKvDJ$JiVg&0^Y!*IPA_Is~)em%-ffb~yo7VrsB zIcf^m3Cu9!JKS$!tkW#w6?Ek%yQrNkZ|`fbOq988Hdl9iFD%MWYr}Kt1uVc+N^P$e zKHs*aJq%ucT6%NtWuGA?Uu}#?B0iW0uO+Dxa<)MlJ@GkpjO6#|%D6VJpqvVJL-7-u zUw`JFj;r6GK6*}WzqH>nS=P-<;CP!y8?6wbE&5vVE;;dAUy{s9V5?x{^<jtFDsyWd zpAt5_DK|j!td|Dbs92SB=}JUjN+2yQ3MKdx@>F5P@X#fc{5<@l=V9$a4d>A((WA%e z@RB7D(Xh0un;DOWrPvET^|5a|%eJaoV4itx@+V?5yxEdI#MnlSl0T;nLoFbzluHN; zQ$j8*{&zs_?xFC~$A3EbLvFVa7Q*)77~SOnKf(uc<d`XAuQ}^R+7R?1kcXXyQwI5) z=SMOw5mtstbEP;I{;c{qL6{^!b^2ESErT*4oQQ%x+g;ZC`Rr#3ck?uMPNp=ctWC#a z%{7dR2N-JF_a;-KBIF`Sl2T&o*k%k2w*S1L<SXX@;fZj>byTx)08>&Zz#inF;HiVA zgs>aDp{S2;ih6HIIBMF_HU4t98g8dYfpX3|9vly~-k6npYf~>dfRnGKLJT_^f&&2; zhi?x&g6&54KZW+ZLvZKBq&X?+t^?fySUdkn^OCmV5oz^0244~Dg>jCT$}S6|jt@_J zNL}NzN=HqVg0r~Hb&_pH)QCa$MOR3d6*Jmafyhf8XCo)Q!3q&zIsAAc9C4vHp^z#0 zKX^!xKYF!(b3ICCTUuU@P_X~nuNJq=v9M2keSy5|?^1PcJ@N~;zsrsZyNRlpxf05# zsY3MhU^k87Db4T8W}HF%+oYr~cJ7p(*l(<N`qRpsk2@S?{kO(+T>5L~?=lR+%_t;; z{zY{ecJ))-kf*o&N<*gC-RC5Ee|5m0QMqx8)vg|VcpaV{n4c9mUb_tb!>Z#gOLbj< zx)!V8uO{t|9rSXsROx%*)gyqyGA9Aft&1WzVK=!sr;_!EfT4greR<x;_Ypa&uVxTo zfN?%E2%&t6Lz7NQW?;tD5{_>|75x^V!j`|p#vhppufMIX-gVObgh%J7ZEj%IyEoPj zx_T{sigAg7AviSrBfh_pN_L2$4Y7%X>J$Og%e9e;F<=AMuhFe5`xJ=t>n1KOAG*0C z*gajmVlyZO%7q@FOQX>u7cB}X%6N~DgMsBNoXwy{H6r4wz}BrB{6aNZOnZpFg{1c) zTYmj`m`gpF7EyMBG(=@UK|-a5GAgidn_#8rC8lLZicQRs=fIUbB+&`{O}vI&Eavk4 z$E#=_QfO+DzuYoplfc)KL0ge0uL*|08TshcM5WCboe3t?%O|%20yXnblEZvIBjUB8 zoC-i~w6N;amF1}oz<(PBa#m)>Z_lj(fi^2$8)@t>b@EPNIQ-8fq<e^b;;rNF#fRx@ z(zN70iS}B0d#t~6Z%-C8osoC*Kd(&Ja>J6Ntj8peN}_z_3!|8Vs}$vbV$}>oGzj;z zs?bZH-d&qS?#2;@1ZZB_DiYHXbCQ-;1!uSA{`sA1>ZfN+sO4E#=t}xM;fr5GVq+sL zyA5hCJzXm(9jIxI`W(Z=uJF+v@1g=ngtxkT*z;T07XZ0x7hO7cSjE0=4U$(oQfcO1 z-}4D7dlUXr-eQS_W{U~NCcM;A86L6}x=IvrER`#iQUPXNxsLb)rSZHzi(h@MQt{5v zaz#aCo%DPjw?GkbqLQj;lZ(YuPD`{(yseTa9gl!~6|YuVs);FK8iueW((-6wzh0!g z``9_!!CVf|ATVJfIKa|FBd+<VH(6A$+27NS2~Ni_?L%~_-iziQ_co~S(qe6{9I`OV zr?g1$R=1Dy_?3K?{rk|@2Xdn)%rL4jQvozff38iejl4%n=USS8r3VM~)I;5F$Vxzw zoI}B;s(8QBl-V95k;?D~Vj>kM&TXu&ox7vd2j;%e)uK(ll%qZOC_1z+UBGNy?b-Ys zU!X!PNB&meXx*M|ibDc01whQas^EH1t+d3fK<?r&pT_&#Wa*wBZV?A;xl0g(eIm<w zoU5Ts=JlC-p7i8D4_JA&rt*I<Sm766GMf^b<`id7Ix^P^BxHKwmsu0MjdwO3*ZRu@ zUtvDOM;GRqV_LDaeww*5$;nNwVRMRSho}1f($~nEBPqCVgaghBLpP^UgY=VC+;yg@ zy8r#@w*=nK*(D2@BRQ9Tscx@aYCa$HMl~gWeS(_2uvm@ti$i(*DKUm0H(U&9TnozF z^k^LRXf%J(Xub})PI#AlzGM>PxrmaPA~Z)yw`Pf4NlA`Kznb$o>L=eYHpj|C_IW0+ z$AeJC){4MNYc7WM2k*1x_=DmRfG*!pO&DU35?X)T9QmR=7mM9+2r;NqVJi6-z$9}; zw9H7`w!v{Uc1ZMZg3{cpq8*0E<PW}Ui^?^-w0ON{aEN{z=_sA*0gWRNMG-)N{|g*C zXQ~_rfM0Z6WVB?R?A3dQU&E%q$&!qk{7I#(&~;Nm{Id*mvBDj&;5n?cr#)i13CFg8 z@Ns^7)_sqi9Tq3`cZ&}Y^QLWw@s=L13s`?-f6p;{Nd3`+O!p~vti1f&moipcBv+<U z)v)-;K!J;=7;5<}8z5*`xGXh3D%y5!mHIR%i(erhNYK{Hy6Q{|DIbYxQ(>b3=-R?G zPbG=<bXcKalR|R^U;K-3rr0|E`TQKoE~~C+5D)mpDrnM?v?ow~EA<qk^kZ8rWm|b? zHH-Q2G5LyQDe5N$M9nzg#u>QG+Ld+hT_Rovm&;`buf?|F9q$cxUQMGhB}_JmZ`@}T zsda0GbTziL6Uq`6Yn^=_38^Sc(u;kNfxLG5;hxN&a=y@urWx{(5FtISf%}R#<C1-u z^Eh2$tA-=?rLr~JZ`Brh8<fvpa>bw#9V1@O!SK>kRsndr<F16N@!us&k_+39E!qXw z{2l0m7}+ZFHpMS;mj0lY@e@T)m1b@U$`&>ZYGNP`z~gZ?w_{ot&Mst?MF5DMF`o9- z<<D_oG85ioj@2aRFBH=*Qo$s%08gFipElMu^i5OlWqb4duA$~LVmd;ah%a;Ht>F9& ztcQjpyij3N8&$7qcjl5ELvjlO=@BPd=|bl`;a4~)rziJ7TE{U<n<UDWzYR%R#J+Ho z8X5R38>9YDRf+^&_*zRCy9>R@nk1;2!R7np8u&p9%(q*i-{xmIrmbE<%vP0nuFT{% zU(?LA`G=;jt1exc=I-wy+snjhX@-&nbS5)^+cL~yCTwJ3H9r=KK)=fMhkIG|jdtML zDk#SkggI;A^rq65=Y`sA1;oAU0CBL7-&kH3_eKlK0%V1irH76u0puV7JKZwcZ6ga* zB();IC4zVA)vRS6cV3PefMjeo{j1K=d4QJs*ud4m3KsnsoGCU<PIq|1L$X-RZ=2dm zi{-(4+}m`<-|m^O>iho*Yi7QCRG=cB=enlmv2;Y+yBd4uXy_*)vtK82u$&B!F7dxi z@VHKB&V+wM9VVBYzq;LGDqdavDze{Ja>WO(ucTlk-O%rhYg+7<JRE&fTzkpqa}ed9 z?2WhB(YT`lkK(z5S&Mou3b!`J-hm*msxZ~tCT*!%H|=($FYXy|sDOP%CiYb^xK zEmhy0k4Y|tj=;oyg+wIxde0+jNa={~+wA$UC^sCWotGuwDQ4Up=kI%Fo?teg=FcPO zum7SR&$so$_YQQt*Ty6-ITjED&C4OP`^R?(UAj<Th1@~M^xvKSI0Nu*hfW!vPuDl_ zcDUy_aqYpc1eoXzdB*Ls{?gnnYPu9}p)0QGTH9k?Eu&?lc~kw>k^8>$-SU>?-lZB$ z(i1Pv`}FMa${lOR+VS7_M|pMOHZF7VLPWQ-`x$L}@@-3|)9tMF`I7&sXtB8C{kWSR zx((<}J05Q5A8o%Rd*5l}+U?ah#TT<1hpi>z@-L9KGW)-;{m(L%CYqNVB~Q!ZR`jpe z<#vOR_@56_{ax{t?=mzFr3Sp8>hGWPY_Q#(B7&%Q{(FfZjuDxET`{$~*MM68Yws`d zFU%%g99ILs`8(@-Hdi@gOM4J5KkM&ITR!WNoFnfiz~j3l;5kejq<xZ?R=agDQE_SD zPB%yEf7qnFQK9TwkUOzI=kK|I!ifEocFUyfJ4$@Mad)|MaV;+$l6H5<ZcrcRHr<*p zn=~3EP{`HPy1hNw&<zIY&K$@#KmKP^C1q$=`YF9|Z6+9%%7p-IpVvh$hCfZDQm$W( z24*M_WP^&y<Mg&?M>&4UpfrY={1*wvS3`J}2VH06-^pR#5MBlv85pPmx1N|~?r4<Y zz_cJgG;aEe=#q+zz!DuQke_@6z&oITwK}u{aBiDVSBi!3zN#h(>B^6|r(aoe6F}gN zv+ayj$@nvM67+IBC=5J<Rg1GaE(Lbm=nZmVW#CNzhz9VMES>jcKTfm~7;axN#;E;S z+IsPx6W4W%NlGI~`>#$}ee?#{3gQpa!_YuRGUeo;d?Sihqq6~Q8X(zhqk3!S#}Z~5 z6q^dbk(y}Re#qN={4LW*AIyc#_Lf;jkwvd?dO^y&+0wCEGq*6$L|s7mk*-iKE6!tR zLO{Vtynq=}UaX{mkVa@}XiE%WGr$}J*x3nz>Bj^y8X;Y2N`7OM4a#YNL+4iHjid`~ zfUwTp&j{B@Jcv^smks?JB|cNgCo|(I3G7cow4uc=lGJ13p9UUM3f+|?(#BeaOiCQ~ zz9xqEah`n^?v;EflvUx1ZvORfZ(?dzo>U?%ib<zpJy|AAUr$=+L0tvGU+pA6-KtTH zS?0q<(TJN%)rE<A%rd!05$;pm%Mo%vUOf9!!3P1OQwxCVbXRHG{@j<U-~)D@*Cz2^ zL0McsQls=CDvvZ4Y;@XCwSM3Cw&XTh2TgUI*-U7A{o|19!nl4RB`0I2c(9A(rDT=) z&@a%(vq02x98y~sC*OM*SP<Hf(d;2b(7{}c2H02b3IdVeU?eWpuVzm-F(Mw`r|3&} zf3uKKBET;MR$w(G#Y`|{MCaZ>0TiSL3pl^cJY?Y%AiK&e>peGOp~hBJj!DMAizGN| z5RL0()$N!UUW2_SIfl;3=SjR!>j&YQ_|jhMK%yksL|E(@8hM&vt@h0+4|NqdJw`yu zr^PppXu)V&00l=^hF~0n@z&WF4(+H!8eqZ%019Qr0cr(K2~AfTP!-W_e)&g1trAGC zKm_3G->R7%j|M->@fCLhGR4xT`o8#c<0@Sjg!mI+LgDivq-g+AT&r1p9&WJ|C@~&1 zB{zB*))f(U`tz7?=TGzW`~Mq=Id=S-Hs5Z2yX(uGUt*+qZw<@iMxta{=K6rjb0_VN zSmgHB{g4Z;wbG#Hi?uO-XWr<tqJEocfAs;W`Q1aL<T{k>p#E8NrUo2EZN6~je{R2U z%$|yHJl{qw?f84OOx$)zh&iv@UsP@AEXv=lJv*P7br>kQ<CQ__we8HihkB#@$Vz<I zWHv6}ziVEBAKmzSe7W22Xb^QqrC;~cT|d-!3qeKJ!)J%6JiS*~u1jRDaP0i&6kq!v zV4dflQ91bP-C!*AluX>wlz89GH6FQV41~z|a0OlQEWSugzf!wBPIuT&efG{MhRqjc zf0QJFbVSYg1?2lJ%3qw`ozlKsA>7-<YkcF&20tUKIYR26KmBN-<aZHw7>24%b9TRB zx!a2O?^o12q=M;d%JfM!ZdV8UpKYHxou%2YpZ{Lyu7ID!)$Pf^0~+?~W9*6Hpv&&? zitm%u*-qnTnqR^?`~ouXd`f$J375{Ofv?V-ui>+2T;{;LL^7q@MQ$$__KV$b@Zg6h zol7q^^aoc1;odjtl56IAy=n8O`PULxIQSQu{~cn=jHo~8pz>TM&g>G%yy#QzT8U8h zS?<LAfW8`Ge&A~D|Hr=Bc)tZXg7xL6^U9Ikk_hN#ZCs7d5^&5q)V)52UziqOZ`JJQ z$#^r>+{MWs&Me$w&ujVNj?l8sIrVZ8WE<XpmmpTaUJIU$JbB<dsHK$_hk>JD%V?dZ zTfrNd&A;`lL@6U6f#hX{$fGrg2ePG+%7d=Wl^0c|vgh3G&49`3_1eUd6olrXhq4>~ z^LyA^|IUX56+1|8yM2hOdpdtoR;DzJT|9Zz{**Xj@X<|>YYJfm|EJj}<!E0*86JBq zrOpX(0S9)G{oQLI%60*@tuRlM4HOGJv+C>e3imA7{33y$49HdxtV6CBMnmg&3FkN@ zz-s~8m<i>7DgH48@pT&2DU&2*XdScdf4-`BiobbQdu+zt!9Z|t+N$H@Cc^c6b4V^a zzeA#fI`C{D&Kr$1`-6M$V?cy`rbvnUHvJ7_#Dw&_r6LmKuR&Eq$6$>s(b7sVPJUOB zj9c*JXe&WTy>|5wf>VaLVE@j`d?&arN|e93@Zjb`9nHY@G7s4`TFRj60d8JUjKrD* ze1BckAY|)Gg^aJk5m!Oq&FK~4Tgb8f-qIS859^yxpL-yETYVC836qdMc7$b!+VEX* zRVHgl*jH7L{V6*y4VyyGss8Pjs#esSW&OghY{MPrYon@gu8-c~RGs0sgPj!G?w&KG zd~J+qLyh~T!VxcCcVX)k?lA>kL1a*pN2TMMFl@qh)#c!azQrL68w3)wl3`&vN}s{$ zG{<+^DfACM?Ie#j*y%z~RmK#~3p3>g-#IJfCzaeMpCJj!b&13Y!7^jPj>u(j0#yrH zP;gQn9F2IXyj^U`B_T3#9R8l9cR-5~+wL`Y2+{})tEOhg0G!g0#X^67sku}D(hpFu zO=%{MnkaGdG`!PT4Xz@Pl5ppHW<@D3734hj%3_JBKfu(*PF`v2C+J{ls(nzk79Dyx z0iqF)p~MluBXk*cp`h_05l^P#H(oaaUZ4{I;Ee(AUH}EI2#Hd5NF1AVatR-=>)TDv zjG6F^Q{5i69LRzU6|#WQ<@tnZNB8+>KvYvPehORi`8WYt7Y4+w02LGBO2~cwU`N83 zIMqps5!=hFZ;~}p=}QRvQv3;lpH+gXpkRyJ)QiPhe(^;Ua+d^&{@GW8V?GypvcrQa zY5-3oPUGbjqGQ9AMGSs9;w5KdagU7IggC(o_Ohg;e}BCpT&PrMf{tK$x_Io_p9kR5 zMg7nIkS*e$fg(N&E1qq56OLn5`fbX1&4I}a*EZ^y^ctS)HP_C?Z_wS_cKq+4I#)dU zJ<cV?48zYn#})P4j2CXN8c(xx&l~RAQF@oEdY6!aRTn7z7a=>J>l{sDU%fM`lJ&`& zYXTmR_f)wJKBqYFw32T(93{=I-*du!t{%_(PH;P`81L}Kt-Z&VB^)}ZzT4067VUe| z|BS9PCr+wMW9^dc5V~;uQ1!W;WD1W@+g#&S(|r^B^*B52m5aO6!dmesvfBE6?(qFb zvnb&utio#vzhy;QaC@wN|5)6e-n{pS|Ef&WqC)mgb8w00;h2lji^^Ns<{NF9%!(R# zOlv#ci|&LAvV}v<mrO)I;?}eVyd~MvDC090E$`N;JXRa#`xdw_Kgz}Ncpt#m9i^a7 z?G+xU8~v~Ew&2S<b~ag76NgXqPhaodUY)5Jh#kqpyZ>e$(OeH|=s<N}+4z91?60z) zjK9;&DaI_jFZ+>ovEN?JVQ%MjJON#IS@D1KGrm@@GZwq`NsprLT%yK|*~C2gC5tcA zZymhuQpl_v`d4H!<!S7*_RPQYoi)Zz*vf>I_<7+6d_M{qSSbjSS*dbQjq{pr%}uj! zPD$<JQ{u-Jsddh`C=lag!O%80BIXV)mI*SEgYqd6y=nEEGP6;o>^Xa~mm+MO{7zhM z%j6SnC=d#3_%zzEY_<bXTy65QN|0nDPHdw15jA5g{(RbOUu`EP`Tn0+WWR9jy5oN@ z5!k$HWl4+(UeX*jH?jUv{{310Luy?it!6)HTo(qjj;I7%N2hL*67cqigx#gFs~jT# z4hMbilLHwiz`@-^dk_QOsu`!n6&NG9d@#}org#?Zp-*ZD=yfBzi8TL}AgGIG%+U1j zdj)D=e8j;i3`DhEQxY)W8K=_|O1o8YY{()O`6|N(@V=IT7QUB0mH~0h)qi|ze>FOv z0JxLJD7@yFaE>6Q5p9z#JBL6-2fR{%R5RiThH6r7Gp<~kct2WpkE%vBeE?Rg0s4TV z?51rD24?~~mWWBUPYEDKwV}x)>L-(^w1iQfM+-TkX+c`YdDFdfk*4I9-$^*1=VMF# z)N-rSu9`bM5~gGztqtxbG2~)=W*{1vy-!a}a8nir>j{GL^<UR-q-2(G5+2P;=#de& zcW@gA>gI3N81kPC$i?fcgJvaS1l;a`T$w)BA)VB&YGtl8_u%=s7OF?617lS3jJKMT zVSup1gT3$xV=s?;i?G#gt!(Ogd!WG7NAfm;gt~A^+@BU*(f2}#lKLzudm1!&NS*;R z{n<(o{=MJLIaT!Tg#5C8HDj|7QEkwl0+<csVP_qhzn6Y`Ygk&*&>p3!c6tB_k4>u! z$m}zUN|M>_eqF?t;-mswoDQ0Il*fKS495FtLQxRYg#(gjt=K0at6*e=80<MJQwB!H zd)>ld|N5694NH9Hg^=k}9#&UdkfVOU84c+>XI$4b9?}HlZDcCg-le6rfa4bp01jp7 zAmU38q7x6N_g@K;Eq4+yvwhXh7K!OT*uZ4NzO4;&gytzhOl-E$<!ZUfub&gr!Jh%^ z5L{|G4EB##8vh_XYp+TdW^Fcb2&NIr%{2qN$tdeFG$=2X=@U>;I9&#-$D*yXb=7m> zq<y+?nQ;rf-fBZRV2H()0eRtedY*>()=#NrP^s7IOyvY(x(Q;oLgvtz8<)a(gj1eo zj;v$nwP@W{sXL{#^H<5JyR(;>es_Op8?KQ@GMC#yA-^QZ|6>>`e3cFumORKUS&p&y z5kNH_>D?~5%Cu|f(nQv*Viz_o>Qsj9(jX2Jw0n7qjMlJ~M)4=5N+;)R9}6oxhtOeq zX}QHIN>HG#==6J`asHBV{?{v>*JO>~WGIvSUIjjbU*umz@QAkhUxcRB-V)v=mUvIm z9R%PW8^eR{Zija~X5u81{hj7=JhyT5k#|#mi&PGbwj&>J@p2+6nRpatEi!{_f>zRS z&T_vy`$S!?CHwsx%{i}LxW$=2&#Q6nOp)+h;km`3RSP>@w!LnvkxXEdJXMjr1k3ah z95s*v&3oJ0PcWpJvvDVU+OxMlp4{{)-*?{FV>E}Z*W7<gc|Ue5af?w!*=_4LXSHHH zD_>L9*W647B_ka@1KwSoNrr}-&hufm;FYuU{QV$*77n)Nik+a7ck9W=<KDez2TWq) z|M_Mr<JAQ%ta<wxq}ex~{BB(NZNJ22|0oXBsrW>cVBCb8@MM^J-!L2Mkp47=%}%b* z${ndFd(%H+klr=U3Q=@DI2ydnP^62W`A&$o+Sa}ZvcEqZMrCQKvw=C|GAw}|lEtv` zn$vOfJ`GmO@Mq^A`-_f*t`Ze|wqiN<KAaBFb(>9eysa!4Zc~9X6&Fo1nz1&p`+$u_ zNtaevfc2VFEp1TMkE$FE70SBSB1rM=fm}FutXu%#5LQg{ciZv+R$j*_ttnnjx>p1y zWfcJ+qqZRcQ>DYH0V0^pu{q^0p5lNeyK30*mw9OYlaqLlMM2?5AV0N7(&-{o+or%O zykz3?se|*+CNLc13jo@wssd2TkK{mDWLWQ&ZcTzQIrP1JYbkP^X-B5}pu_+5j8(^r zDQ4%?vXj_%Q6MkPP0sWr=^tnw>wP4I8B5d-Y6N^o=-pER61{Cg7K5d4E2dko!xH<< zXd#!~AsSJSlg|!GwgM*K&j^%TJHaDjooFFI4$H-W@}I)Ix3&o0wqz?q&pV%}uV-ZQ zbt%lWO6y`j%CKT9F4lf7+@E~=rFT#5x36R|UehmCFVT;bIvL*2#Zx>rr)?qDVxz>V zuJ|HVr#Ja45h&sN_^u%>cn|z&HzZp)u~AM{;|;3jDgJtk`Opns@(Wwd=Mzg^C`d!d z)~G{O7i83}7j7neMlZ^9ZJl_$_kluOb7c~;$oYIJyK#1fGURq*D0sS#(BIt!_6jY9 zI1S_wEy7;l*lu}4&_OZDM@?`N{{^<YTbRW!vA>J!$2a)`{~7{mP~6^cRva=q5eDyI z&%D8s*v1lV8!2}lfFleV6q*F8HqQevUhnnP@G6yNgXP6|t4D8$8246SjiK1R@ND#3 zaq1!gyP*nV`BO#)i2SyS5pbn%LWS7eQ$u0Iim2~&DU@JgtTT#<YLARN{YrcJ_-#5! ziDQ1Nb;!CpU!pDOvg{QDi8#@gS6sM|gym0peJ`WEz>gB_-QjW|K=vTaYk36yI9#4N z8H7Nmt$Ny>LI5=*53LiP`V-Q;{5nw-D{bi0-)soc7j(g95igsY6El+7s)vvDRzL_W zORjrm$6Zady{<8=gHyK@xRhzEC}eR911Nw~xc*KRVhq7&hvhMuYck8#3g>4V=;DLV ztmQV7<iY0r6i22-c9nX%gMS<*7xtTyA!MzoVukM5pE&qvH%n4FeeFTx)rXR0I<rTX zsfgPKkDJWqc>KQQMNMcp?SrS6yqwwp0sKK-T?uuA{kfLk{uMkE1z%Xf@>>k^n2Nh4 zfgj7G47``3ujN@@Pwy1j7gY?0zl4lnye=-Cch+evt#El$pL3)GD=sg48c)@!IVaY7 zaaE!L{+My7tasQsdpllpI9}8IwWj&R-s9}*HkIz;`r+`-c@N#~6TPcg3D1GTTbiAc z+sAsRoxU)OBdvw~%=6ze{vz(pNB)O_hshV!bayy=@N;~&p^wHw^J~k<<&Jb?2gful zAxpG}P-oZlm=oH54@bd{#`SfwgRmW*CH(ozv+J9Ng?4Sf>#b4RV;=h6Q+t0N9?xFm zbLEl?s`;Zc)Uv()nXixC@zC`Uv)01L{FC;(_?e_m6j;`zP-{X9u1pH&RGP`jS8;uG z>zCipE(}HgdmS7$Pjz#119xV(a*5FKH{FU|N9D_e78cjW8K1O0t-`uNoW(25q7>VG zPllk*NZ-lMmm&*3M_5gJ?<)s{4!8lqMk8cuVojYQ4oKMtZ!`b}U@`ba=)f`;-R&X$ z*ZbpdNMd7QPFb2-r}UQ_T%ddexOKGOP1X9ehNQn#xO|bQFy8%Y`?yEl!t$6~JgSYJ z0%TAVNI)4uD+n3f>rAEPFXJfV?X#i2lmfHcOOs6iFoAga<3G6sSRhbJfbi5HW1Kxd z)2+BCzs_jI2sT#$e>`=0NIT-Iu%Y`ADx_cE2LMqZOQv~+I|nAgLi7+~`72EXzGBAP zK9c5&{lGi_42wNwPX{gvNq#x~qx8>!CKv4wF$(dH!~<~m9^->Nki())tbZ7$pHCY4 z6^)(ei7w}txl)t@xm%BLgK1hy3@}{KOMl5TJb2IWNi&h1)0+X|Y@~KK|BaQbmzyk- z77#|>hpwPh0sIQeaCQ=GY2$TtUNM7I38-UmPpwX^u%5Pgg`wjyK&<7JT-YZ{gEAxp z&IMROdNoJjR2j@unfh)K+|M@<2UAvFofi3PnFG$7_zq$6wLwf4LZv%%z4QW)=YEVc zkd`&apYA(~p1v#Rgs@qGk=!NJdeo=JDtv||_BnPNLg?35f2FR{$7{(=9-Cb#3}k~! zPS-#VNin<R!+xjH+lOK>&v5a9>-ue1xNTI%cy{A%#)o0L<dB`JhXh`db+a?68{e6Y zlAH&Slpo2#w8$kUkKGBvp?i$rYtu|*W{`FR<$Y7(AW|A_Q@@LC+bveWS<5<YxJ|_T zILgFEHBVUYHX{-iP{1d=<wOsm_3|R4x99uBK+1xlc7*Y86;|Ijged*>>LIn15bNU` zI7?)ol~Vf^Eb=TOm;tA(c|KqV4EL}BZ^iJEQXMM$3PL>JPHTrak+tZiY$(YCzM`Le zg<e49j?EuF<04by6ZA6(d!$=oT1)FozhJUZsrkVeP@#(CGb#cPF<3!%OMR@%{dGgQ zkdzq&pHC_KWwhIpAPT9pOkiV07bPJmG@nTW$_X3+LxcLzH!D}m+p=a;775|4=7{G7 zKc<H?gP>jHop7sA`Qp%)r;<Dtz|^r7A*OHBQ4{Sim^lIY1~KcMUmqLn7RMu~<;st? zeYw;qAob)v;GnJ-BMWnMg%jfpP8}MR{;Nj{)Ts$jt$a%Dni_<FcRVzu>{llUKdG@8 zTzl!=(%nW{LKZLm5mA|kK6(d*HTwh2$1;b=EA=}6=>L(mP|d}EW}Y_-u9R9%zFoDi z<An*(>8|RQT$uVDd_b9^mKP4-{`)DCr#SXYCGuzfYn}9EJ!<enoZ6ja|3DdWflkv6 z&;GbOYX7s^jeV9*mLYTBC;Gm-$`=DNm*PkyHMhi~ul*I)scxKk<Dz2i75s)Cep?K| zrf%PqM0xb<J82k-UTOHZ>CaEGxkp}ZlRhhWsSwa~B<y#`WlsKtplW<_^9TC{;i(_1 z^6HfG+)9n#<yoEi9=qEuOyjoaZ?E2H7-zBo1zC}fD@|I#r;GIKar;}A+krl;aU01O zb~>#e3i)dJ{LiT1tqVTyf2cZ+$#_d=p5!GTm20C+Oj^w3XOEI5_9r$t!?~ZOOPeFP zXMf&xUE|XqIsC^d0&aa;S{nY&%2JZ#?bpW5P?3WLeP6OxEa5Oe*)N?XCe|oPGBW)i zeJn_nol`sC2{;SZ{=;j*BfFbM3be4C@+EuZ&Y$6cbsB@fx|5+SpyyX-GmS%BI3KTb zFN3y`y@Aco;GBkc<As$cM`>ho*2@Y?##|p2u!G_1wWe@3x*AnN_!q@?Y_&9pGR-V* ze()s4|Bml+qL34FCoJIfINMc#&*dQ}e^95gc5r+d9J3-6yk{UqNCP5#*u8jLa$Z)A zE?@p8Ly@b6?1mue@W#Q{lso&k89-soT+v<zf(<>G!8vu-k|YU?!~a#|D&K+H=o$z4 zL<pY4Ly!Os%d5j=0Cq(~Bo{aYvY4AFUHQEh%3=_}jQvM(o)biv+7Ny0X=pbS&dcur z4Qd3>Fmn{p(C&`k$i8?V@kQWbdRPu70acFMD&UKIGf-A=HIH7ju0w(1nYx~Br%vR0 ze=aOp#W()wl`sn_OWF|qu@FeSgP00b%zWKw{G_Y%!V2GsH2rtSMK08~F9p$HK(@Ei zY{{9W#;gG5<^@5}(FZ!ESC|1F4KhvK0*^O@WDO;s>$-d;1&yaqQICcG)ctz@smNBg zCTP>u@gpOCXfi{A`t1o~B7g8_7%=Z%qz8SBEM)oqq<CyU9^Ua%>I8pliSwi$E2X0E ztdd*jXO!Is4#`Q71$P5=YUN4uAGXySX!nJ;{k*f$!ZsKXwSu*;yeQDv2wgtbPBXG_ zG$xFDm0JIHU(aK}w#<0Z6soO{&cH4|zg7@pI#4P41XV_XN1j5t5jAEii2`Ts4?=qN z5*mobNV!VqEoS#s+VeUBTWi99NO?PmXys{cfd1OZ4BiSp08&6fnD2X3t<@98Pb{$o zCy$+|vQ4k5K{be>#SVz3u?id7F#%9khutgMrbpeOLD}}LcK^4K^XY^#)E#W<VNhGJ zVR-{Oxrpg2MdZcqGzE4(A2Nq!2a`q!2SboqE#Y(c7iOPRGUQ*oa6V92rZTnYJLPza z_#UE}cnpcNTmWi$5m@Cw0GNMg$$n1|qTMPA$~rgG#I3EO31R_ql6%zD&Ha4%gHRr5 z@hOORKbc7+9vUiNaaq3>6XxRx%SCxMeLmaVdSols%6R^~8951B1*XD7flCNDW9q;H z#jc|DT4^JYBJGLROw@ULZGasUCoRJM_-z#U(J$~sfRSfV1g{zz<{jm_Oh5>e=+~QK zbSDH_>?nlns2$PCIG`)bblk3f`EDv*K&NrLOp-sao60W?Uc1$K(Rz0SznDLnI5Izz z#MOTn`2Q%Ct*=XmDIJ$q<Mxx>8$<Q4>}C3u?{-TLe*qmYv(_(d{m4H<<E}rgF84_B z`kZdpfAv8(*4NeZi5oJ%rNXQ0)nuK4Zfp2AZEhbinX?6W$_P<7ZLj;?_P~CKJ3Kmn z!QsA!^dZhgwZ1RDF{bsvC5PYDLh(M<-63nSv}Yuh{UxQ{#R@(zR=Kx+Yn;#D4ad0x zH67;>_rqfUOKdwobu1A-y1SjLjDB-{XO{fpJ4V0V#lj1og)3%6<^n#{D1_&3NPlrh zUZ#7b7#=!sk-D&aUXh_BUx2@bcU4Lxm2rcD$DJ&kD@fm2>LX>YE;Cmb<KuEJzW08H z`Q760b5$fCMf02!Wt_ms4to!s&x_(LR(KRMF3tRa>z*++;ER{(dx>4_b*y&2u5o=o z85?WcD&s1fXX6@QCRQ!Kc%{&PP12|Kg6=tf@Bfh=Zx(W|OU`35@3{PSrzVDm<#B z`#!lFN#m4ZEGTRaHn(XCSn&Oe{#gEQz(0AyJp(CFtVVZI8Ky=U3aVkGr1H3(!Gh#W z2I9jYjSdhUGbRGy=a5A`xy)M%co`lQ6V&^g)j2dTlpwaXJb<+0%std@;CB~f*wEp{ zy3&YRj;YLcS02!#)CGZq>Z^?}^_xW~egs$dm+_7_GjQcWL`x1D@vlE|b6+B%q)g52 zrM^|$Y<u**mh<Q90Y1=G*kBl#vkSTdfgCUJcdfbqCFZY(gxObla?A<<l#YiM^um%- zogq$-Rxr(vgtF0oxJPo^iWyH-QcP2VtlDdG_)Uid8dqRbxtx4IAbah?O}Jm$YydJ< zT@5U-tiI8XOC$yR#p9qAt*Tky>DhJ#Ag+E9V)ueh>m=AwfRFK1R;@<0C}$c8gO_{$ z=JSW4956=0wc#>#Q8|bib!r}J_6ZAuZP7`5-W+ao?|X0@k*;i$ot$qfKTzXjvzbXB zFi>OVg<zuw094Rcmd(m;NPb_#7-A}jxN^<X%*w-oVWWMp#($ND{u2A;_3!<m+6pmh zJf9M)JzbcQ-ucCHm;YpLTeVd!bF-v=PIYjBW({VQ5&zlX`$u<|<-wBCPT$P^Zm&*% zSh-HISVhO3^@G0ngf{uB4(a;jY|IVGQZ5C2$Psl-`0isuI6LUoxUSFcl7AG(8h$X_ zNkrB$Fk$C4iR0(%7_A7&w^m_{#^Cr|fVzs2ee)EXe+LVfc^KcRs|bZgieLzVEY}Lp zKi16;6}a#se;&`vF9ce``DJw^Frg_~rObwdvf%KPHkyx#zT?&QO0b3gB5djnI6k>< zEgV%J?w7bc<;*#Lu1|V<WJ)ZaMdm^HL>dI`PdRlC%h<ai^3Ph-N97H-(!?X!3%Vtb zd!N1%UYj>cuTC9)oZgYJ*fGl?0roJ^?hJ(K{Lad;=-(F4MUG?4xU)GnigpYgj=T+~ z6P>sDa|&5O-6uG$YJD&UFA#J<Xra~duWHE|K9^q?Oc@&u+R?-5b?tr}!TA|+Mv6+Z zUB0T_i6I7FB<u)7nn=s(sooC)YEXs^y31YeP^rSXz^CNG&hOG~>l!6bC5bXwRt5cZ zL%v4e(t0uzSp3qc_?g_rb$BR2GK~>?T^OXWVMi*fxd}F#3^8bGVbw^`clc1M8MNk` zR>EDLXk5OFP>MUv^%m2Jz9`gyf0dWM>8>=1@%p<YmzBMMl6ZN1zeRigkTjS;a)n}` z_O9_i+8Gcc?;lT3G$*l1E<HN)r~EVlzde!M5F1z;*S25t9Ppk$ytsOmKBs}C*t;#r zKg2t_>!8xV>@ux<rn%?UP8PO7_a`LN^MStav0CF+7+sLpC(}8%8C(2%XlApM&0UX% z)5uQdz{1V?#G?J5|2X{8UtO>M)*OxIOMlh2Z*sjz-?jt=*Ei-E-)H{L-xY-YIBVRH z!VQC5`l76^JPK$24*zwl0|qlnW^1JgHsQZvd=a`ZW$q)|Qmt-T)f}kbxI*UPwoKl5 z(Ru#M{`!twx2|I-C3xemhtA<BL4&}jazxq*=zXi+hyTcISN%IH5;uxoG3WXI4+)@p zXrt7|C|+=tdWYHDl!^-%SPTGLES$!OnY~O~bB*UK;{as|dGes?>@|7naBCe%)pUzB zpcheY*q@(`nrxxzx|F^`5JY^bP8F#5*YA|`IKb73V&mB-5a74PqZS;aURfQ6Ryi1R z&DM-xNOvT`Dm1FuVW3SqjHEejjN#{f^3M`6uJfK_s?9U+?@vqzSZ49HmH*)8N0M5D zn*u<F9CUVrBK7KC?t=YN<|Hs#nSbz<-?}Pa(Mi_%D1K9vkjU_{ia{XtUqBih427iD zRfkOFJP|x05Mw}E5`kSl9&|<A^1qry2YHH?QBjQ|?sR*m74#m^u{>iMhB0CU!H<xQ z_?L{+r=hF|=f`RnGHmLQ5$dEEQ(OzMKt)}G-cN00QhEZKwb$wreqeoHl4FGed9>Q9 z($c=t)DxlH{8uDOM*<to<R{tU$6<dcC@)`;HRbh(`aiyQj!6y6`RE;%Uqu`EbW8VV zS;w0Q*hVsgC6TV%A1j*W(68=4NkiQK`~vk-do<rIF<+j))??rvsF_Tf#n6vLG}uNB zLq5<j2IdRk>&ZMsipwY`U07N!8y0-=t3!tPs-U0$>K#cB@{E<(X8JNIVL<l1id{1C z{`^&twGWE;4&-@39qBq_5wVS|G{S4!2oo@~vk4_R!Av!gd53d_Q9l<XMGKh>MFpWs za#v_zrUN3#Wa3Tv8)n@6WvM&{t7!&{f~oQx!ABUF)QqCkhWWei67Ew?OIV)ukZQDr z!MZiJ3LeGtR*ogkUifaOi344+IE)1SXI}R6Fl*%CIB1-Bj!vY)7=j|z`(TWpV)`O@ zY0qawV)VDWiXLbcj*DeSqzBc-Sa#t??a%!<fAKiV`l}oua`)@1yg@ummIT;dL|Q~x z-+q_cB-4~HE;hb9rf<7VdJUuvvzsb28)7gB?~>>ymPW_G^ArqICS9i7rK&l=3n>8V zSqP_vB7PQ=;cL0>I)pqE-F*)qIiHq6P>#pw0N^pOk3z*ZFs4Ay(9iC`P?$eK<s461 zCF1*MV->m><p-~2Un~fM%P#<1sp`SGL+~TpVBLtnkR!fwb+*;EP-_BGxvyI@P<Lrx zS5kaiQgZ%%f$r^@&xWG(>Rq)mRh{nbxtxC6-BD-Q>WTSLq5Xwt#+Vn?-BKOAm-ud? z*Yi?-=<4?WxAK}t(-qhL<^k<ZIk(IiTghUtl9#@r<JO7KLIpg<ndd^{c4MO2qxVcY zmQMQQsovG{GXnh5q5+apt36L*f9a-p9<TRthr5~k!zCBoNZ%R#Lx}~C#>mKm|81^H z;~gJ7C`5tv?we9ROx)FK>+;&eYKX-P)pRy&RVDq%;e<|Qego0Y7qh~)H7_&2oRfY^ zxcRSA8#R043G@ly8MKWT%YrVyye1N}7{IP!Y($(l?tb`&8a!H0g#L(jM{It6<?s~L zYk<>$tJKGP-%_IDJ?KG&%(N2{;NOfCsng|!1LC0YG`{OgpVg~zcUW~I7L&jZejpA_ z%#K&^<Kj1j&q4Syk(U{9=0ThKfa_ndhFzs{H9F<Qu^M#H0J03U;EqNI9PAYvUxMZd z(Bvhz>GmPZUS(O7md4S(IhM%nQJ%7F80bu1*!s2`{8$B^>6*eNA%~M6uW42O&~9!x z=p9L}8VLRHirxc#Az7LS+-g#5KaYDOgWKuZ!7&5WmwmS>*RGx##sC^Qh};3L+lt?q z#7Lg3=__$EKX4wjK5OGwO8jeL^&P?f#K}N--_)TbwkQk<@~3+w6=>5yI?IENs0t|L zCl`-^dg&HNereF50y-3dIv1JxPE>A5@a6f>ML8R=?8s)fiFe!E$pq{+OvHPiQG8<v zcDGatN*E!>r%1;^s>J+e3on<&Wlhcx!YX;Wn7Gf43@HLLx?E-PBfAkfL5GT^0CU32 z_e}WeDadR1qM^B^<RB+D9g`$Ale)(Br6NkTy>3w&Zw9}a_=AFlkYo!@s9x%#G)wRG zQPhp=`QOr0CzO+xo}Pc|`GxV{^xp^xzlAGQ&G{dmO9(g+q-R4T4y9U#q~)uZ8oX`$ ze$mDU53B}Qg2ap(6==xP75XFoC(Dw1z&8lDbSyKB^*GLLj07RJ^&-dpt32XeHfWmx zF}=W`_iCd3sg&iqZd*S&NW0s!0Vy34@Z^^AohYij-=<CSSXiHs#^AuQ^<F0^5{N%B zP+ta3C1`;ShtT0ctY7!u?{4v>#IVCa5Q901(WQu+`iC<aAy$|fD8rwk<Uh`*P3a&q zLfW*|(=HJR2FLY-8%s2kc1dk%(=+hP>Rh+^^I4rQ^Y+qjpDXr*jsXCt_(O?f!Ho^0 zK->c|ZW}8(TQ}@g$jv^+J2S9ejGus-Rh484Cbg^YJHIf1<E7EwkR_nb=%~2gM75l* zwv>(l*;QKcLN*3*8Uu?PA%Q3Na}#iFd?|9c(W366IT;g#LL17t06oa50J?9{I&-7} zN;S&rGbV)E&%F8`hgl^3nRfH8LHSKx^i2gB-%kEik^k;O4rnq^KXd=T7f$(VR%PB8 zUr(^jAw{H?F(-VH#2yHlx(wn8U#=Rdz5Me5{V~Wl9O|MQXT9s(Cz39$?uSPUKExCH zu214TF5?{bQe;|{rQqV+|2Z0k<t;hX2LBrW7|lmF5mrUYfC;L@ZpmrNljh);TFonk z@L)FoTVl^;sEFgpzmEiXoD5EAWt@UzGI2f~W~^W32<-zg%#V|~z1DKd2t0p$x>p?w z-(}d-Kx87ngG4DS*brDYA%@#V3M3G1CU-&wQLuWW%L;a<zcT)&Nrxj|!B?mD+7Mh7 zHCHrzMqa!PaHO8m4%+XSyb`=ZZi;kjHUt2b0NtR^d}WFd;L%gESQrzj;2V*PF6jeT z>(GU5wGnOWv8yNbY9K&e4Ew*HLRMkZbt7@Bp2<9PAJIs(G$s{LNeC`j+VOg=0Ttz! zrk#*z`1sZ)kR*0w2-HvVA>DJf9r_-}pk7i>Q3|Cb1UGlMzf}SU9kAjMr+w}*qG*^_ z5df)D7F^eOF!EHs^tap-Oo^G~mcWI^6sLkvD0M0+$mmu-YBp8RmIEu{V5`bfPB7>% zvqozJf|1z4y`-fEF@YW304BAg9p_Yl1p^^Is{pi{0kL1$MfRy7AA0o~5(D|dfnuHE z)Rpj{esjU52Uz-DvzVYY<w~A{(d~$!OkzM1Egjid=$!E)3G{-s4YAh>Rbi#P+06+$ zy2qDsF*%nVT!;0um{i{_QDG}RFTQ#Anq;}$*_Ft^l&$S53A9Y(>E<g0s)kq5az``< zxh@&u?WtH5EUa^On$|7AyZca()aSp~H(Zg*+O^sv%r0f5epeNJ61Ho;+2LeT<ttmJ zXxd5iO|9N=8x<$d(&r0a`4vRMEg}JO{N)_r6j4O{klHxmdnx(qVWaK{(*s4`TG1LI za6=N~lJ1`ZPT<%9tuU`AJotr?)(GSjI%6NF2CmuJCIZzrpq5$CQuJ&`vr*e`Nns9u z@V5D;?Q!_aA0D*p+HH?ApQ+agEVPNgVD1?VnSG93<Kk|vgaNvAMmxyazSViu6$3qn z1~vRyiyX~>9fr$&gSmqV%Ic|8%{HGFgONE<TOga;8QgBdS2=&f6=G`Qi)k+p<#-2l zEJpETm3np<arojbXZo_wJY>;$s=+FfG<3Mz6xW#$$;X8Yti#}T@dd4C4)a@)t2$*0 zy6fZ{Sk7o9O2g{TbamW{K$z#e$3eZq`yHH9z~v6j&NG)QLghk$&rm}aguD<%>+t;E z@Toe=!-DQBtRgE6ZTIV6tYSl_<t(W^fzs{fIAyAc;3_o@Db9B%f8Nin{P*q+R)OQC z+~P$s8E1*J#xv!My1RYU#Tm~Ps&N~ITC?}tE38w%*cKePoKHT4S<}w%{Zf|O8n|@x zL)oG>FwSOMo7`uSAfTV3vvlY7e<<Wj`7zX4^1Bn_-1|B=nk~O1F2PNP_u;WO!>Dz6 z{ezL~<7fKa|BJ4-jH)sUw}nAKx<MMG8;MPql9GyaY`O&`-84vdN`nYUmw<F{N*YAE z8wBajyFB-tbI<w4_{QKT2JH7;Yd&+%XHIsbYemEB6OxlR5~^U<$OoC;D2!NEk^H=c zNXBo6z=Y>62vr|Wn+YNSv3i})b=0Wao~f!O{>w5R`#sA(kEJpImV2%DHgfzXMUAP_ zCJ|L_O--zoXqw4FxwIH5hw%svxEAzO^Q1rQf{k@4np{VK0YPg6aL@l@Js1&4n@x=h za}#H9!MEqn=W>}kiwhZg@{`}Z^AlSzJ@$PthSDyB3&pq~HjWC|Jp{q}#X}$y03_>{ z^u4CM+@R>hp5HL73Xlyk>|q6w8g;ByEZnNjbvi%`1ltBcU0Xpr?c03U2tqMvd#7QI z4sy~U?4y@12=g{xO@z#o<^E%g-5=V*^6}(<3CLz@*&uijEF9(){44q)`j&eX-z#8R zZ&w2?b2QeAQXWv71wJqxWY7m;x9c0`9UTWpsvokAz~i&c{D!}l3;N%Fu~MfQ`Xkh> zt&||W)tPhNS~lVUr&BnL<i*NoSobj4g3V6^bV>X8Au=6%tI~uXE)jZ%BmVV#*=@`? z1bt*;WkK0ga#4f@6PL=uzo3^+ju2O1f|NNQHGaj2!X`7>mrQ{&GsoRHJt%Bxcj!YX zkMC^njXmib<7AJQ>DytQq?QuT(uLr%mxx~x-95G6Bh+}rP(<H5Z>OQ=V*0lr3{H8D z*42(VtkLZv+9teAU-^Rw50HFX`&*JgNqr;`Q#_B!nGS1$8{uW>rLBVx>aN={4uaaw znZbCXqkYl%XBS|TF#e<DFHytuuQ1GC`d@({WFymoG!xi9tnWOwLGjhoUUb~6IFRvJ z4d&0QD;)~pvwPax_l_p=#y6c~434zabN=mFg?!>|%SWfSA^V{2Yx~F$yO6zCN+aV} ze+|2LD~ix5#{JVdo_FgACM|1owj@qISJP>-t#+N8wgAV;ulhFnYZjr!de>|>anN1^ zVs+vM0{F$vl`gx!qNwctBj!PZ_OHK<fKQXDurT%ZI|dJ-h4)Ksm7>to4^=9_hyaqX z=*gW0jJkySJARXezW02i!u>k;Xen|<Bnj?U2Nq0;`B&#yT>q?%u4-JZ1120qSpZ!Q zu_@MmfCWngEPw*S8{`*&iS!9@{6etC$WlenmSgpitwdh#ev385nOEEO9eD8HuHV?K zxWx7NCU&bGOHHcmhy1_PvC!wQP9yq`e_KhWZ2R_1T(wM;|A{pJ@1(N6SGbH1un!+% z`@3Os5|o}Sdv}h`>(ChL>*1EO;L#0*H&_mn84ha&eMX~y3TIP#|2ZWaqf_U@ih;3W z*9^8v$;rVO0dfUrQ#CfeRU4bzM%hIJ9Y}M+B5F^lL7FoGG&{*gtHGZ;b;HL5-I_cH zeolei8$OcLrEBypu3kFp@F+Ka^TK_1!S{~s#HyTT0{<ZPK2I$VC<25uyrT-JOCQ(b zb1nth?FKX-T-v}Q4G4O3v8oGpBVfdm)<3OK+glHhP6WdrvICiVbA>#}=-}*Jh0ngv zWJnUGYk-4<rm&!#LhtFa?%*Ze?e(ZEoS2nNKza#cX9kw<gn^Yy2H^4ueg(Fa#E_Fv z9wog#P{Zam<1YQC^}Iw*J+?&|1(9fx@qWj>bVNXTMTCe#9BJzGOoOPjTr2XLwNCHb zB-@lCyVeg|&aXe{Fi2l9#vy2i;PEam>}HL6UwjW)rg@*`l1Pd-5OsU)eX-qkNOoap zmEC$Net2E6?LnTqAyfSZ|K;J|9{hK!&{ol=J~0`(_uGqsNE7g&E6r`>=BB~l1$KK} z+of%xjn%nWBNCqutrnx?D5G&_d7!v+0U00kZw;q|2L<Bix@;)(@c5c?dO?C`_?X0j zIw^T|H{$wO<(!tV)fq-%spiO@glLoen~|T;s9w=*D}j7^pV)&O2d9cZE+1+KzA55~ zfId32AB$)HZUUzW5H0FB)dFg|<owWhi_JW@tkdzvcZU8+!$X0}tR`Zzlvv)7?^WOk zM+}Q8^cB}La?Fq$xU9Vp0WFwM%ac*FWYOQPl|i2vv=izz%wnAo@Vqb<J64@wxENeZ zXY?^Dv4(JUEI@=b%2D#}_cES-k3#K)3muM3l9R}Pm6<Uz!IIrw561M1vdEP(b?T6V z6gVeLY_jQ($2FezO@?mur8cLA+XStTTm~spQt=l$<4aFq;4O%bQU&B4(>}#rQr}&i z$v=gDV@`wyIbtchpbL1}j#%__&3Wjc2C16Wwmh|$lTH{@pNk`YZ@cd$=H#k*u$V2R zR}G>c@N!CtzcLQy@14jvTKjz$q8_o5J}~7~8;^H+m(y=QH1-3|v+%s0XO5M~VOI*K z8pkP8)aAxPOw5<zXjRo;Y#Qw~;1=ZgP3i>*q_d5N_e6okFPr%JR8S5h55y$&DTQy2 z3+fKs0%Yom&INk1=zSm^H*W#dfMaa;HIz0l=vNS+6JA7z4w5i?X_(|<b@GVSpf^Sr zXTo|u{st*vWIIgrO-h?Yu;h%)Uwg{-imRrcwlPH15sIta?m8K0tx+D81~S^$s{3gw z3exSR1j)V-?B|+1FdnM3+cwMjm6x{+fgU^MP~|U;*$aIQ-V*G-l*?ClRwudI?THiX z3AWB58AhklVyDf%+3LNk1|t-0_mAbU`?edgTWj@Ft#Z9u+sP8my~G!NM@S!5rYjzK z4DWJDPT+@+zHN`drbN<qgnB(IxS%Bdrux6Xd!n?pRow76Li?@e64_}Q5T;$*Ebc3> z7B8_L6}$yF42CQr=Hle|DDI8K*wRF0FyWgS#lD4J*GWo}8x=lX-a0ZEk^cUl5rPH} zRLe-dNj9X3pcR3v)F?EXzm0|Su2RSx9paPZml}I^d(@n|U*jP`hab<V@)-#;a=FXo z!Kwpoanai=-%c6#Bf)BHXA(XqY9g9+0nHt>tl1!k9X*v`CW5w8%@rzFmyEX!q@UJZ zYZawAzB<d&c^9sWm94M2#~SX?LSuWuI@;d#lKL_Yxmg3<(yQR2Rd{b^vDO%iYRdae zbk%7y+K~Ek4Dj!jjt9ltBaCVC>Cpzb*zv{4NXPV`c9Lbp1+lENb*FfeWYES_2Uz6h z=3{UK3|qfuD$NH(sP_U(0Mg<`RSudWMSQT2Xf3P$aU8rC3%GPS8ikgmLH427dymgm z!$SJyKt|SoR#qI2`ld-`lg`|KT|I*r=DXn4)aBscZFP<j&n*TK9ku9>IZTgMQm$WJ z4X>q+IKXw>^I7)t6p|Sl#H<(!e$S^OhCHl<OPO`5I;!ZUz1z|-2E!OTG}Q4kbQfg1 zx}E4of)bksbh&gp?yqjSuhpAG8P(&3Im}BhLUa~RpH%%q-4-?0-Mw~_Ldfn+!vJv* zXt>eZ&AuFwP854a@`KsxGM)FfQqyeDGo>}2rpWkG#GkA?;=CK|>GyT?l+u4j`SkfS z^uaL!VF+hTPpCn>{RBZU%y2EX9MrVbpwF@P3h00Q!j)@BQH^XY9W88h&SEDcKazr9 zE7}x_p2%dHb3DO?T%VFLWKTdjx#Tme=~A~wJI6Ye=j8toQa3a^3B7R3uwS%rFiWrg z%Bbi}QB&?Egd9HRsxcCg?x@x>8gJe4$;RdDJV={Li}LV~CYRM7whpD<W^;}Bm@kPF z(;MpgI}_<|*1lCKaarPmez|&6n3w@Q^`cNuzj=0Ezdw78iw?7J;jIj5T`Bd`{x*k+ z&nTs~Qqswp<yvXY<{m2I>J{#BlrPWaAWXzb%QWM0@iyEw;jt1Q!Kvk6Yc0j(GhK{{ z-`%%{#H9jz9Yl*=p&t5`6*Hy}mG;ZLJXK{8D|4ba_~op69yW;0TFR<Abx0?iLd+Gk zM;e<KIz;-r3pPfY1H5c|<sg;^rZIh?Wpe6%P<YUcwY2<}d3CNc{%zCWO4bo((w!AZ z#W}9UXlu-)^UZsY-P6iVcTpx=s`WqH_kLpAN9{+FhYuS*Quu+L9i73Za}*z1@M)3% zB@NSD&HUfD|KBl?jpR9zvD6I;9%fLNusZ(r34A#(vpT++ZvV0k1eC#f$#>ZyE;#qF z$K)4YbMJM$ruZ5!+#_XIDqRAGUw9!dUvJ7E2<jhpPMs&$w*>b|TvQEN@?Bh9yj9H6 zprSJP&$H%ce>ykT)yF66vh~nMY**pU+Igkl{R!V>V)oqzssxI^Z~J3M251C5j{dNb z{=T9!71b$sLH=Km;|s6ZLH8ju>aIwmyR|nnP9>k$3IM$MC$%6Q-jHfKZ6EqE8{G#y z_B;4RPpz35-avf+`n31+Ax&HvB;u{nc-OT)-0TS-bADhVCJrByfq%~hp`(G9!(3}R z&aW9bnwz?+++Xg}Y5o4}#=q8js<cx~_T()bJhadH<sc`mo>vkbI;20;%j5_n#`*<o z$@<o$EptA&np3PGlLJnjSqiqBi!@1>?39bKm**tgvw-rJEY}B}Cp|xMr<82ZHV6Sn z>eA+oN*c2E!Y2nl7`l8et)~0K0;AHHC<x8YLqFw~J5;3Nt0m)1<HP1DBFv~Jiw+O6 zw5?e&JRL7y0=k0m6kdL4YC&xf1Nb|OGQt0|%y9E<eJX0of^^MkSusy=q!70~u3WI8 zT&6F#<SY42*9}k<#O^#GKKYbOCiP3PRtJD?7e3)Ru}9Vr<GwSX4$M`*G~F%o-hDnO z)8pP)xxG{cqbaH-SFwpm(2p?dMogDMG)<Z6s|Fio%E>=0M&hk^ylm|Qi&bm}Gyj(K z#k+TCL1YlXB~}&$Fkch(hjfG9dEY-GdNd2i-__8#pQhw5UF#-OQ}*U;6FCk)&BYi| zWtCpGZYUr^aTRUo`UDH^#TN>FFNn9k@`O0ZFF3STb4OnDj}%cA9<@7$Q>Rl&^rP^l zszyqFSl}nr{N4cmhGU}fpLY#(#7$}_lvsBn=_-#RQOEQ8GB>s^w7%}EQubHtsUE(o z0%ndB>|x`-AD3*ej!7e-duk8Af(~1+{sN;?-@5bxhk#9KrrEJc*k4Z2O~fm|#*%4D zK<8LrO3mg<mqI(>=0G^2E$%rUWj5}g%rV24HFllGS5qu0@jJ6vC8ga9W-~Ht8yv!s za-?Be<sRxPf4#J_aHBe>W4$GC97`DUDva1rIVddHlAfHWo|Sxe-5&~n=~Zt5k`mPt zf*#hT7uU?ILuI*`fm{yu+QvUKLU$_#OKsOyi<RE$Fm=){YfD&|n0ud9!ltCvpAm6c za+34$ka6y=o_RvH#z5Fkr%<DJ43Y1Nv~)7~_-_jWyE&<jLJNSVU-cTt6*Dpx(a3+g zfFtF0c!inYdfTl3(k+y?n?cZ`F(^f}X)wQ^t8h?LE0^_2-w@Lea|N=sMG{t|IR$W5 zeddxAU3Qtr0Oe9{u^~l80eOD-NrrP_NE5lV>>&lKi-S`1!9BDy#Z8pqs0&bsqoRGo zkzEND-J|G~_Ia9#S1I?Q+6#x5vEP~vPx2mD9_vO)8W*)s%a|8BFdt6ZkIOh8RgxBO z)!Pok+u@Ub4{~jnGkuR9yCD<~?kg(%I^~-Gb!vD|Fq4##J3QtypXTn@d#p!t-N+-d z(X3ve=(KKs@!D|}fsjXA^vV7wo++KOD$R5e+WvW(3CdBfPq!sYJ8X$$fhPQB1?7c% zClbwx(=H)Osly}8W2Clyn56Y2#eJzuJB)<pSSGO6>^($6Uh+hoR0rj1uldFH)QQg3 zFlU}05SoH5ZPnAO&tg<a=%0KQGdkZbC7Yi^s*V|&ouCSG-2a0^(s#Qt0;BjdCftBv z)d+?s0?e*Y4pr)Iy0LwBAv(X>($$ceQ}JR{cU+=)gpeB}c~qUP^~`f~rE-p(zLNJd z_EUq;gG=!OT%Tx**}$2plne=ix!D%ZOj03#Cs0w44eqYWYhFq#+4_+bTeKMF4KvXm zw&@Q@{@GZw0ALqksL=d^#|lp^E5@K6#KfpR9)5TkllcO%qPx0MbkJd-EuAYT8Qmvw z?i#1x?3lKmM4mM5DV=}nu=S59vY6lkM;=gq<iKA4(|*WuhZg`U=%R_HO25<xbAlTv zm^dm6Ts232nwwXzEjj;{Sd4C?cQ&obm;Q)H_cj0ff~K9bn6S>1c_)NI?Qh$&)Ammb zdMx^JN^J*(7v(VqRVVYwM1-{`gFe|LD5|Iv0e}}ihB%<Lzl-B{7QtL|yj>{90GSGu zV|`Kv5T8tZXv}>@yAQ;$Ns9z;@_at5vs?P7qSx#60%}vm-F3Ib8Bs};rBzl29VCUd z)q-(j4u||eQq_BbAb*d852ZuFS1War2g&g*BiB4~@u-ywQI4GoqG>ntp7!lH_F`iy z1d<Zvhms+3A@=z{#}_L3j*sGJDbukH2AjQuv2nD&idDfa9v`H=K>+PO#i8n#R4j^> zh2x#L=2AEETrBQMnA3=z6canZi*`L-w<?e^Ro+_G=rK^`%!<9*tOM*V9Y&a35xC$o zX>O8cVjs~c^_^a6DHZAN`@%MDT^!)XUy!%8zeC*^-ES^yG~7bZcjl9fShU4eP-rQm zqsMDC>YB255f6_KZG@`{_mreN8qa02-x?$zfTuwSTH$0<4bawD&LK?yGI?Y!`7GwJ z_`IqPvuGEOG7?8fv-}0KhK8z>m;?hsi1Y-gN20EvxlDd9^tE(L*-nlPf@3|9P}RRv z{4Z}AejT&bBNG*JgjZAQeD@inZ^+~AVzLX4Ylg$lr(qeejWLmc5<X@y-4KeKoDqez zku~#KM~7F}G^>57MY0`@>?VsiS;lrm(}zpxBm7q1G!woyfk~A7$%X(uvK!W-xcVBt zm!gBCoH3Y?#TXVHyw!4Gmh}=%p3fi<QISNwA&kWEI^{tKr=*ju<1_5>*YxT6;{z6M z<AIu8ICSYU2Dj=u(65{3v3q^zPSTs&gZsOlJmPf8e;*Vq1Z7l`Qa1`WV^p&E!<LB* z3SsN1ED?Y54gdQ~;(dxxj6y<?T;3}pl<i5Yc;D+3zqIz7()KmCO0PwLC4LNS(p%#C zJbQ6f@?zyzq^jeZj82T-fz)Jdf&D~YWdRWvMyoeE_+&pWl~AAu$|Cm_#8xg$LdmOh zIbF2!(D^c)y{cq6AW!<F6YLQ}3c_WL<LqRmX~>G@x}|D}vES;bGI`nc&|^?cBnaDt zp^1;#7vx+LA3?KoV%-pfsJ~=w$vAgdLUIc&T_>Xeq~zrPR(`Vby=moZjjD5r4rb+` zX9p{ApPR|UgbCN|)Qg3aDLsQ$TlA-d6tsuaW`n2}EzBtpr|P7Blt{1A+R&X5e6c37 z3ESg;9qX6XfowHnxgn|u-EqvC{Ve@A%TpfIhVz?gUxo#l&{Ml8R4Xx+GG2*LtOaEt zwh1A>9}g1hMq=(17v)yrUCp-2{KlxnrQ)qo<kSW@UKAJAZd7x4Uy~gCmo{HW!KYUV zio@Ln3~)!M>d|g@X11KeT6Uk&@@0q4p=+F;x=g+?6_Ff5^%WuQbF%qf0!2~e@)ggC ze`^(XO78w(UCNOq81`8XV_I3f`|~eRG5MTk2*#L3e?Fh)4uVP6X=@Rt_Ityt>_j0U z19n_(5<I>b6W*S`G{{BlFA(&$??gV!3}MiSFW9~0>*9ZhYdv@(HT2!(!HN|>uRnM` z6KT(pZ6#XP`}oNdioL92Of<1HTGTePkK==i^nr#X)AqD%fvL(SBA2&{?{R3-kBcsB zN>(tKT|ZQmpxdXp=r_tLZFR4DXU|~$C2Bmy*`h!8&#`$MyeG9w=jv~-Aaqzx$negk z$pD+G;vt}M=Ry;H$z+wgmg}C~md-i4jZ&m9#D2&om^SyBupcq4h($URrt}Q37I|J4 zsz$>?1lVI&d(uWKx@zjYYCJWpD!OA>cuvshl!{@c2`YkORy$?+O)#@K@t#nXMWUnH zC(-)@QUXnSm(J6q8K?87IXF=Pzf!=V8_i@Vvu>fi@99|HE5*l)4Q3Gp>z@gl{Q1Np zktEZT;)`2$weXG~JA<rd^DjmFvo@I&g+{b|1JoI?ctUb)-1|5l^nN7^7ym8`y;>QN zT`(+P@n7f}%8J!o7UYadRJQ9K%6Fa21P|zIogjaB?@~F<%|~_;9+-sXLbH0S`m_+u z>AaS3_!ucOIQ`Pf++TZs8DQnrHNnrE_Tg1?;+-{vUhgIPuWZ4Thb5z)JUcMcmuR0{ z`$OYHSl_Z&e^upo;riuaA?2t9wgAuYJ9)$|@nx7auKh12qI60={_8d4@(^R?y~M-h zhxRns{r#=S<L&*)CtUBid6;+MKwpW-L;ZjLf%C?a(cV#>6zE5?_7nDY_<N&Uy``I} zdWoZhHyImMmD{(KcNB)#h4p+lJC^gK9#Fsg^No?d5dn*SJ;>H;F=IaRReu*vn!iNS z6CJ@X`f3w1OK(1_UOT*GPMsH$(Z6At^_eiyhQ$k&oj$i3$8U0s9kv@tvkhM8Im=`1 zOO&Qz-T!4#`JTB!mPEW<%|AFllErT5CuDY#O2fKKoB%tVdq0(n>nxNSU9IL>CqQ@! zuCQ6RnFJ3<bu#2Oq*_{~Em~WbaS9u$540;;xdLk~2NUm>h(Cf>3YLoiBz_ENzUB-p z{0Og!6%zr2q^eM~jE#n089`H=Kc5xT(-us~Pkfv0g_-fwl{LOe)#SF&b0<l(3FDLF zBOIrbC!!4lqALx=<<cxus(>QHxoYDB0>#3Xw0ETMic@^53Hp9p{;=p|?B`mcLBcb6 zOFESc_^f#Moj-vuX^F`hIRHb+kq}ZgmUBBv#|rJPIEZ^X#t_^k+{s~A&xwhZ0PiW2 zrx(b>uZfI4B)1n3`)u$rfqc0#-Gch%RwHV()Bf#i_P?DLlwMbQT1(?4(V<y%4Td#D zTc-%`0!1}LxHR*>9>o%8?D=BpdUi63j^3YE|CTm<f`!s;yfIB;Q0^dx{+7QR?FC&_ z@X@>iVGuUXlw26Xmu>110g8uX#hbq$eSYvKUF=2DEmOSbG)=$tQPX;8TZnb~ID|A3 zZu7P=Y@v762OofOPF-%^;jzSh+Ql`U7nz5OP#FhI%3gH49Ry+_MH1R4Lg)CaG2sgR zL5B~@L53B4=;O_|O~VoC)x@{}j1l&?`H4k<SFO?#AR_J>^zBlK{K(XqC{WXr%F(dG z{6p&T&ssWPZE@^ZO=>t-X7W3s8{6KhEAT2^xKV_52zCBu+Tfx~A_go_Ety$jaLn7* zs6%LjeXI;pjLcH!`=b#kAzic;?ZuV%WFK8}qU^KrxhaK$spcuO9J2W+VtxyLAs=-$ z9vG{LGLy|fz(Q}CEMae5r)sM8c+x4JnH_0bRIv(K##1_1s~7K{)|Gxi-O5RHqes{Z z;jlsX1NlT=V4mPitD%nOQ8mqiZE`Jj^?Zx}WW%{^79gr4+HVUnvE#KAkVPe>K$m8~ zYP}U&QrX$C9|%y^0#po`Mjuiu&Yu(f;A%@Q^jSZ3UlR1ej&1&Ss(_l4y?+i^$NvKN zEeWe%rrQ#x{dOKt(zD$qMsNNU9)Y%`<ica|%C@Z7%jTN@`3e_|ZjHXsHgH1u4?^I) z)M&VQ+2^sX_D#k>`xbxuvDe+*H1ySr6E|EbG@13;ySB>7+m>-9qnmfg-%CX)!*Rw{ zd3dlx3i@S_5vTb-6w)B{<=Bj4#i#o4ue&x5?Aj*f*nB6(?l-TEdeGFFW5Zqa?IA$3 zEo`XQvnc$-Q(FvUnEPA@oM)2#;9O3wM>Nl+Bb2}(0?T>PY#oDj9738E@fgEH`O5YK z;Jo?mxikM6rEje(UmaWL2^EF$Cpl+^6E1CBh99sVk^T;d8oa$g=4zy)YIr70&Vc&x zUE|N#9&|3%3t**yMmIo~q(vK%#a%!qI2pz=Pg*}lARSJOf&T)N2AApb)zwP;FlqYJ z#z-H73XY%B%GL~66Jy$*B?e|j^)?Z|M1!(Ig|Kxw^EAwIgw@Nx9zheOCpNw~Q|)=f z*2e^PON6O}jRIJ}6~dJ#@kaCg*>5pdeK}Hwzj$w&u4YB5_S5(K$;A2B$Lhd!Ej(sV z6r&oZ{v|aEL$bfC`AO^Gh<uyp^A?X21T|YbzH?&@j5szS6?R;O?MBqH=%HntC3`)s zm9o%$h5c9N^qBVr14!d?Yl!c^IhHe3B;E80@ZzfFqh@o3I}I3#f_4EvRm$sg(#W6e zVRQxz_g7`-YH-C*Q(+%5^;B?`gO4s1R{Pp_pyhC*ywe5A%CZipP8*7a3L#XRC?(Lm zQ#t@^5I|Z<Ithr>_IRE_GvT_K`I^)K;kr%ow`lM@Z(*UO(xr|5R_3%gT1=0!24y5J z$a|&?pjzw^QZO2M3-=6lLI|Z8M~gJ)yKwY=10$V}a?#9g9{k5JS7QTSX#F@x@**pi zPc<kOB}Piwfxa7|Uh46^`ZI`3zopnoj9!ML)@2&G9~bF%UT+PampHe|hz7ek9BBe+ z!qSvnsqeC}B$g=V+#0?(DN;B%iSSmNB{OvNoe+*nB)qq*1YJe<>Oq^NhCroXMuCZ~ z&MhV0W(>Dt7)1jG+@Ot0I%*TQj88a3Ebb-FMm%ZUC>OqTsw^c7W3Oh_#~-P+VC%*! zEXOV;2gfQ4Qlnu~DmGY@T~zHj&TcnRNADI3W2;qLiFD^k3d4A;N;D7HeBQWdZ*B-! z%EJI2@mXXdB&JGR?+Dyq;k~$Bl5eXlL6>!e)SG{D`<1<?nv+FG`0yC4$#20<K9(SC zF++2icuSh1m;K%LyWW4k%s@-Xdwo1c(jKmEHR^nUIGDzFc{D}iXMR=F_Wy2eE5&I8 z7wi|l$C1~QM)#T$cdNLP;0kX2wS5%ovMle_Zt>9W?ogz1=bi8|0WjsFG9Og!6_uW4 zmQ2kEK%G-K=$*F(Iz<!!<snN*kRy&JZIbzo)?34TlSouE1>Uo7yX?UtZB+>4P0nPS zPWj$_dB(aWfIj{m{Rxn0ir%8FvKVx;yzK45vk=Boozfv6(PAGAn=9b(W-d}no!Jji zALzH}E|bN>9Im>GLsMd6Pp|$)zilV8bl!;Y90RCGhi5M6d*eYdnKkwzI>;^=;K11Z znb{Z(M({PH9w+i@Q_ho$-*8!pwg~|w*SLiQ8Z+y3h&0XGlLxsVcSALl*MC^-yR&+j zP@AGZM#zxjxD8%rJ?*nTpd*S22PhC%N1I-*;1wIhX2--0JglK-zp;WX^e;)%n4r5R zR`mNw>kQ(;W}NAc1qS)-+Ys~q9Ge_9#04Gaz13f9_d2n?I>@L^f9aLF_9B8;0lmqj zbig{z^IES22xDqGTEBn8I73KH4vUmMHs*v&hH;#EQMVlxHcZSZy^JxIG|6SDg|swv ze!wE-;zP^Ux!I*c-IsSMOE7r)bN<HC=OQqmFBT=v@+N2#F`7coxin}Uvz}H=U*Ng% z1|M$(L<+p~Eo*%SiqA6RPexHBD>#l<G|+HgyM-MFZ_XebzMGtjeLv1lVHz)sPZ!8{ z=tz7@kikg(n{5-Z+@(P^acLaiXLFhP@7;At5IsRi<eK=_RA2W<;9w)Ci(J7cg5+cl z(itX;FiaAmm>wic0SkSYO<2OYwT#hl*l{9bfq;cM`91~Bu1|ph_H;B4RG7J*C!Twi zGVu&pnR_?5USTLvGO?pkg2HNW<pO@g2<AvD;m(*2xEL&zMDa!4kGU1Hgun1)TT4JK z47$zEr@ucNv&)RlIDCyLcP@A<VB+LnB(3SInJ?E~%M#N$DDmn#S<js%#g;BjQ@J{h zBfVbj!$bcE<YRk3uRb6xf*QV*kpqmLi1c6a!nbqHaY^5!>;gq2K(!JNWEjDGKB|o7 zc7aJ|wZ%|Povjdru%R991D9KYfr&Y}ot$(?-6weU2ayFsJEyik9*>QQKg<C@G_fN$ zNZ$WWUExQdq(oeXf;X=v;c0*|XbD++Ep|kxE~STvNc4WY5;v_VH8sj9EJ^iS?Cb32 zpaIs8Dxtrwr=9T(AMejz`rpJS|9{_O8Wu@E%){$uFH+&h(`Miu$e{V&a=UoA8fbOT zarHl>16`ltX>aUNp92?<>p`QD-HAdPcUbwGgo^eDPqso3e2z8@2%r>3QM-_l4vnj& zVTOi2MUwdDR3PSr$;rSILL5ePQpe7<<6kfD?NS19CJS$z44uMLgIypOAGK-tlY^7K z6CjLud9k+yOvK42;@Z|-5P_}8{dM(lN%~RPK4fn^b^RDoMfW>dv<@bICIVFwp$S0M z;8?91-Wj<5Ws!!ye9aPU_6F91^lTkkDR5qu?Os25eC3~G@7!cy0S>^~pkfv9`kFrT zw`XHJC>EHRYTay0p9k-_3xxdT6?9z`JiZzL-=wL`PE%DQn1~<oE8B&<;;F_S;69kN zmQs2KjO6+1L|mpu^}=cUfUALSG7)AZ^hfZ%{9BRk@}@CF+EJl;@TUN2>K4jnHV1e# zC{qOhE41m&ygvp?BswlC(sQzMY1tT_A@1*T1)pcN<gG-g|Km&QhLDObs1njxc1v01 z;cYq%aU|jutt&58WdPHw8`%p``R@X;7N6wB7j~Yo9qWK1DTrg4_csU1SIwKN>&8F! z*`XKl0f)*e37F7t>*28c<j&)C25P$z3>k|RV}!gazdJhK8B$y)w!bujFMReZ5|(Du z8GNxY`|J{~Zc!R$noWEjZPz8ZbaC^#pWCrVh-2CF-}yLgAQq!#Rq8ec<!j7IPo<%b zbn^&>rU#L(K#pTS@TX<(9~VWt0HTR+e_B~9lS^AzzrwLj552XXdO#M={k=SY&&8DQ zfJ?B2UGG_&neJy9_*IeaVjlDMYZGD3au316^Mmt{vK?TNiX=^E8bK$oW~fJ(4Wm6Q z7JjC%N$0m87NHjQc`;0`8y?qez8e)4Wbp>P%po7GGtTHA>%BR!0CcLx?(L=7Q`9j} zbp$upy>;(zO9*He5u?LK7^Ac9PbjzUPEY5k_p#O^;<|wLUkRPqFIrjp{Qf(XzbaJO z&}?8u?wLS5B2O>~Z}v}u{f@Egf~A|LjQ8?o@K&WAawG|-FnEFOCL{2$3F``7lINar zllP2WDUd7bTqvXdr2``myRBjnZE{FO`fZr=-Nxqv7I4Z7gD(hYldUS7_d+8<8~u&- z&PT)U=YkgfRXcdZnSa8$ff(I-3u#!pbPc6@c{#w!#MBimbe5*_QfMk*UXYL&wV-PO z*qBp%CTb;IN;+--iviavNB!w|NOLc=d;)FnT(;?IecbE2PX2Ji)V52*u?$!8eLRR2 z#c23{mvW)p@`e3!FX5LXWZz>FzxcqwK-4AZUgFo3wzGVo3{Z+7D3S2|Q1NtD)dmLa zr&VKTlTnZcH1<N$RIM<Fb7(lH?wGc^rNE{}qa1aUVrwh`_`wbcfLi;@gE^NV`OAq~ zmAvV4U`bGZ-WI9%i}$-kqO^uJKdArcA>RVco2W4|9O<WW&?^vTnR`_1yZSWo>Yxu` zC2$AVjtSakbvy^^sIe^{fts3#EFHVRWLTArqv0j6awN^_u8qB)iFaX$In~S#{Wd=Y zm10ti7~`2w76v0sX)}1wKnBQg@e>0P5J`<rgWf`h+sHCo_yZqlf`Oo|>qn*Kk4+$_ z0Y1`c@Qzerr%)5#6$xfBl?<xI&1&;d_Ftz!d~q-<BLrdxPyp+4)f{I$-o9%L%Ns`s zgzar2lIt=6^H0U@*DP~Ob#U3X(qqfgL8y`vBNCL88Q@(z#QZs&E?g=fZ3Yqu`z0_2 zTPH<M$JT|bKtZIM&@yo&88$c$Au{0~6T}x+FV@g5llO+~20q!K2yP+<%4;v>lNn@~ zY6U&~{wb|N>wRcjy8FpIS*q~ws+pSSiZ0P$oBFTr%F@M?uWqXhZX=@l+MZ)}H}mX& zy;RYmg-${9v!`$Qj*n|K=0ue>9b1-Ae@48c{|`rx$f@I%<9_Gg)s9%)Co9oh4R$2r zGb0{fy_QqW%B7W^X0(ViODD+osok$I9v)^hTjhHV7MoE&bv@OoD`5g`7lb;lIjDIc z+5*)%=uj=X>lPRtRCIrRUW$MCzRy7}Df}EA+Rc}eFrNzV{YKkXpSPtPm0fi7v$xe? zqJfaHMM)$n>F~BT9QH;e_M^F@Cflk`G!x6};?PvMMc*IjW(X`cL_*77Ljy}Wv1Sqj zX`)-?unB4q7*g;`{TUGD$tVsZmiefj7WBuvzh>hnkpHKY<(50snIy;f23ydRJJso# zFe|eOJ)@~6#_oK@#tvB86sBg%@DPBjqQ7xses<j7!=YdIN~g$W=sm30{P!T#kgK#L zPWK=}Fk|G9aM^>`>rT*uBkzOa5S$Q|{Zro$Tv8Y2np&!VbIc3_%anuwhG@fBKp_c# zXhE$q3QLx$dB)IU@bc)ML~~P3=2-6cAp^J^WG&)MOl37|3(%?sM`P~bI>SnYd^;Ln zG0Uj>Fqf%(;UVK0Ld*|U{mqlpejekT=vAtjizn`Dgnn7YSu5f6zxXetZw+gxOC9Bc z_hLrR*el$}DXxyPV9wh}$)X1hNs?auU3)Am|9w}F5}?z%A4eJuZKfEFytsqE;Le!b zrOU<`wu3J)v2bj=W#f{_&+t=Oa#@&Gub7`M8{WFV?u$tG><G<w#fK$PfY(a;vq7@M zEvbrk)V3P`OOv$u)N=QqP2^5a)qOy1GS>TH@rrWA&cW=E0aLY4DG|!6>tUsL_0-2w zy%%#jpO7+LKvXk!K9ckE_iyi9jOQ4nP=!{Y`Ggs2B0bQar-T{7I>Sr^@^6NdpZC+w zOhB0g^q=GcI@=Dk*D7#;;=_T>et~yFy-cTHHHAcY`<^Qx`L{r3WzoBO`X%hs@{YK5 z(Sht$kmtSd=O-lDrz-rYg8S3@l5LiT?HuoRt}9L83U|ZrlQ9%82z71{Y@I(SR5N^R zKSLl8FA?K=p3j+;dNOz}B+_-PsV9YqO$}P}&T`E^%&ObO8KixY1}^m6EO3i)Qvo(@ zh-pE+qNZG&bbbozOySb@hp$dI%sqxQ<n?B}y?@|B?}Da-^Te6+2+Fn*lTWA>C~kBf zkUf?F$}{c>wewV<%yx?lU&Qkmr{SmH(79s1jvsYYO=4BG(4Ghag54q6(^@3mUEYe) z%dyEZgy7}31V^E>=O4$_(=8etFy~csSn%Zq?tRvaVNqP3>gA^n>PLH!x!8ObABGRj z#F@nd9|S=T1@x?qd~cdQKQtedIjGnC4xH{GmEG}CG1JjUkD2`0wc$JcD0c4D$)a$c z8t&)d=&lHsvRn6if!;F%iMz7iUSJ%ui}(oO^*(Lcm_)@iBY?<aXQ?CQkBdUft(pDK zv-2&f-aNRY;KHsVT&O56dL48~`<L}_|5-!+pp$0w>|3(}u&nGH?U9<wQ}@p|F-1?) zBg%`d+UxbxF}fO!Am{j1ox}i)o&34<auHDs@g}ntM~BmaX%u0ZjQWqnAMnPx&y3*S zUbsQ0Y@-lZkDqM?0t!}w{>l1a(H?`V+_I*FW0RijD%Fik#@J_+Iaa3CDwplW^T-Fi z;B(b0??7NXblEc-s#V|r<3O6nkVuTJ%LVOY&h?=|!~&l_@B KNrS8j6QWb!m1N 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≥{IE;dPx+ zTe~vMhsD@FfB9XY6a<bqh@V9r5=l5id7*laN65e@z&YycOCbKR+IZc%YeIa_IIho; z--;1R+7WP4?Gn(XKRtL<Z`W#~2OvoNhhpV-mGiUe>G|uc$9(q9oBA$&fKs**x-|KC z$R*v?U_M5DonEOgp@$F9x@JQ=7c<~3nb5eq_ce8nX8LR8ncfa&81$90Jbsh`iX_Ju zZ<j$}6mS0$7*LKSb^%K@%?}N<$KJrL9I}!9K}`RN%~)L-=24mS&q$7IO0^NXlObjB zo<3JT+28@_Z=@8G4LR#K$P<u;fuUX`$9pI4Y@E;Az^$`~w-Zs#b4OjtK1F8OzMLRn z_7aFOB*AziyR)Ga@Ie}>Cu+tgxFiB(oBC*3<#e_ECZ><mmJnFcgES=TryF?CRKcLh zP<{nm`~X1mni|ap_D=;Cd+E*H$9Z<>{1c^>{LMGnWUzI%-Z~-^IKbNoYqQVC+*AXR zS0CZ2B~PX6JNJR&?3yA5?JkJ5T`NJO3Uyrn(ccB|zPWtC05St|)|aELU$V{J(Jny| zwv!1|Z}mP;h%UjH8)%xB6Q!hPlMSmA6kZo>d<`jxs^0j=1?fuo(e6b@SYq(aKZ>0H zHcl3gAC0|x(SB{tzGcqtO~mfKFn3{2k>%X_d(g-2%F$?;;IV$?K4s`Xf<tt_Dfw;m z8l9Y4-xkq{d)EOWx-xDUL*z89WLk+R+VXYLUDmrlR9hFffGRs0|MJhQ#psWZNjqAB zx(n|s*;u=TevQ8Os3-`y__k>6biKn3u|2y2Qvz+#ODsMdjo)pg)N%Eh8@2D=SX2m8 z>%k_D2PaBB83i{O7a;a{3h|(K^Q}ip#K{&L9EY1okO#h2x%gE08i}b^+GbomW!b6d zK&tF6xDHGl)Ut>Sh`e>%-mL31l}D1TYN=;0&X-&=#f5bNm>sN&0PtK1t<2@mK-zRT zzA63BR+na703-j$IsJW9j6nhzq8!Gg@)C}Z#+j1<dN)O0QyUV%Eem_;tG3QEH)w>T z{f*m2^Kyx}z>WZHYcwV~R%}6}Y6ZF+y=0C(^YsUZFGMX~66&E1v*J9@8ZUYJV1c-x zd#_E2f`R#Q;Oy^gvlwMh!br-TqVaN3DBty6tRRawA#UR^71+mxS9%Q``2!B7VS@Ha z+$x{n@J7C=1G^XCrWq3GW|@h(dd>}H#{^O`o$Kd;j~9IIIWmBhFRi8a-jd1`_m^6O zx>P<T{=K%8%Ln^qaO+_Q&z**Y2bL6wU%HG5iUJc3fcgQfjAGI+5sZlmkBZ;LkPm1O z0t}wEtNIreb~8gtBCG)c2#Mche8+Fbz^XX9N`KXzO$-e5!67V0+ST5Wta4ydh^mE{ zVsF`10YSg07y%-tgxFqs*=!e=vm%He%Up0V3IrirUd>=XNnUW#c^+JC34UgumF5;6 z;4j{=zHT-7vI}HO^xeF5d~qcWoq!4s%?6H!V4oOEe4AO+@0vqpUc*prThab|%xIAs zR<J|rIK|f`hr=b$-$M_PT1}=qW1ea`5dp}hoWBzO<Cw=17G;35N0;HHEA>~1R#7z{ z7_W@a%lBEa$P;)e%<Yv@4ZU|@U^u1=AT*M3vNc}N$Rqhk>a9*vgY@!8cERSN56fD9 zIA;f2`T&xwR0M7|V478~1wTKv={iV6T>vwsO4|Ns0NAOv4cS0RbG7n9+EDeNWlQ~0 zNi^3PX-w<FZLHFSdBchdY{5me>;Pl~2LE9P2-FZ{xYyh%&b9OJcez3B71T?vK4)g9 zhw8RJy`qN0Wh_`r29{o_FKvv}0jCCE?(Of$S$&dtm7jUhGUU2PcqR7g$ZLyUgg{)0 zLZ<T)1g>#Env%Mlx=9^_wC6kB-;=%CU88);W8WOfIZdv(Z*nrADHV@cCi17X^eRC0 zkzD&fte+^wZ%X~Ml>IM0dpa*ec664^Qp9$hpRNyl{!BkOOaDt(`*qf+Zi;7T|2E3U zGw5q<TM`L>%)-K9UOm)y@LDVOXb!{k7}ogyR|Y9r4y-spsr+i&4NRY3>=5{8j8-)b zjqbgyQQ5`U5sFXiL<z9B!3-?0Y)thXOm+0QuX14&rNRmYm;`_#>(MNLOrZf(M$cYR z2+89Zr!HDt_1&e}(}eU>TSvSIGh0Ii&YsxD0G;#(<yvy0A&?}Xf}v!SR@9k%aw?M? z3u+dEgozA7q>(7or6LN&PZMxR&C}pj+3wH-JA77Gkr%9_%sHS42alg(Ck1S`0l%(K zcJ)1W(uW=F*j#3~=2WC%Fw$k^CBXhwdliUnS_WVDv_@j83)Qd!OB?Q!vi>P5fD0M6 zwPqwKI~j5~D*|tKl~LxyngW;d6c1>)XzvuRl=-$HGhf>GH^`MH+xzK$nTr-bu>`9X z<8PObVkE=9Y-;pZzjL+M_k4e#9+gt3IX3@NqMFXN5UK9$`@2i&=77F@u(BW$h|CN` zWBP50N~L-SUc#~Agoeli8$%T@DI?bN4r|)PIkNhrs~Jt^b9iDtY20yrI2lS}vcUFN z()ArQAzRXdX1EVzV5`7_(mqQsXSE`jR7%VXJCf2Sco~6+4+};&s0s{y{WTl_js#bX zbDz;Hsu?~Wrz34FH2MM@{|zf<7kCmQrZN_%ykMg8DnMw&x2p)0*7HX#F>%>TQK2kg zogG2J#*e&z{6C%*O&`<a0N|)u`Gqg>jk%)y5TT<laTtb@VpxDK7*rw=(l06HsWXeA z!Q7mc$7hq0dEt#qlb~!L7Sz;7!ljQ0S09cwOSS4{K>`#|5ga^b`-fTmRAFu<7Ss~0 zC&j>~0<_Ix5w?JE(rZ&9+VT&x8Iz8B#`k4Nc5N0%mowXALxS{js%V)lY}<LAiu89> zjIL(&0{S3;S3>3z4UOA?Bnn7%K*wbEeMBGb457~!pN%G>#|aFpPvkM*0Tav>tLy9q zCsuEGSAxpNDdvU`;VI}Aj@lWb&1Si~nweFxD}_g$3Eoq1#5GWqcWC5b6Viz4^z+=R z<cmN5aM+@v)Jb$em(*l6@Wa_Ht#Qx$8Ew}l4Xap<y_XA?oYUtp!kx<b8Ezq$K~Rke zdvy&o01=c3bI!LSi~0E{FPoOhZS>-**rQ^sGb!xYE@RU(r+=0&l{mDT?Gh(WMv3NR zYFaqSgs$%OA4M3Homqdq+SdF}bJqWW)$vqo7q<UCw8vC=9>~wH$O#IFY~C1N2^l`z zBYKV=k#FDlJ=K$vle;=JcFO-aWNvzDuPRuugIpNfh$2VZe<nC<%Vxh_dJ4J_%l^H- zW_|u-c{UzYq4&E5a{ODtwnFsGclYCWN#GUvUaGUE1B#?d?+%X@JV48+&@B6fC!mMw z?K6g%D>^nNJO;-88cKn`-E41@)?XA7E<~^d)0wou_k7YI))ieoARDjSGe#Sa6U(-& zYF}wGh}P4lt8Uk9IrSVDJX`Pvn&2bRkN*BSXE!TrqT2^I_^p3f1<xMYM*k{T-0nS{ z8|@k04y>6Ry>f??AXn>g;VAOdLuN|TkcVw|$up?glg{mbtan;2^KkB7$_Ci$cUu11 z6B*kTQG%7qVAnC&W~U0TjyQParfhfp68Du(+JuJH6y}(4V?f-AV$2597SFrJ=5MWX zPkoi}s72jO`^ybt>8<$M!$nK-Es_;7^H}uae<Dowm5>X+M+iuY<=Nm=`dH>(?i-t3 zPW06(mDnU@f3GZTrjz6CW0gdQ$W`-;%r9i#InL7xw`#tf5sNk7IQw{l32}(kc${SE zx1dtf^EC6{Wz&c@)Of7Lh=}94+l-6dzd%Rv@;ed5gEsSY>LiPXX9P1ohbGJ@G9i)r zgm$STc6%PGib_9PbWOqcj_t{c#1k?cVqHQN)9&$HC%;`u*?L8r4QiZV!bhD~7&l!{ z_K*z77R`#+PqsDN<>#@GN()?<E?wMSEy_rGrkXfxU0e#P!wfUaM5X5m^Nvw=9R}!C z`y_R0u0;>cit)N!9A&IF(n`q`Cs<aV(Xd#0ExEt=QG+A$LTVioRdn*((}XT*tS6-{ zy-m)hzU^#fe{|MF3hxU6%_YL_L+|AUEJYPFuJkp{iB_W=XG<9ks&s4g2uW$;*>aDS z<?0(EJ%TEB*jTs1$v}wtm$w!+!$msImSL#o3sY$_L)WxKSqxsEDV<gnbnhFHBbnPa zVLIP_3kJ>?c+-v`)|eP0B0Yy7(f{g*Sad1o=Tw`Gb{5}U(q2YOvl@^JqCJgOZ`;XB z`#r$&O?)bacMGadvE>&VYE6b}yJl*<b@e59&z!p#sef!w10wCsjFmb_M)^9Z4>170 zl2=R)tCea6F$5`U`+1n%nWig&x8iV|^Z8`QHPTzh^B!3T`Q?&$LP2s&h3)L>#c8p= zo0mVQ%3o+V8QY4GfJervms9dE7Z7GKR=XRl;M0ugw&kT^=vvm;lsolXOP^o8jHfPF zt?^tX$)hKwMbA7MEne!-2$DpS?0~6wMLFLTNFr?fT3#O$RdW!owg)LpVeXq;;a|=n zq4=S65@CxZFTYr<W%NO9GQzSNGHL;7>4fjD2mu)uBfl+X(E~o**Q;8VyC2S!s+TBb z3Az3Io695Fw~X#BWM^#;@hkTR?KdrAL!V2;#{c;e`@JOA2^>t$+HT?>{bFY)M~*JP z7BsH;k)*uN@3$DEc$`=M?f-}DN%?Ql+V8pB&b6C@KW9(tM%zXYmj1zFe<yRcVLBXf zbea<ta+bl}SP!=`)wOQnd9^KO*m3t-!_X%LC`sueJl?20?Gk2-OqG3<`AU;jE{2(0 zHfn--WSM9?!deP1gAIu{(UE#X1fj56`JUIP#);tHXbC>E!PMykUaJklL9Slp@h_4* z3N8yA>fUAVZ>{{IDLGVIX4r|)8b#8e7$fmQgx3*oMbgL6unF>!)e%E5!1JUhKvPt) z$2d|U^Dx8TuIWVTug`Kao^8Uk=1&;0A;IN$SHMHnqZl1+8`sNs-+HCR=00(4u4pu) z0qOhU;1jE$UFT$<c+rLC5x>G62kd{@Sl`0$IuOd4u1OY=%dwI|u6AS0c;u-?TT9q! zDzpYd5iR6!K15Nt1<k`{n3z6ynLO`VHVu{x?^v~L{Z^aob5eAw82jEBF|qS}f`xEc zk_&Y@eK0;Evd<I;m%%Fo^|JiYgOYg`LcH%baZ9;Sq|^_KvM7*K9qRXGM7F|eF;M>b zQke(dH$M>}K!VQ${-Z-r#sVwFpyPf-Xh8X*(i}}Q0owjc8lM(^1Fr4+n$79E-`Bdt z1CcNx+FHK!1zmx}bCDSouY8Lw?+WAQD?vBiBf^NR+8Z5xc{0<Ihnmgr5xzywFh;nD zn;Zrr7Gc9pRbE`^_}lqZIQU^^l*|@3bB6uw8H~@*2Y3oGBcKGdqB`7hbg{L9Bu3}? zY0i#eQ9lE+#;e6$^4+aAnic6UC@Z|*&_-%(NfZiHWgw5ItNZ;uCzhX+d4@5X$=y~Y zSM2o0$=1}dmgcmd>FT@9CT16k@D?nMTmC~cu-V#^s7e?lg7weUcq38wzLtOMIQ7nC z+==u>co6=c7tWyfixRI41)~-0AMu1VqK(~6eEAk-CNsZ&Ti_!~`iMLcc&)fcd%?R3 zQ>HY~L1O15@lcuP`l(8%RR$+he*)<u96X1b^F&Vw;TBm-0js1A3}yKDeQ^EJ#gt-m z{T5FLW>u_gS09oCfd*;JIqa3g)I=u})(ADxp?baL!TpT5b3Pxdv%Ol+1x(;<n5i%C z2<@!^`i3lpqre==p;?n(NY~um{w3O1ZY|+|T}odxgxQ=2l0QFx{7JbRKDeOx(?(Ku z^H<%k?s3^@hr!?Z=cB{w|6b%vqlEH$7JQUd|0iF+rH}rIYnP?{BEI*D#S1F$m?5|8 zaFE{z41coEp2%9gt|C_)!fr027nRnUR=ti``P$#VmWTi5jKJ2@s69L*oJz;NN%$zJ z$|>P~X4-hzX<4qHQ*=}S?ReR{jGhod#Mmvtr{Kn8MV?AW8+5f^a5n+pn?+WSo1i2b zAv1Kg7*j3IspX9h>8AQ7p6AqRWdYOI#Cw**PT`dA-fDdMP24zG@$838jq8qA)OG;4 z4az-AV->M&CH=S4&1CeixG9lE94%Vyif0%t=4b|`6yK=OM=EXHnf=B7RJxcKyfv%T zRE_ge#s+PWmT1CP$2Grk@JmdvF;ZZx8GkU;XZP1I^b5wX;SUxQtYmu;7WN4yf$XD^ zL;bQF(d-;uoY-`36Qn+UeK&6~#~axfPv;B7wY(&iq0`cs1JG^|I|ra0Mf+2x%eFXX zz)?0Sc2^-vK4!9xWUU*izsPVp#d$QF4|sz|eOY0cu3)fjDDBq5ytQ&qKrJ5dXEVsD zU?(hvGY8x2on_&v((EV0ncAq}pChH4<)f)*{+``??ZXu(io*YX>s4Rbwp>14j@d`X z7dlQzM6bfAIT|HbOWCagH}$I~J;>7#!s0H<A$dv{mCrP}D#+sXgiW@*%MB){U^zoZ zT#0m4SRtAm17^#yW^!q$wOoXTeB2F{@3&CAxZ;08utMA>W(-|zWz4#$KUE8z4=FX( zSKrJaM4({9LXoI_4b+f^$M#tCbC_{V!xbaLlc=#vNsMx*C<EoQ+GT=H)%s&rtqz4> zEvSTt)*rdrGw_JRkcX2DVV^@IglK8_(mxhfE>4lWn&fB<B7{YCAq<A-;9yRMce^@< z*^g8+7^0+oyELOUigljhGhi3;Er;^lTthyG*4b%4kTY<lAGVkgUrY6d=v-7E6Ms_B zmaf^>uqP^tSub65MItgPV*|H??dm%ir537#y0ft`RYbhyu}Kh8q^Yo72#fOOH#vFb z9+4X}IWLGJ+<_oRPl{<h<(V%ZE6LizqvA|T+B5@Ws~2}U3q5h_?zHq#$pOU$iII~9 z-~NnmR!P$?{p-SW>j6r`0!dHG6f|>=%rZ3dMS1Y4nb2Y{p~qte59A*mMk>gh&rEo{ z@Juf6KU;)iToA9`1xoaIY#Ei3JDr7ILjUmRPgi9Lnb!X+sZP(uS^oX_m*USk#v`WK zrKDI7Fe&&k_~Z9S(Raf?I&*BrZo2;rjIS1^4gEU}KYgJqDqK5rb$9Rk=+po4Ty*WX zsL$L-Ujnh){wE~=P5<Bhx0Pr2Y<>@pPbWUdrWB@p8L&M;i4U-VAL%xMCPya9Mfewr z5C2nnHjoPoFhnQ_P5DaY&s*5^7e(}SX`j;U6o0%l50Ro$duJYH&Dz}94Hb|&Jd|y< z*;shUEM26!z^&;+Nb;iLHRqV=tSeqpIPowq;h`dyhainzg1i+V)nHKIHesjFa}!zy zMRJ1bYGA&GcGvC}(pCF}<L-A_!oM#>*FVra6u?80xc3?p{wYPG&Xh2yT2!e;fE#-$ z;zlohc<zZaI8q><yzyEcTJwx;glQ@$f43<5<<_JXbC5BG3wgR!)Gx)E`A$m(b^o17 z=umJk!z&I-4`WLZF0#u_Y1y1vd9wAj>23P8$#lDIcf1l;bI&i$x=mekSR6YUYEvTa zuQE%~2y7CpHX+S*sAj!Mh8Gho9(Jedbw?>%fs*-Qu?7jY1Y3?`Mh3>gThYhK3Anb$ zLF=n%cexOAN@ma$q%J*o6*kMdjsw#aJedb*uKe2?j-J*fUvS^)B6JU1yu~pY-{RjH zKPVd0qkF+1B#lkcYP@CgqXa9Ne}pV@{%k4OYTa<(ji(uFWF_wAkh@*mU^Dz-Gbzhu zFMse(+Fd>y{1vcySK;@2E-ct`QKd;;)9`6t0yJda#r!@Z{!&!Lk+=aqJhdNmAM#i{ zO-`K$u~oYmxH$W?mnc2Wc3BK^5G^9)Cp#HzhN0wyLtK-k=#-Ck6r(&js-B8eoBfI^ zcKT5xhAl5>Sh(v!id4OYGWK5?G?S-zNzt>Y^~~=x5zeypvE`Jqf*5Mr4<2rW(D@to zJ8i#ceDV;GUco&M#<ZSP&?Zk4e4#c{qdcb?M4x`mJm-jrrhiC$G90O(jqlfCyPIuz z_&lpr^y|c)j%%03$-+a_$3v9a%5j22=F?-OG%K6Wo95h-m|rCH6Brgmg>!zF3t9`q z9`bDt4w$S^W2%Lm9A#STxV0eYImbRq+2395<LpVVIN2UF92bB4km?G~*}6<}sL@Sh zR6NY$=^xSs%BE4|_){|X*(kp`pHf<2NH8pZFlbHQa*|>Lm5zf4O^Yq#4a?-=+1%cR z-}=Kz+c(*6uGo=4N2YAL??Nh`-HP1OksXq4g%{~8X!;6jRcDjiVyAcs3J+YVe0l5L z*i=3Su^>PG|E~3BwAi`-UWwnX<!xHk-7VwaEU`=HzbFz`|1PE<Y2p&&4XgTldl4L4 zFJ9*S*=D#Kv4nIt`V2RokFNb0^_k}P#i4k*?f3k(ja<8cYN}va{+H?Sq;YLm{SIYJ z@pw$+ItIdla$l4G3#N<U@dHxAV4I%nX@##a^E?H$y_rm<Wb6l5s##M7PMgsCoqIcd z_Up8vQ2O3*AzJVev&;2faLJQ}^T}#e_IGCBjuZLIkAv0iFK2*H7dvy`VTU%^gn)Ee zAtqWF)av`W`P(}5^boRKC(yR0xJP2)(~zR@=Q5B~j>MzXZt6P<+?Gf0FF&wc7rzSY zNf?|Lyp<jIq-psaN;>)aS-j5f!EmH_B+Flqzpp~}#$u?mtQpKo**}zD>+|Cr;xgWQ zxo0RWN7+-K)4M1u&)VxBFQb7ImNlT?zl>g8>hD^P?!(fut57j$-aT|R*~OjgJ=@+t zi<f!8Yw0D)#&R}8Kxhp9Z;U`2x6wUwOb;UiH6tl@&-vsPPj*r4W9|4M&RfUS7OIE$ zP1V%}wdj!&d^4q=tJ%LcU|dT$np71r5e-B}GvDSyOn2_VN0i_b;gP2w6!4oINi7qF z({VYcm!2(NRiGi|uHVveok|Y{|6Uz8@J7|2`&75nQr?=lMfA9?C}=l5e|F=LI;Pm^ zJxUY=mGYvk+WQC!l{g`>up0PviK;X@wR+i$PTMtQi*->PH!Gu~{@?FJIEMMM?~1a1 z-C#I6ofGK_oSwu5ur%|?7u&44TfBN90q+jECOPx%TeT#W=!2ekinhqly@|jAb%gV{ zQ7W&V5r^snE{&~+b&38GCq%XFY<AD5(rX~)P@X5o`F?dmnvx>*z~JGx5uf_5L&q{& z93zu1W>ceNlvC7BKwe~9H;UMM7L3U^zeAa<By{;naP^GN#a-VLp;AGI?iQ6^n{`u} zU7C%)(X{gozzD>tH%;1C49kr}`=KwoEm7sUvg};eU@vmk)weocy<CeiDbgl)(b(v& zaIiJbKorH+Bd{;hJO2_MG-Nog<ISsuw#_zS6z-7N2hm4<bcvqlA-)5H!S**&q%+}@ zy&+ZtbG9{g^stc?X=)8^NY;<_KBf5wR04P!%}w>03s~7&Sf*t7jWnGI4jv*ySsbd; z3-EHGzjT$<{V!pt_JI~hu1Yh>)hvQZdbAh!+7E^;b27g=WRp?NrHp20#2dx7*15fE zHkLl$Y+VcpsBp*!5i_j}-&l_mZ=@Dm9k5_cV~hsU@0(ruCAACvy0H}%^6fs1`uXoX z{GWaCz0l>Xo+A~!m5Jqk$>%+VpD|OG!I;r41%gDFK1}|-03cFw3s7wPlmWE{c+uh& z=+NuWE}9RiKDrMi>HL~tY2r9a)_v5t$oynAS`Z;r_;*Y;oe68})AJ~&%zf6kJ!3s? zk;yCffz4!Uh@+pq`k1hkrL}>6lFKY=CLoSF%<&|=g8BBt1?eZ|ww{+EXpwU@Ere%G zq?#Q12ih21Zy)0nCm4J1g2QK0sLw6@hWiNYe8q8i&?4pA%(h-to&?(pn;*U6np8o^ z%9k(=-c`|>>HOv*N?-cqT=>>Z=(OVKB0X(7#m)8?d5a}~W&hBX=jgI?9`&e}XEzP^ zo`SuV+VUZ@@J>;*L8K+48ZYHOU62`Nfw7yVj6Lcxh{dURIQ7a{-(%Xw35)#<K27zv z_Y=6|mo`}p73rwI?A|0?V8*cXrG1l;3u1CFQVO-xhNr6p4lRM#s7kU37Ye9x3!r0s z;x5H}q^%o|_ad-Q#nBMo_|deb=jgp%Xtz7RsEo?lh>HKtS*h_J>vtyU#G`!1;9UK< z=NdXlDg09}awhhEf<@PK8L7W^HxVOU{k|p;^MM&5;K(8nn{6t`CRVvEMFJl5x$9^~ zUn-j#V2K9JeoMTEajdMUbr*Hq&0C7D!$W8uKSvff0@}+}N^`FCt8`xoQF>_QxY+hD zw_s5rtyYZRje|uKahpbS?fv#R(LDsC<-F!cxma(MXGJ(~GQY4^mDqOVdE_R8V!_g@ zTO~P>YAfq7u%6k2wPlaH*A*SI<;h*ZaCmzY2o0BQH(WwCZSF@HR5&Fpn~%+qBiZr~ z>U^2@lF?-Co5F`nN$%K{s(j;AAy+qI?QgOy@e+MwYLcWbgoE+z<=Xdz!YwyM1YU}4 ztePCli=2uolews{GED(;%Nx|`PhphjuQRwcg(G=*I5k^%3Y}@23!Yb<3*_hd|7i)a z12_kWkafR8v#sJ`+RpKtpC}5&11i`zc^O4OZZ`A{#m<gC%bRXfDt=h+!vkStZ#2q? zjY1Vca)*~jr+6=Navju0`PcesbY~g_AV}K9w&dKKW$*-3A&X4NpB{%Bm6KnHyACB8 z=7khor-xY#($u~$yIw9LUmEKFyAb_3`0+RN{%PfxTiv+`pX;vsKm`eBBAv9y%bG%l zBR;-+%uQdrgZs(LUhznYC&bI2FAwLuo=JpXPaaShW>qi#Z`=FdK$cNS1Kag$=`FhJ zHx9mIaBWec*zXfAE{0-snx3av^nx;_T1dq!VWj^yv<)kUTFOCbCLn|afPkKdhb(Oy zV=))v9I}@t&s>PMK1pKYQnzE}$b$>D%wvl0-Z6_8_g$PD3ynSu)Pd)+?vOow`$4Jh z>H9<lZBSsFx{d>kg-r@x9&7%VTqn|IrD%UGfW<oSEv&8jrXCZG4LW6e<a&C7$tW`C z-nBQ3IB#Y`?!zOD4lyl!t2BcymzxtVK#_mf@LNzgr}lah$?$=^KK8M!|4gqLBCVah zM1-F9ozc{2gY#E?92$*I&AIQc1Lo-W8R572Oa@$4%9=b*Wiu`NlKQpHBsFdTY2o-O z+|VwYco8>6Qkj9Q_pT>=7WZfC2j6GeX0G~?epzLrh>p($lr1vxvk|=_@UzwHJE_vj zM49<>kzw75)K10J7oLt`e@yOD+s2z`n3EkkyhjBoQ_IL0ya;HNb^>tPc67jj&M+JJ zslU(r&Z4(ID>p=br52XnW=((W6N4L|ugw-8P#Ch+b{|zSUK&_@85*(J*mnt6yUpu5 z{@J4MVU!4h#I+&tlO&tBBuazmrf6L6*TtgJ^ZgQ6K2`7b`kUv^VhDp4;d__SFsVU< z43Xt)UoXn)8<W%7f{F0m5N^b)mVaYh^ek&vV52CNhDS9Y<iE<EPQe2?TuRh5aept5 zWhwQYxRqk}r(8_5s&vM)xqlkLU(0>r%SA_xk5wU7m>tZ*8+|bV&;~tqjf<$mNouwo z2;_4$!Y^xV&gcLxyz>&&@byQ|d2;~1$H9}6g_%T&f^9v`;)U*4k!|B1vzaQPvfk+C zgJT4Lj*M;%ArDV~3GPy!hMvNo?w*c}z*@^_iuG~7i=3_57|-~X=T3Xl`umzBPbkj5 ziRY+hN%xj`x&mJLN=N0O-jm;Ba_?!kD?XljblP*(YVRMq5xk9(;A^!i7O7Ci(J|!E zLW~N(sjwW4N;(2Tc9x)A{|7H)My}_A!ohHQwTOy0&KcRS4)A<iX1skI!|Z%w^O)|e z+`F|;bebR_Zcq_JtdwvrDCEpZaMhp%zhny!KlqR1h?B@ISuN)r%HCG`{D__yQ){fH zp1OR7)69UAJXb5sHd;nzhSg(hv*$X?);{KY=-<{TX~@HE7x(1@hM;<etX;{ES_Mf& zZnDy|r?OX6b+JlM=l`$ddcEWbh~6+Oub<+1&ZuTmM5u~~T^Xfh5<Rb1P}+89W11Qg z8g7)aP2a|Tn1N9r55EerJmWT8KpsC-H=NfYIU-S{ioi<Fuux!Qsmc&eMDi*9zCDJ{ z35~3aQ;a;YYkIq#js2X4G+S2n`ACBE&A><+?b`_&SOliePldE4<HLnZPHO%uXrNVe zEX|H!9G<97ff|K%R5#BprBk?B@v)vzC2Dno8p9NKAMw}O^GrG+x2;##kgbR`*U~v{ zT3;PH>MHTbjxO~5i1ef*7)pj0p)392n-gC7HJJ@gMzs$+UadC8nPsdwBZeGGGy82M z0Q>}J2_`Z@yC{Iu5RJv#l)Q*Gs37)J4_sEPV$&M4eZzfTU!9F0O3L}$d^%-jiaCdj z5fTD;JqqL{eZF!79!F(tqP8o9oT|!+h-YM9B_IA!L2YiQ%3niy*gg*C5)VZlOZKfV zqg7K$^HP-R(}{pJ5m)K$<<^0lQ2V7SiW~O>?!<6d(X)X0j61(bFnjvN{5UreuZUlN z-;FEoMLoaOMyXHXJ$X7pbGUCUjSe>EJSLip)UvBN*JLPHdciZ0Lq?Z30&^KQAuaU< zR-YIaF9{i2zQLIt`r-}7<&=?0dn6)(>_9PEg$1AN@a6#R#$iA<DJuR>Gt_F=d}=fP z!oQdw6yugx$ZiuX%b&OiA)2k>58Nv_L+`a80_Aa{FPN;jjGG&29F9{z9=gt2i`i^8 zR|HwGV3>9NDi@4cDYO=)u}*J<eKQa5E5eG|i;#Fs_;Krf_v26Vn#@yJaqGpLNUUG+ zMtzQz$75B%9l!D&irAl)I~@PLn~PQm6;5){cxsu|0EG`N=qB2cIUD|r#hlApFsWVW z3h=e({u1h=c}L)LdJYZ}HAG#n@-iO8)o*ZYSCMnIde^0{S55xz*6d_Hq4Ls?fLr^7 z5^oUM#|n))6P>K~<|BY5`<k43+MN~*lEW(l)&hdv&0XJLbTsx4zfc$IBpdv<@iLoB zUHBSenfPULm`CM2KZgEDCCOPu++pD^Gn(0BdO80B1i5nG<1D|0p40bg42`n=^&cMj z(&s}6#aH2b`RIsxY&lj7j&c{80+|T$9WWnsr$r4gUr)d93%mMhP-b*Ac|h{+|4#YL zlupm(HLiLw_btB~AG*<LA;%BFC;x1gpN~u}^`7NsWF{u*%(<))yd7`;&GWqME^)3F zLq6D|-gj|%A;^S0I8)Ukbx>nAVtkMqt~|XGR-Dhmc&Pe(!2y<Tf}SJO1_X_RuBp*| zMEf*tz*pY7!hk}i@RiX5qj!#}?qNA4L9&pQ3zo3h4Me^!Gxr)sx%5Cv0UtX`n#-GW zs+RZ-E&hnUFYVfFG%131srqaECBPw75u<Ub`m*z1L!;O=yPV7NBh(NSm1mD7`i8Em z#p`LS(74htcoQzy+RG0jLhTPnMnErrY|Sd!SEN&eLB#KnX|-gvPZmAnmw)xvQJ4BI zE~*XSEAcCUhO5ZSM3$$rA<yvE4-Z|<BB^!<E95he+-&QlUFoE+$$g~p@{RdE!X>kv zR#9J7jIDeENdbvSy?##tK>4;&-vmrj%#>#<4zNu_M9n!^iP~Iz`6}1@ViJsfc#d5G zG+TC^`Ng2c{}=9&Zc&q#RN=n#;TwQFUt-oY<nR)pNx&;zC5Kr60g{lL0-FI(J@+JN z{~EY!*=_xbd<MGEzESn{ocfN<-gxNd)LcKh{{Z2IW#v;q`TlU^r(E>!yw{))EW_NY zl{}P;R_zZ=Tczu6-ncsEtJG7eP;GYcy@r&;p^?LcV01U`sX{99zo1&H3s|6Fg`R*T zK-H7FuFs?JGds+SoF-~oFs84t_>#zt+R0pZI6}zDT<h7%xTrLp(SiBlUUc2<R}1V| zBTZ29DXDMsb}ZsuLPeesQ!c9hMnAD_`FoEX|3;g7X{Vfzf$r<{#W%_k@>mqvFJ^N4 z`Dw#(t1pJJJLL=y@I-J#-bM_EZ^Vd_eRVkF=$QEd`6a^X`jU}c04EvHwWELd(D?^s zA1d{8BzRaW{A~MS*%<LRN8BPWvQRJe`AB_ulu#DpkcX$PK&ki6V$l4%JA6P|WDu&P zj`8B@4&2_sGSq}$?MwU{Wxj~~hD55qsMwus*EZ{_`m|LwuOLc*A?eXPVk(fHB89$l z=t^4z8Ma;9$i-5|`V0N)Q_YNEi-N7ErOfLM!Aar6+-ljn^N8zNR5i;6g{<1Q9@(kh zuNJ<!i+(ti%q}JS;p7n|4~LQEcQQlt_22Ded$9xa?e8-$zx6W@zu~nHf2RGXFCLy^ z_SjpGnm?Z*{EPW<JG_id@(B-~?vyETGB!2ZnZ;AsCYQ@ak8Ce*{wS$cN^)kp@YU*j z@#<L85odhZER?7ej<|p7YKec8EWSEY+KQf3Dsql&;5%>7JvDK75H6jFsyFDG^H`{Q zpUJ-fFPo`%$_6l|gbdABqJ`&Hq)cfsL1y|u-4MGwr=S*W6XhRWyt{ZqI1KlWzHe@I zLDp(z5lfz*G65XU&ad>>7T}6wTyjYnNC(kj(ga!B$n2oGl5Fu6h{N)v3gypm4DLEu zz`H=<rzAk*lPyFNv9(}X$t}78y+N4QLUwHk*+ilChBv=iaf8Uvu31-&D}vs;^EyFu z0+$ym;oqaBKu;`W73BnuH!H7J(VUKFH{une?V2Rr&>RwhBCx%oSwP$KQhauL99Kk= zD+awMD+ql4YLb>)06VbXwfzQmI2ud`k2QzT4<#2+UBaDfu_%1YS1CipHOuCHN8Xx; zPD}wn3m~0%jrWNb5UsD<tOwhe_W9feDVyqPxHdd;2^3}^lV#Z<Bph0F1U92kGF=I` zqgVQviK|Yg{l`A!5yJn_28t6Wt3ql4C0;=Qvv~(g)acna{sb5c=ZeDlMO)#WRdiLx z%G<FRfkGsGWuEc;QW8Z)3R+N!KE&1jMhJsG@riS4Oop%Aweqgz@N>(yWsRrf*r~MY z<<KCbnuTB`f352;42MGvGHW$jB1HC$nq0jTnXE>qFoAEx4uG+!3cv?AG8s}LYcR&o z(rABwPBK@3%;e|zeM}#ilNo90r<><f@+Qv*{5kvECDvPzgT3Dt_N+2)Kd7H1;)F47 zy}rX7TgS8VZ}QgK{nAr~`*;Y?rRu$a$^`tNwzP>F4w?j`i0&<)&~1R>FKKr`Z;R@< z7W2<jF5EYvbJv^ZUsrU_r{Fo7HG+)6Un6Wd?qD5Q%x=p?BzHrT<aw6gj1~~h4${Ea z8ATu4{$sH81@?hm4bh%z(=8oYo}T2s#-z9bgd7=*PVGJilX%9HxOr%b#gt3_$N9Qb zieV!dvJ4xG-rUxDtr^F=aszg?;mYy8t1sBmWY()5SvP8z-xQ_WWaXZZXAmXDZr6Nr zr<jGHpGB$7+^Zy?*a}{2P|(!<kf1nKePs9ka3A{fKQHCq=LqZLZ6vp2InJ$*%^hp4 zC_dJRM$4VbYY40N`hOOmP7Kx_4gbZn&KyvXv^`!gMQIEc8M>C57M7qz>g&D;OmQEY z-K&V;Z<GY6Epj@28u=S)G%{EIO+KP{PNsJN2*M5_C@qZ;p+qXpsZ~~nCcKH9m+?A# z30|{$xGVzD5oC=Is-xP=ip?P|v^%p$INmGIpcBv*@o!K4DhE<c*REx>=N_UhMeO-< z`5}@UL|;V%WcS+~P8p#%Xk4{jh=a1pFrMB7hM=BsD?&Y7CO01k-vAUYHC-lYN55hZ z{0QNkYUjxh`puAcUV|FFV-g`Hm!V9A4(d0@Dq5LGit=oyzJ2n-bhJ1+DE-T5^AAzp z!ke=(I?eMBO;-rMIu~B<GB~(!Iu}Dqr3s7xy}N<L=R=U#u3o`5KhCv>;b$+(VA~hF z+xb-SD!3Rg&{BUaf6D`#YOBTxt$9n9zGTJnvO8_{yn_XNiUM@!@$HDyQFBRpR%vZw z+ze3tq~!(ozZ}dWbGGkqq7?k8=Yy$#fJX(5uY8rBC&ZyCEPdE9B*VQQpyOhmZ2zHB zZr6*7Sm`I<b>R1T0=wX%YhoI^s3kPPAhS*WQhx2o4ldQm=5G~u?kfsbff7gq(|#*q z^E)=d(PZTgan#ACiI;DZo9e1WCN&_$<!?O>b5p<g9=B_d&}LUh@;I;&11hyJJhTx% z2J?N^J=@2KZ1Chz<`{7B3E<&$xU>+xYAoWs6lwDGw$%8Y@lfa7i4}Q7e05Y2gXCXc zv-Mu?mb%^&mXb6>u}s@wNLWVWAU&FmuI@EanvymmWoB5VvM+xM8uv&XEe$k2a|KYH z@AoyH(yiZT<*Vx(Mne<AVa&8sFU@d}bSF^pAPG$ho38@K;i&|nv47!4G5il2jf3fM zVqD3*Lmz6C=H$o^T-Hptyv(|s&t7Vq@HFEFcnbq91}!WUqler~?$`>SnnN}S&Q+Ke zhi@_;Ax0KsiIS%Cl$S<R?Pd4Tf~Z7?8+9_uq*GZVP-tO{V3W|I2m?ZlF=)eeCul}2 zvp4wp3rg+6hja$DQvlxe-8l6;)b!QYRieZ*?2@a+cW9IE4>P3?M=a))lKJX1TAaNB z%W=2<!VvAkElyzWVso}HOUG{_(h86iX2?lsUBM8FZx>)xv0{!a-Wq9aPjP9Pd;7-< zGdh*=U-Y=$^Zu7s>HZbMy3xJoc+Op><=J~Xc>h}*-@nUZyc=t`W5{CX(y`X`3p%&& zAOyFaM*AcGf#*JX>{m3dQsbbV@mn^{oOniA`@oPI3ykYNz(JCKY^qfpL_|vEv%v*M zGdJ-tb72j3qO`pwONGgjmcj|8x#$`7ptnQcX6?%sjLpQvz3xw2ti8B6a+?6G;%n7l zX(6pj0JptiWi;!KSar#7c<sZpU=~3ut^U@eKL<Oz{_Ho(jwwKDkcBn#LqO>zs`|Tk zH;_r{4>@uhcU#0|63YTZ4Kq%%t*|(zhuLnF*<evj{~COnkODV8TRQ6&ZkP^25K4T~ z(Qk3rNJY*v@<HgyLDA|scboNtd}I6jWH0Ixn^=^1=GwQ?2HkJ^OjSJiAkugw8vqMn z^gZVG8C_PTt38~JX`Wza!**kmT8BC?svVyKrh&U9kDZwZA|=@$zI2npoxP~e*Zu}& zymT>6PCfzk8c2nnQn;wGzwpVHVak2i*B+Zmm*4}aMdVU_dHjaHXSa%$ok8c~4d);x z7-5~dG9Q%}Hs5n)`#>vy1KFEZ`X<hqjF_GJfO|z^3ZqE#w6z;wp-jJ=QY#d&k_+EW zKidfGc{y0Si!0X=GEb!At%%1%qoalpjh#ov7yiLAN<MnqI2O}{)GZ1bqJltHYJ(@& zRx!RnpZ?*@^zvMmT(`_)=N?G$o-@8^0Ln<G(sw{s6tQfoR{k4$QmRgHXv$skD&71r zL{u$5&1sNO{n&R*hwH@BW-0x_RTzpQlN58bau|4XG~IL~HJGHM7ApI~=n#*a$XnAs zd~$r!B?=CYyKPIYN`=~;fM2}&?c75a*<=bY#b~8oO*JOi5`BG|URT8ou5Qj_b8G=R z>=F$-7z2soV_MyFW4KkMky)91USGq-j$dM8dy7gOT{ZGqHRJ)<0SW@Mkf~Z-ZLPt~ z)h2SFtW?~aeK|OE^$p718iy8Qms)1PRc%^Vq4=23CX3H_zgXyfFpGELEzvqg_gwD% zS?w$?8Li39D!O%`MgBD)ZY6j`26tQ2)|~P`0%gmZSSt`1!V^G=wH9cw<w!@z=hG^J z9mAey^K+w9O-;9%_PBEde~8T)5(Tx!2kK0UbObmZPAx>1Nc-<EK_xw0Otwu}_#r@; zL~&g)GLqse9EL*F$1xl{u^UO;Z2Q9kpp3w{jMvvLdkT!vl(@Yo&uTYz>$CZ{s<3JT z;|I>I{P-68(o@?Uir?Lh{yBl)@5D3zwsj1@@^Pbkd+zpgZ}!`>A6QQ^hcekO|8})p z_z(P>M|Hc8u1pz4rGQVG0|5zuaAnsbgQttHC%Nm5<40!MXWntfYs^GxM9Gg96<uB^ zUWrFykPX%F`WW)6pPsxXMs%2OzhF~)GQ;^`JI1n{>ub-6tx^59@3hnM5=tx1ZLAYQ zDD3Sha|sQS>}^stIxkCeL7FV&?27;VQZA~sB8XmoSFy18{b}g2z7iX8_8bFCg7f>} z&!GsB>h&8Mj)HSXgpyzRj@5YfIZYbTLk$k!`2JKF2-(5pBF_+HBbxNp;r^$)-@~l2 z%757@l^;4+*$**mO<Vc(rr&C_o_YQra7E55QPcOt>A8Z_8CE0V-+7f|EJjHdScQ!^ zk~y^mabldQ_hu_&F#-wPrPHk5$-OVWZcXl0f__@GB@HZH1d=@J47wYKo<2OYF0Mw& z$`b*Ydv(DiR)IQy<^QK3ygPi(hIFb{UP-AEPM@CB9=_MPcj2jycmm+?W-=fcE?xXZ zn^CI_YyIfn)0tuRT2KFQvtHcPNu$##*^6cTlAbu1ua6~T=F0m|D|WW6@CMYrGy%&V z=oK-?<?}u3omy*f$kXX)bbif`lm_i?-2wSuziblB3O!v|ILezgZP_~~FJx;`323Wu zT-V&cko)xQeMQs|=T>i-{ZJK@ufSR5t16`~nw3$oQ4}omY|l&5XjWE2-`nWCHLc#c zL1tP7Wjs0yXnb2{?!3;4N^FKDYuBUyB$qCl25+_PX6kFF=jzaX|J}AL;{It!;QX8O z1tA7xYZd)2S5Ur+MtTR}vZbp)WLfJXYB*1nVu9x!|1&^A_Y#JF4d=4pq#m30*ec;+ zl45gkA*9<>_JOt8rorfM`VnJrbm-DLf=_9y*_Jo#i(=t9U_*Xpg9CU(O(&}94P+wI zxo?h*W2B2Vp)xPP5SrdA)&B9XtR-IEtCk>?dtV9Ku5GDC7C?Z2!8q-JjLJ={A8B3o zj-qs%X`irw1QqZSDoG;tN;)l&M)zfD{1(bPkL$><&{RZt0t*BrAL9A_!BBl3#x4=} z*6e+IFTY`+IpOT${3z*gOnc%wx-4^#x4w!FREWuT(GMM)So(+Nq^A?|UNyU8;HNaj zHsjzp1$O-Q>Z6+6q|xDen|ST4Z60@@(Fob=Q*?^J{%aF)eg#<2t^WdQD-4qYo~8-% z<?g+W*l&l|T)W0uS#s_tNyz^e+0u*sidX*oljN`e4cgPHW5xyCp#I}rJK^`S|H!*P zHm?4GccrWf9LKNH`D>Q=4u5OdFO-~4RGe+VfO;i_<lBWP`5^+=Bn*Xr+mjpE3g1Qn zjLiv7=@OsL#}@mM|MQK>S&kJ*%P-Cyd}An`Y-M;N_&$iM(7A3x&ji#n<`uu7FV7>h zpCs;GMOlub#%`Y_JF0lDxHq9|^eUWy2X5-tfs`^ZhAF2D|9Qq#D3MMSX2mk;R7s<G zAR)5KMF`ND*=WJS)iD}XAx&?sN@X?{faVObIEm8_HEdhE2BL5g^<Ol*EKDR+tGnf2 z`%wGi71*hZm7;NB*Zl-nZ(z()L8DNt>N4`vx_-qSgZG&l-EXB=;~_fErE}pkEA#MZ z;m{qyYlwR#q(WJ{8FJ%3kWwaZxHwOu7s}F$cjGbHQ~$H;;^H{HIXZL?j08BraTzZ> zu#l%90fra{Pq6^VxBKvpeP{dTv-b^J&P*<C`-%*mZTkr~oO+P<2*bV-4Z-O|l4(W! zVKz&!T9D<)E<*zqnq+McjdkGe=bw0rD!7c<&96c&uNcu6q%kQ*{lly4({D3HRe`MG zHdn9+HME)upg(7tdo!I*#}5b|aZz-iQbrTOZMXIvdblFuch8LB?)wq5Lmp;ADW8Z0 zcv#uw<t0`5fJ%J|nJAIfhfMaLDRv1|hF(BU0GQ9!Xb*6}R%7NLNR^|~$%f+Jxp%Ev zM$m>So3SrtFQtsuorH_t0{UVy#qHq=P#eiB&nIXly$j#c+r-L%X5g2f?^~mPP`zbo zp^qCTvEO7kH0X2%@EziWcuZ65qVQv?J5cyLXgIr^r=u3`0+Wt<+qH8_Qg^VkzGqxP zCZbHXtB{~uGYGBN^M-XnCb-{vEMHVnS_LqPb`!*W{0Kvh?Xx=ehopnPsL{C{aB{;I z(nx_!Rt{=a$DNjTzL7wJb|x>plXagdWCh4CFvO6+yC+0kuV<7S@BG-B=A7R^s;2Sl z_inI(?$i8D+2HhgKd3m6(=p-sWVx&X_PaIlndBEZxH56_!{8R`dQ@gGf)iu#eeKj| z3`$1$6^_A%z%)8yZ{3`G=l2z!?VKd?xW>srM0(r!e6tlbyFm_0o5h#6N*|VwNZx&O z@pVW?{-FUW{yRZAqD`hkO({hh*EA(xIT9&fYmyMENXv=$Ci0E)jK=DD9R$$+xY@?} zr^1hmrT?ibuD`#@mOR)nHo9<pN@n!md5rfzWjMP_`k7Kf_2XN^pIR}`@uxk{-XB*P z48VB+|F%lx%&+?FUsUTQi5};xc{PM?;hzZn?p>duN_Uik!LoA*@R5XAce?KVDq6=r zW5QPmpnaIWL*bfy-$q?n+5TxAsO+MTHiE*7Q<=5z4VT{Ocu69?hz6n@R?lYVw)uj{ zT;%ljFHO~^7B(pgI>T?YVD#|t0pI}~eKzAm4y`F<XZ8tK?FE7$9`TFGKg4pfD}^-K zse*3dzTxD9i#J%*g{xZq99Jk~mobYnFB;>}-VF+P%#K(Eb`{?m$*n6mTB-dx!r?}I ze{ioM?ux{j+;GWh;X%1o&AR+8dNPUHT>#yzS49g53A4!Zpt-LAWrF$Quiu?Ox^kCm zeuG&Tr>Zc3XZtNW$M$?mBQN^EpJMNCr_9Hxrge6wa7Gkjl@H5r;1LJW`M#!@-NxZ0 ze0(ltJ{OQfMI<VBR%Hq^*#JNLN9L4(Jbbi3W=U~an+VTEWIe!irGQV}SL!#BDYckr z1?BIt+6H1~jZThuM1@EL2zH^bP6F10N^Gc3LcTJnrMZp@RGY65o~M?QL1cg7K6ytO z@O52CyMM;b?zd24BLU5F=_054Boe?oQ9H&6z$*zcR7Dt_-2=K31tI#<?hj?xsOEC? zEb?<D=;_gCoSK|{SF7lriKBPBn?%iaKrgkm8lx8FbetJQ@AOaO4h}L_wy>~WRfdFg z*WAmW=~{?6MWRL}ulLdc-Cq!ItcghG9T>6$xLsPJRYesbR|@Qy?cJ)Cg*Z3}sB&@% z_*E6>yza(0<Ss-4$+3cL5{Ea3#So~Xlrz);Jc-gqtvq+jBc+1@S}QcpCdz?AN#y>B zm=CA3dm{!>T`RYNi_9aC+`~`9bmFgqQ9wuRDyNc9hi|V;o$;yiMOVW2cL+s4_4&6v zjF32Wg>f3lb_oYTBkPz>0{{H;cAqr$pDpWkacp7PwXfp~x8(Kw0CtL4bj_Rdk-vEU z%vZ<RI$3`ouQ)nz)fK6F+QR|SKJm6%?_Kyr{3MuMaBz!}{N?2y+jmiPAFtk4gozg4 zfg=1_l0ke+f;1f<T#6Im_XY8TXRRSkJy%qv{4*OC3ERf0FZt#CsYv$W_<vXejYB<y z#resW3sGq%cXSzb{`jf>HjsR5s$N4$xjYs#t3UYO=jUIB0(5k%Ai@q>7|$QE?#J3< zx$)9!V}arABlG1?*pL6=cC`MJ+p)Rg{&<mc?7vY^Eprw7cznp*{udFlxOMICBxQv1 z_uRk1EMBhtOzwGyKWUiTzb6eInU3!7@84Ykt|$Q`P%d92w(XOy064t$N7XKmGw;0K zU}Gz4$CoG#nljLIK+h(-0C0&t-q(vXCd|LNiauDl(-*C$eu)YEn|X*yAw8*}hvZcE zenn*J^R&7VJ&%=o|5`NPcN&6&FTSo}KcH?@2=o_MZDT8#bSB6Dhp+bz$2xxdhYQ(c zX74?+S6Rswm&}Y1ku7^f!lmqyJ)`U`*;~jaAtO68WbYBlbGnb?ci-Rp_Z-jjM@RkP zs865qKF{;D&W$c|Y_umHpwBUMj9rVVechew^NoEdsN3wI_p{^=(3fWfE<X@%zj7aB zui33&n~rBHA@b#GekSL8Dq~0Ebk`eIzCeM9L`)hE;BF?Wub_THu>03?tdrfOA%H&7 z)wbLIZ&_RA3-lV9Ro7(}8Dk?bo`It*h5hcMOzOepS%E|>wb5HNWKrKfN06X|8<#ap z0nO-=!s~0IiBVFf0wdp0Kxk@?V9_g1WmaFSejIdtV*lsaYp7h^Z`!O+t^}(EDu=sg z*3EdpAc1AB)ylr=)6I(9a1_x@gP@yG2}rrTB(wIZgUwB{<?7vT)R!3+P}X~Hx*cNY z?85skfNGIheT8a^pgZ_1vk;@75g37)QCu&;W7N0(y{(pP`$}sf!Ro8qj}e$nB$_^8 zjOK(S9!@R;**Z$UT!nbN`=b6>@b(%d$N3lD?Bv@#;bmKUsRd8h%_Cx3w5rWaSOmTQ z$|#AbLqA4Zy#NS%!iH;B^Nh52p4sQUsS~|38Tz5-NJG7N?9aOCuGpCVO9yV@-=Ef9 zKM_0TvXyEYot#V(rEkp-OM)&~QZh0qrMU3^=GTjiJ7x=*Q1mJK6ys;3mEMv;m$0!< zW<`fZGoU5n$m(DwRX_ekSF!owcdy_gsWwbM;vRO5DDu-c#Y>(Z1W!Ek?xuuwZ)_Tt zg2>el)e0T4kZZGsv5BV23w4oARHU*zGyD%v?#SzFdbX?VWX15A>aHo%oEKcT%QCqs zV^;h%F(|zN<t1H+cnQozLR9-L#}or_@!ySp3tbP+^;X3S>r=JSG~p&CblN)!;#^@( z;IN?TL%-e%eg>Srkrmdi+aKLNI~EeejZSa)n-_2!Mi-;_V}1($n+QhUQ~x0oQPaUU zp#q|Fbw0ar?Z;S#VTId$9{n<oYQOV0&Q`yU12d!&)+D2#+G1_#oL(?-^Dk?oe7=`Q zzOm&08jT+hE<IzL^RYRd`MSS9f9fdv^-tWK&@c7Z(;+Rp@ALm2eoXNvkotLNcKUAf zxsdy~l;n$+iI@M!t9Oz8eR+AgbUl0Iwc8aEtt}`2#zg2kCKw-Ct{;8jr78+DoT60c z*+4G-k-5$+%|X3VsHn5BCzlbB9ZhiJj=Tr2I&=(%dfw53vm)m4GTHc;x3eZ+i1-jP zfjFfn_LY7QwCf=Dh=um=VjX(45sV+yxF5+Tc^+7Ymb--++WXyS)$&;Knwg&9unx%H zzuW0G0Q_S)_p2xA8CtbP9Mrz5%pT-vLX?jk?(JAJvt`*XoI?`=5-+W4MWVVIQm`DY zy5wMcU;z8ahm79^0TD>%Ux~O_gb~zm8clG;eyL8)3Ir`@3ZwIy31X8(RH6cronnr# zS>QtS2O4RGr0_Il5s5a9M$i!GCS=`}F4g2M<499f3g3~^1-Z0o)yLh<Vdt*j-$B=) z%~X=BC=e~GOfe2RXx<s3IM2Jv4B2lK*WVCz{CmKFWq93TGenr~dG9BFk7u_&SB;3d zAI~btUsyLsYHxCa%H``bj}JfNl-|nk%eg9Ge~%mLagp0Mf{GX^UO7D>$#Xm3Mw!3! z2dMhQ#k#0;XEm_;^%Ts$kw$!~r}>T%ND`xw*2uIoy1I$VAw{h_xN&89#2*(D`A%DY z`)JvgU{t*_qPP7gq~7F1(5>|hP%Hz+;H$s;sS^u8D<NW^cEmrR!S8j={xAwd^*;!I znp%WXp2p0;3G<JN8O;?J{CD?(OXHO~E6^G$QE>DSMubwwHj{bCVI}h&dehJLL=zbk zxy?V8s9%>iBNm3*4wRSWJ=dzY4b|@L>dm>9KrM`<G^8!uj^Wm?mq{3x;!7Mg3+1Ns z93djZz^NeY;dU=ZD;Q?6|FS97=D)>5q@l_-C*?C_wDHg*u_TJDeELq8b(G#8ncTr> zW~b+4)(gz!X)61}R<})jifZk>OUQf^HiTob@?6qO*jl}gsL=ImE*c1vG1(u2PMxLc z8Kd&!W_2c-lnf6W^;Z`8wB8DIB1x9L8VMk9)Wk3hJ4h>%2IsHZc%EX#f%CH*+!V|o zM#|7n&zyka;3UO$)^T80P6JbZjew9UY7Vrx^uf`<R6)~q)xd{b1I?bVer)bSTw3vD z1EpxQvhy@bKU<6A7@1(Wu9IW+G_orOr@L^9y}_p&ndqGUCp@V?-0NgHay+}aLHX!P zD*S&9$%~iAa?4-NPWKr8jJ|ojoKCsdaxn&7blKm`%NLUa3VgOvs;__h$o@z7yrF+T zq|}4f&C6@r=da?w9tM-xp6@_0A|K^-PxP>KR-I7w9kP3@5#&hBVp+DLSLSfg4D<*2 zgy~A3@;)l@x@PIwy|EIh+s~?inP1m`4b-OXhwSItTghx~e58qAZTXH;gqtE@|0Sr* zg?NOXCl^>ho@6ZNTsNO;G6rR#G^mRu#eX#<SB<W-CZ}HM%Nr^CH}Eif-$-k|1VWGZ z=AlI=f(|@d{3%>+A>Fd^7Pgk0Qt*T7LH0Rai>`Fz7#O;R-N)8y2rX7>;5-C%yto-u zqdxHqg#M!LLk}inX*`12K!wkAa1kW%$b~x|r00sHF?Y2jT_&SLgDk>upEg`S=_N93 zxNe|Z<{b0E&W{zN6%0zDn*?qG(1OAEswxDje@}of{x1#5!;YhG0cI&GwHzyvSeCt^ zQ?YN6ji3kc<xO6rT*DWLCV%KLa7ayoArA@y(fW{}k(jK$2lB?+&P{=<hK|2;56FyL zm`NkSudJt#Qbr`IpyyNQ*@4)qF9&q~9@6}9U=?47Djg5}BUo3q%y=i@_%sq|y~jw3 zRW*R4#vg8e*CP!Rj~@M$*+#GRvmLGUH6;Bmc1>aS@q{texjFg64w<3cokt--TGgE_ z@cJ1S@#{BSzb?nlTW<&MVAowLp1E!;n4CXsh~hCUMcw#LL5?SGeeM%c2LD*$Y=xRU zj`Fxwk^3oQ!F^UiuR_}&H>lPem|sao>#Y9^k7*LFZfB~mAqBmSMk42eexn~dC+L!V zi=sWi)zSSn=~p+3ft7ztBspoQK>Rr+%e_WpC=CDX2}^Gr@uD*)<5rb_ks<Y9*}dzd zT1R=4M~YW=`H!`;JQH=e(;=cgd8$lFdy{68E~@{-d&@RGIwz*%zYdy;MFd53?C>(# zX>46<g|pWaOp+1-;kxc5=YG!5FP{Wem~Oa^m8h?oCBccK$4Ve5BSjhslg<p`L>*e{ zu^(R8lr37>$t&hYvk#|TN7kAmFKMs!k|Z=(a4w~cb5Wl@5C$IEaE(p4TArQ5rI?UY zYSr`S>>QvoZmvn&mu$(_BwQ`F{ZkSenR`g+Oz(HNih=2{F>RYznu_aZCU^3>v}T9( z(M0e1ogo867+G_zJZ8mN*z5O;O8@RM{NL#G<C`Pj59XRm|NKG-i}=l5Xt{>9oW?Hl zH~&iiyJzs2i`_a=N#@Rww+Y?3F2hmt-<AKi_Q4-oX36fKhIKz$U0pTa+mq=GZ?@c? zMh*#4TG|A6mAl96+W9Sp)<dxc-BYU-WE@mFp@)~@UnMYnZ!?h>xq~;^VWeCdgTbd7 zUa0M17Y(z}453p;l)VPLZSF79e&5!rwpjN3W}ib3uu{xjr;>4O@QEOprFcpO+gwV< zH~%In6=sGxf5`U)B|KU+4lV;Ln4Wq9?Fnwj+|^{Eql$?4AN=kCuq>fm!nXu=PO`LX zl*E^^Z5#)`#v(jsKjc)u#XM@F>l)C<K<O{}AxPHhQ~9%;>F^EUYW-`h+!*2H;4)XG z6H%|YlU$|8+*#u+eO6(~$)k1%G7_p@Au2lp$#jl(r-)l=Kq7AyY-!D$hZ{(;$0a@$ z(tsB<`3a1;NcxFWWWi4{GqqSbt)8GvUi}6c7^FTY?^Pr}!s;JnFbcj#V_c@18dhJ0 zB!<rmx;*EhnaGt&b<4_mUwsW$*Dcp&`DTr$nSqL-_tu0x3kUZe2xl`LOGf_i^%DOz zr3Uj-Y+ukPxOnAoZJ9@s14o$PU!q}gh&tRDKAx=q;3G5~i7FDb5qH{A2r$QZkHGti z;8!1JY-2JHV8q5=ahT97dg&g32Q!0do;z?Ucdd&ulBbzA%pD}jN;fgM(1feA@q_T1 z6!KSburV~Qr2WvYTyKq_QS^UrjcLie9l<gr^-#K%M4eQmsVXWw<Y(7M^S?M~VRf>! zvEu!=!Cp?CrC#9$mMdILHd-J~q_)nNj3iiN4}P98fBJJv>DhbJ&J!6$oTTu2L7H)v z0Ax@D5f&flTyqHLUY||B4s5TN8>83v3cy2d>?OBtSQm`RllOKKVUuW+J1IE*359bt zBS4*XIaAaw!ig(!(j}|*SC+{V9*~o*kGvvCBE7`hm|zvIQeU8vu-Zixi@s?98^vCl z2kSt!lXhs$t!PXR=4BW{k7dlZOoN~E*#M3(`2l(xveu{Inw3mvVI+Kyoz7gDeIqY$ z74JwV+~DOMad$Asf<IX<^ox8Yz%zt0EIB^&$y0kl^~(r*rU%U8&jo%RZANM}E##)6 z0l}hiV`P>FZ|IpnBJ2%gnX>aZNJ$EHZ;Srx;g!%8Y@W`2_l$;2^*eAGU<Qy-sOY%S z3Q+(3(wNiI(^{OxKYttkUqsX6In=HGq1TtsLvQX{UDBA%o^dD`U)W#!yXHs}tJE6x z+4b7I*Ff``<o{xpav{D#l1f${m#ROmng>u>=tF`3_(WHGI2MuGp{Li>#au5S=pwFg zO?k!P9k$Ad!qjnG=z)(bbw6nqlXEPx9m-O@k7xF*CYHaVQwn}EMZePKVtnF#v2Q;G zhK-q0;>0*HE3!Cj&qC{}<pg76!bvbn4oR3yt4ic!`>e^pQ_uf{q7c1u@T+31<Fe=0 zMl5rcxw-nNone%uq$#V}-yI-&dxL-@4to4ObZP`@20Zh}x4ms2f>TQ|XPj0N=cSC* zvL`rQtvr?0#d<R$1wXR9ddA6<XA_JEj-m?Z8*fK{QuPlJ%RIO>*FapFg7f-(mpCPZ z=)1yeF}WqboPFx+6GUbY-)EE|x3{o^pKU9AF5{S~!;zk>QaB!4z5QnzBjToC>L75( zyyZ8m`B|Pe?14T$M61bU*^_tcjih+cXgas%&5ciVf;#8OhF<Bn2*R5>lM3MvrAn=8 z*Cc{K6XaU`$3?rkU{B5o+4Y0@$X`LLD2k|jL<cAR_kwEp-y>;iGQLSX16@G(AzHWN zLNnM}TR~oieg}xUSUEmyxFH6TmaDGNp>rcDT?!Vz`?8ifp?imQ`xvE{y+DDw<Y|kb z!^zKeTBQ*7!m8ekw|V)<)FjpK_Ey%3-%7y|<nS}3(Hu?v2mM=91{d1c=J3=E(rU+X zlccl2?)5KSN72m3M{2*)ykvi+p7|L_s^!@D;$`LPmLB51F?=FqQs}oZTpY7@$6*uf zRLiW%9f}8zOP-^0ESm9Kf(o@r=YAG_m%Lg~1nk^7AFMy$iLWzMU=dB4NNXb`lfyfl zjoXrvQwS5~^xaZQdmT0Z`tQo?wlQ+3@(?VeWc=7TZ$M}BMq-B>C&Hh^m#31MaTi&` z*PZuo;X_?lj7aq;XHXV1V|0M~d<NlNw?a>awX?Z1KU9xL0R>r>2^7xX<QwK<vg)Zt z^7>h!dwr1;zU%ilh1~XV177sgC-i|`KO=Cptyr(oh&6LhN(4`=WDq<Lpef>!Y-Jge zaEJ?SdVvygW?Y#!TdgAVg|1>tLLoC-?~jp)zeQY@FUunaB9$NXQO~wK0o7AI-9P%} zcW+^-N&HApxAi+lKOhrQKd1lSNb@QKjtkC?9qsFtRk6S2>fMy{H+kaxF56#*|1tKl z>@j%l*j|~MT{?dvz3EfE`JWK8W7E+s5Eyp#vOjUlBE&{RQ5Ak+KMFK@M}8hnOazbs z0dDF)HT5w&)KCf=g=e7h&}T(%mkqrCB7dVP+`HIgVjL~u5L{4k)ISFUjYzX-!?8>@ z|Hnk9BEPN><Sz8Ya{Jt!F+qr6DiZ($;io}tEwbi@N+#NL&8po*De&3lVCyK+X-^wS zJi@X&b6q3A)@XwRt2cV@bIi{y1Z<SYM??_q-9hskrkVXX0J#@hl7M6R8fo0<$NIsQ zARZe3meodm?Au{v^$uGcM@frv(AcL4%U^=J`S?MZ#hQlBIlLS;g9ED|Yjb0;;XC5) zN;oSPHH*B+3nr3X4UPIrQ&W<`&*Pbu87+#g&#uKyZ4+qyyDtUH210(oIHOSXOU0hk zTt2bksaFN$wOB9IeYZW9i3%v$HI~DokJt+hTbUXo|6HY&awQVS^6V8S9|WE)lY8>a zulz2^Trs)b(QYCVzRgUCU)ksucOD2U^W0+5vDYADrp}djo7XG_LLx9CW+<j1^3f<^ zugX?zX49(HBoF)g7px;HSMdy7>WFrh0{>R*J`uM(n}zzyy-Vp;cVt4yh#BiaM5+^Z z(9{NHRBC~Y-2D5n)n640_e-am$KE64>A9Y~g-L{nNU%+R%OIQDT9P-S%uqZA|7pDp z$s9>buDG|sj(_5ppMO4lr6C*oCB-Uq{FRsVXF<V;+sWrU3r#Edw+&h2p3>feb-Cp? z(d3?`n40sH8kp8A5f7r1uYFrR4#*5|`p`~BfC_KIJZ*KnjPf{^Y&~WxI>fk*jrKXx z`OEseDMs0~bR{G2+Fv()2Io2gCxSl)tS(LR5HguD@<{n9HL!ytS$k`Uc^K4sU|kPY zFn*)eWKsOkNcg1Kn}LGW;3^nohVYexdfjt&m7_GCN>H|!O9AUM&}o8mTgo7Pgp{Dx zAza0|1^npN3sb?0Kz$lba=pqbFk`K;+;KhT>n0s{TL}7`)>*gZ+5``q!t+NL5C6!& z&(&t2+9)D>Fq6|f2ZdDIQ9^lqXNKU4@s(ld2@~ox-SHksD#EK6m4uJ@nm5tRg!8&u z<Vj-m_7TW$NeRp#*fVim{-W=iEk)?=M18~Zd}WoZY))z9--{>UaW89l+44WdvD#Au z``>BzVrhu_8SWc)w@>s(E&o=SE<X<9|IvNz(4Kzrhv1s*sdMiu+J9UB{l$*1iC2MB z<8DXYGzG}ugiW5u4lQ}-<h>9w?-C*jQ1oY}Ajk#31zl-!<MFD|n#JZs92;r%)m;X% z7czs)N-e1HZ5hn$Zuq9Yt+EAKFZTO_d=`@$7Zl$ibpm!{`Q56R0-+|0mV+D0;`gpF zq_Jl3klpg))~a36NR0VMI`n4h{Bs1R%nt+13f6nJ&GddIOP;)1iq`j>R+&4k0xTSY zy)&DC)r78C89xR|$^C#+H}Pl7o*;C{)%CW$<O&QY&Y&@#zaM^R@3(@m2SOCoF`mrs zo{w8|CccA66V*C=^lJ87UA5VjS`eN6LD~veiayR@DjoE?*>?1jvLj~$ThR$yS{y8= znMMMd7RmyE+O%46N)2vM*^V#0Kd}0+fn@b5tpDX291I|9ZO$Bw2x&hBA7Q!6a8QUH z^EH448wBr(QI_IENL^5&^`S%mxi9GcVgnDvB$}nn&r?*26)n}6n1AFs|7vrw<@oDz z6b<?<_vUBYnC8RaSOpmr$4VL&7fCgK(1vB()JZfmk>9grOeq08P-6FP|B3u32{+(j z-PrEyu@8uY=H%UBRU!<SArW+Sm1bkjbJSUiHh++6>Fc+>((`+afMo*LG+da9<0;a; zFW+l0u8^7~BFW*)UE(4dhPB^5LRDtzmYdUdphq%gfFZDW=308s(pMTtf14qY&@lj~ z_r070t)TGyelAkCXVJ&cnP`fh{qDs~$K;SHPzT_UEmn*gz-&O4{Ra#DBL}yHw|_>L zhhdzEbV^Z#W_g#&sI$9whK4<w!D7G?v0+$>zTU+p_9}Xt!k>(s&MZgxpA~Ejul(b0 zo5;{#R*z_S^Fr`!{D^EA^D%?q%s*f0%d?%cmw#UD`DJob<t}-TeGrJY5UBzgor*5s zEW@#k?Vv3a^=zs7^g;wToh`Y_l%gOmY8AdK!3OtovsdrG?f4JY34DBU`|*du+c349 zQ0<ISa7}rC8S5T*&Z>o{S)E#kPIc}yc$oP7$-(%6B<`bp#G7#60*`_usfT0`eDLTw z1AQ=Kq+kzFLP>XnLGBG<Kl=68sRzL>EJKJ1P*vy@jMuZPGr9jpqL#;@=}Qm~U%t-3 zsw$*xEULBQj!fM)=Ie2Pm;Lav=Gy3*(Jd?i!|?YMeD2Koa%pNUV*g9UVVo&@Ox(KT z#d<1xxftnqdE)qIG-}qnbNuzGtE9|Pw)o$*mRhE3vb#_Y#T$M8Q@ycwrQWDT6)H9y z<|Tt@7qk>SbJ?XIYjnS})VZ7CM{=w*NBou6OuQST_Yk2ato$?#D}8S!?Oxb`eQdIL zG#e<~Ed=bze$NnsCS5heKZc@E`Nx$$9UPc5)5Oqi&#uNZrM%`F`lu=-DV-H@PFEz< z^*D^O)Fy^^rcCr+wbKy7N!~6*VOt~7E|%)aSvWf<43?kXDlEs)htquAf@wyJGk z;J+}^=_(T^%fk4C+F|YNvz9RoX#*5sFH4>(e<A31s%<Z!Y6)2qCk{v|l^lEvU_n)M zSeaqCR<6v#36qpud?oxARU?-jxYUsRJ%?V8g4Kfgb-vAD?XAHpv2s#YeCeSd4MlII zqNN<*L+OI?F+`|miGT`y9x*Iaj_LIKQhOvjFY0>pOY$tFC3SoHs#y*X{UX4Ips3Hf zsRyphwx8`R56vS;fI3nNS4+5ZqI;Cyg?<Dnn!i1v>prFM5dBlk8VUKGcs2_G$_0<1 zZ<^ve^ieq+wrFTHrZ0{Pr!+$DYWhipky&|KDT0SpP@9}*9OA_=Fn|KeRr{K-QT~vw zKB`|Txk)tH+Em<H*kTngX#WkXMhGB+mc_@sn{VU=KD_>Ir6Z@6A2Q>!KI|sf)wFOn zVP26i3*v_QGUWZKbgXbEZ`Q^IIKHASlnIPdt|X9<un6_40c=|^#S>lWc1z=LN(5N5 z57^TpzPEuA!rN=_I-KXj#Z%ila>((ZJf_$gXo{^A!TV^dn}IFD*;VN1x^_lZVY%gL zXShieNnFPLXoRiL9RH?ye|73^MQGK&_Lf9|#|-#)fEs_jKO)<Dxf}Hl<KNAnd;fO) zR$FxTHfycCcO}{SF4uzQE+^A}VYU3>sIT2?c&=HyHhfg?$|6E9H*e?&5dJA6^B-Ow zVC$QUDf^_a0Xjm(_QcB}n0MHzL$QJe+=e-X4RqF&tY43<qvIAoVf8*M8F4#RaPJPC z8jcf%bS}<5WF9-(VfAL3>iUz}QvgG$62|wM0}zX56cuH^MPBSG|Bx5U{KCYAXy=j4 zedx~#{ut84x#3GGcr4I~iU_Ybgxmy`9we42|6l`yG=i=tAX`P`g65C?`JbiglkdD` zp;=gqO%I=db5*1<h^(Ae=?}7Pc0y3xJzNDf>`KG3BrQmC`rP&FSZDf)NhncsiDJH^ z;eR^d*LYZO{H2*={^N_4W^5$(xzgEq@5o~7&v2I}@^lWRx&Qj&@njdrf0~PE^sl<> zxgoD4_MWkK6>=_dcgbbbS{5OFCeLM1YUsJ&Ju2q@7g;p{htmguO1hw+(}TpLd-L}< z9SH!vUi$kS^^i^^(0bzRLvt}m9=~?zEgFi!tao!=>$tF6lY}y#aDau}WAnr3QCpdq zmc`-X$unk!>AaF5j^0ySKW4@{0Ul5}ozY&$*Cy|sU`#GVDI0C0B3X{>6wuphyOM6A zg+_J7OR*jZQ2PwNCpBa?8*f&`9!f0o%fkgMChtm|;ZaP%J9CYOO!^Vj75fm(>RaUp zyXDDo94r>gXEW2*+P^AHOt4f&eXpF{g;vM#C_zTe`u?C}M);AJ(G(X+l<Lo-oiVFx zQePokCyihGCVX`sr84>aX2lLt^pF|_a9wxQ=$6Ws#1DfMbInpik+DGR&t+OQCEXf{ zkooXL0!*?jujXfp|LD1^CNz*&JHdm@RH|}f=T+aole7JkWAZ7hu5+Dv?6G;c;p4W0 zlzOWqPlX64_y*p9qku+t7de<*fQ~yDLAT^@-578+(w{@SzCIc(IRfbbZ}ST5rhfmr znL-K)T=g_)9oFU;^;JM&C3~_jZG?bRe6(v~%}eq=&fwUQ$MbFp)+ZjgL!haExJwh} ze7cys{TA(Jq{f$=j}{fPYdJRDB^GqQV$C#6_<QH-g2AZEc?5w@2x3vlIRGO!V%6uf zM`vMJs49yN<fn3ahu0mU21t)iB^n(g+FhF#L{WqCO~0x)Be|{Vtz2EG8e@cqax#69 zb_x$GfVHkV+^aVd)*y!<B4u)8@Bqv-5R+CfaVO6SR@D5;qjI%Ugoj3fG56yV?J`dM zvgL2++!@1uzRyY2etz?1>3(<f3CAgE`dO63BZIRFheqjh=B`DM-YZ(pHkZKrb)RUa zo>+Oho5^6`o0A8mwj7}X5v-1^>kP>^&>w-lI>wHD*9bMH5CG{pRuK2lcfB;_dAJaT zPEO8s<xN59aT>KlLb+$GH{(Nv*xi_*dsf+c*XVI6rAs5UP$wc7_E*K82m|yeKpeLi z%9w9?of7Rd*1C^wR|YaT<%!!{9XjhhAOaLsBWFpAxu(u$;Z=)_Sq%OO|KlXPr^Jm_ z#2<dsQFwMD=_bz5Xjt>Pgiaw|U|J%h;spvk&BMy@MTDK`N}0J?2kU1kZ9;zE$5bEt z|78~ZcU|fF<=ZG+pW{aI*ZZV?J9mA@&vzA!cMa4qF84WDWzT=c%AOGqB^UjV!SG-C zFb|Cvwd>HcfF;sS9w2$|BZeKfgCM{}q2qezSDLC_@9!VrBH*U6yb6gaZASJNq~SF! z5(y!MvSxc6Ul|R0JXUl8AL@DZfyDbbw&C4|WP$h?%5Q<o&SF;arv8dt)WRv@k;+Xu zU}69K5<N|ngZF8RDEC?DyJG*m{TRxRpB>D&6uJIsvQi%-9G&GrHI#<r?nkdQj}IS- z;Bk_3Nw}+=fDKMVd(HxXQ$|~Fq9InI$a<Rnisb61Y{eykE*xFT1-&z$&A;)^TX>Hu zT|f-8sNx9m3`~zqr5_1D#)6qQw7z@3PKXCQI1a&NTu&z14tDFhphX3G2QWOh0MPWI z;?VV(;sixvu^?n$*A~9h>sPF!jsTd8M&8%ZxURY?2vJKVzc7D(8FI**Tt*3bbn%-* z$SC5za##0N7dxS&ou5RvX|u_yX|r8V?7W8*9-K2mCUJU$R*QzQAac|>Zc!~*=y+~S zPWVI~I!7?rhbEf^SUCj$z5geG`<)0S5sRm?BS~nI7O;|LfA{6-aArX|lFyxD!a~(Q zWxd|jGdsaRGj$#9J+>8_)Jbo2#Kor=1;XA@hC*cRSgXKG`8;ltILz)@tC^`s=O;I3 zK?HdG9GpAlJ?{2UUX<7q$jYrM4`Ybf9vBRcCTh_U=rC@ZP-N$V#sjppAQ{|zmpb?= z`K}E#>m%%4OKFAR#qS86DtEqd{S<jCE)xwcf`wI{0$G|nIQAfWU&a32SLtyFKjK6c ziJE3cjMk5q!^iw_$N$Q+Yw=^e(+i~Q%jy_mHfll$Q&ccf3`sD2jV+(5RX8b^A0s)L z2F0XiX`P6z5HZdc$U3XE07`Nb!vj|!OK-~Jr}4}T{2;?FLeunbeRZ{%(2|fgbz(k9 z4*6Fni_thLY!?8&U{bC|h~X6=NaB<N=@xfsoFKJV@NHZ+TAuN!)SBjbK>aQ9!Aw;@ zn-Ti-6B=dC`J9{Z!dT=I>Ji;U{fD&hm=R43s9DdIAHfcjo-l|QWio5oKz4=vS`zIF zZm7+-0iqd#xaw(y9-WVsZG|GQG-uFtH(qCU+bl7ZRnYM2@3WlRPAJvDHlE8K5$7#8 z<U_xQ#5=2$J+H)OI!%QzN1vmU|H)E5bIV9S4NaeyY&no@IUBk57slrCKmT?v{~beu zvaoD>Eo!=UVMbT8aIWA!w#4e`y#LKp)s{8!JuTTIE#m{x|E|y%o<nnI2Cv`lT+Hq) zcl&I1pTghb1Hb!(&+SS2bnCvRxi+$P_)+$VU}Ny|kL=}-^t0e$E7|kO(tq0dmn1k$ zQzt4>p66S&^?xre1uqbiG9T6B{!}QJHw;B@_BKQ;{yfKLfTXw&&>r86p=3S6w;?9T zcWpA+GBvg&7fJ6i-YdS7iJS6#UBi1)<xww&Bz1IYve&=ug$U$q?(9%=xb~Vxq8^#@ z`07Lc$sEp~OSWuBrx9AZoNw?19rh;{BpyNhvR*xXpml+t8hd~O?qKCve9YZ4r65)Q zBa0QT?P}biaJUExvUE<P{lN9G@o#kXRWs8}4?Vn@b-H^cBu|TT{Zxgp9)y*HN-3?F zt0`2$X<hqAn{bR5TGh~d8Mo0y8F%t+Z#nFt&uNX<)49@w6TG&yysg=@hEP_DP|W3f z>KxdiBdLzEh3RGTl-aGphVL*%QatA{=$?qpcu6o4u>u;?B3D5pF?G6+k_-`=w@n#J z$$Y;mR_xDqmUIQuIXR4dYL$*A$Bla6oHwS;upUi-EtB#Tl2CuOnFd&Fou48w7zp%e z$UyIppywpLQ-AVG89jZCKrHz!L}Zl8fM+G#LZt7kqKzctguBBP)ST<jn*HW)qq<af zfFLe?FIgjFwPqH+F--8TaH5cUsWh7k{y`4U?n+AqQW5oUC{SY$xaAN=lzm2Gu5fMz z7fzKQ+%Y3(@#)_Gg4M6D+<*(2$;9F2RQ>-DA4;AA39qsC<Xd1am?n9L+O$058X`Zs ze{wOQ%G+4+a9F%^2zk7pd{;DSchQ^RLxKoAXw!FsB+RM9tN~A4aStIbS3J$sFLRcz zk%_YO5t`q~fUcDgmj#Ia2R3>LY80n3AOtdw?7X?+TqSo2U(tpRr}D=>vNf}Eq!y5v zrMXoS)m8hnO}M%fdyxC-2HzE$j2iT98U%G0<mLUBsMWKgm6f}J!`7Y8>b+;-4WKwT zy*I;rtZyNu7(}dkM7}uZCP7l!36<5_Un~shy(QCy<Jq96aSQukR42EY$3|U&l^zp1 z@u=a&h4nsepWcJ@ADBwy_@HxJV!7j!n>14|$cH^}L>>I=;_Soob*+mGncQ?tc?fsP z!>T~!$pthGCO2N!^$a9q`sYQ&s){^GIz(wzcQa38yaCSDQSrk%l2O;lHS49e(FhDj zVA;97H2;<1tmAcC@X?_6YWklr+1Ix(e$Dx8Fr3zY8W|r`zdTfbeUyLK^napY|ARO- z=0DrClI?>JRX<JY)v(XsYMGM-*_UTOh725=Ityn3g#uuK!?Ul6u7=%+)O4am5s{@l z3jL%4PVfUk^_A&8f{VMI9mnQBQ;HOyY|auqg1jut_s#A_wT3AWz@!v&CYLVCacH4R z3M3kUK!EmYZxv|0{#`gFlo*rIP?=rx@;i2)UIKh-EAp@T5dLa(CAfpB5f??lL|*iL z(I60pTx*C54yw1vA+(R*nj#k|gbvj_jrGjQ0c+H#a!>kkA<vO@K|SN-Ic>r>ED{Te zT6uVB7&QZ*cvP4(I~wLN)bc6VIe53u5K#42TqN_qe;!WYenb5m9fv2@7sUgbA|gpD znyeTP5zg#TdDgd2uh^aE=Ww~@QUWnvhFO20WU*VjH-8D@S4@%-a<$U{<x-s=X;U^% z82@8ki1_((V@P4g6T?m8N~UO~7^89&gjczuZ9hFb%S{<n^vl=CC0ATTu3XuRrTO1= zx9`ANFdexURV6<3fEdwuHV7}<!UI$lB3bu7-^s+!+j0(%X>nE^ILZ_CLI<9B)W|F# zA1ADEigb9RrJ7}|L@~8s>Z>iRB8Z>?4zLSgZ>EsMBHFL9seQ=>^6PAo-M8PAOFi?4 zF1*$1n>j5mqZ^Lx!nCa;xbw6_@%$2Ks$$y9gI~(ik?DLtM93RI9yL0sy0iTD2OGhj z+m81vNdPG0@Y27H^S_*5AAP$Sim+G~1*=G_l^&T}$chCi856eQ-KduiA5`4>_{_oN z2Ll-`M+mzWJ1s<gJw$b?Mt>->7h?Ach^MGl)y^l0RM7)Wi=e4`N6Sl<kJ>%dTP7ep zaKm*MICvH}$y)S8_b<>Z{TyQIT%_lkQ<)gEV|DwvZjSGX0ltu;+EF=(Y!^einACr_ z4R_Kus&q%KXT$`Ea4t|5#>xu_2GO>LPUR6kRZTGU8Pq)7j|nrXr>9{c(7tWhAp2Ma z!epo7*!;X8qjmq<7chR!28TPrdE5<)IYK<HGKpNM2v$Iebyg>a(yu&5fz7Q=SZSq+ z)hT_<D`k7m@6Ba&GAdI%Tt@{>uaO?Y;PIk}Ak%Mnczy4)g$D*-f!NB0#0w`!mSmqz zZ%Fi`@%?*~(>wJF(f-fW*8lhd)l!?)ju5KkFQ(n5l=D_*S2wlt*I`}4$ooS=NRK4T z>cXa(yT{?~MBjfinK!PFOvlRvLOwP(W5R6w9zHFO4yB~C36RhC8S0*tdSIha>A2(- zA9_ott^9be|CBx1!a^V>S_PF%QJBAn%;qA7@%ZFDr9BN15Ol6I{R_-)j$(39ax2K0 ztLTc-kOYJl5V;d<o@dIjieCAJHSWkl*lgo1f)s)(=2O>W-I&euxvAe>FYs3yDzY^a zB?a~JO!1u`2IfLJERzpux@jQzWe9>LW+nyIH%Q^lpBILYr#k9q5Fh75M@SO0H75O% zpsyhRv*X`rJ<WW`+{az*P;HqM!|p+Q)U3P3N*nW@^}-+RJwHdjw8c;|1BhDRKgj+g z3eg&Tyn%L<z4BQoHr%MTJvBD~zw2Gm<3rR!32<3xK{BDz6a~V4+#$x$_(hd1PIHl4 z3A^A4$`Y_=R?S`$g*2^42Vd2eUa`ei$?Gp@&}#A*$j|$CU;^W5-?FB%6H8Ug%;@pl zs`zQlx7sjW_u&*Dd3_g?#{n<!rS;8Xh9tz4*E1l8Ads$XchAFKV}_L*OdZ@*$uzo7 zR*G;>H9<TBa^X}OFy(?PaP}&wK4FLSK5Gs+lfoS=xn)%$7gd^Z6l)YTe2D`~vsS+r zClaWQ6-l*ik3W&p>0?C@6m2EgYt&^-u-XU@N0P^S;GZLG#^o|KS$Dq@)Cujq>ngH4 z=^W@5{WS7V@-$phG7BG*4UM$gDnUhp!F07m`7*UY8fINkAQjT-vQy{ltlN;^<A3^E z=X>!8BZ9R&TZzgn;>L-?y~Huoq#l<y<KLv^$ytJ|xVLdw3?)^Z!<S^n@N{IlBnJ;8 zL2-c!8Q)jgnmXc%Te};}7F999@4cijkwIA~tyQfokNbQMQ&nAzaekQhRYua*ZflHF zKPj<sASKEuDBQ5il{y&1^!}H|A2$G^)bYx}7U_^nNZ4?;&v$lWr#xoLjuzDsAcIXZ z#D#y&5i|=DLk6H01n*EH_9eh6{WEc)L4h=RO{60?fbkkxiC47r#f$A97t)oy7|$Be z`wzb7KNA>B<sDlt#DLkNy{|w@rY!y?hfgQ!S%E2HTd$MyXZ6Ox=VX%rmLvk6@l_eB zI9Ks!8+cO8Lm%%dB!898w*jzQ%JC|OHgu|H5KeO-Ca}^0QN%{8w}xXsH$w0ulz&x? z&z9T3d!|MOX{9pD<c4(Ukdk2#VT^_Tm3(ACzs@FH-=3e=uA&D~hx{p|Xb^f02s1Mk zH%yF)Sg?zL#jJ&CD2Ei|{+mD=4NMS`YcLaC3;qSBq;e_5nLtc^yZNTJ+(GWT&;uuW zi5&VtN%57qKYhsN-q`!2_~xoq_}A;ce;m_JE|7*SH;o?TDViP`1baPnGz~A50*G}3 zu@7LWYDiGst+ddvm^?+(LnL<);x^b_yE<L#)q-kNExlNO9>+X9mcGxdh-X686Kj7q zGh|rmXOi&{61JhmPRS^U%{1&uQIW9Im}z8!FiyShkhSJwfI|4bh516l8~Sy%Blb_V zNa>6{si+^YNk%S>Ieup=M7aqxXI4wh3n%59Dfc^;jOwm~c8P|S)NTGb3ao8m#6yR3 z`Ar5`{V*w|o}s-z6Nx%p0#}cM`#HIE`xSH<Ic-VnC9|B?Gzjry!!*~((!}=-9JYS< zrIz%*(CjEMR?5Jq%J=MpgbuTA!(?)KeW7>@kzGw*TVn;+4JCJVCTbwq34_$h2kS-p z%zL_z!h+~wLD9KJPQ@EC!Re~h8dVMJ1t&Qnm0vIK%@eK7=&!hc;p`muVQn;7!2B<v zoP3^5H|P&Zq8<vi@XT?L5;TjFXAd<V#o!JiL|*hgD?{?Vkh%mROLEzjk=oL|9li2d zTo4ca+6}a_p0Viu2klI$`7BMdaiXr`9heWcM4xzcg{qu%_(nmVAOzU-@P2OtBSEBf z4L>S9_pNjh`0DngbFevym%j0TOUaaC9Qh}uKpeG9&w$~Tp6juV?57V#z6i4$^T@%r z=Py(*Z&r*utW!hRC-M7&**``xGa;CJWg~KJQVM$Ai|p!I3fzD<PHj0c_ifVvSc)>o zq3Rh(F2atIA^OtpPlIOh!sWtGI1VlbB8N5F6Sb<9+R1QfSX(q?An*`U#O@2dlJ={o z$qZzPQw^uSl_vE-?52fM941lo6Xt-@|DQy+!wrP&za`m$sLRtR*Z<NN|7VB!<5+!V zSO~QLhp}nJ^}}$>tocUeI5aC3AM)?XMZ>}=^M1XpSGOA-=V<3n>F+klT^gYV_!FW4 z#9?hT+YyHB(xgQ#6p{VkU!Uk8bu!oJ%Cwq1`zU0h=`1S^a$&fdOc<4gsIr9z4}(7O zaQXxK+KZ%weria-&CI9Xvq!AMV+;;Ja9RNddjM~$kU1RV>3l}e|AUPj4ehqK@+(hP zO@vFON=!Ex=o7rYj^^vLwp%YOZcrA4#gXwmVS8v-<ZfpO?WJjyDN!BKB{(T3PW|M2 z%H$xtQzr3g<zACHVJBh#$rcp=@kyTMID0eL_h~9$?I_s)vJbb3yodonP^4k^&>{j( zd9}6P6#v2By^vB%9BNX%oIOcUZ%x@Zq1t#XohX(f3@coiPoVSN6&yZQ`Sb|Uj-5dy zdKHqI0;#yUG){4*Pijko<y{=c;%BQ?WffBW@M6Dq%c}o~j0rm|y9%ca?<#i{R7kv* zUP|BL@njMpM4+h3UZ5**#|A<u$?eovdE!VZm~DVy)!zBuf&GK|;zCj!@~YU^-yjd2 z)(GSwg7Lp%c=6fL(yYIK9W}Z8!wWVrgdycE+p-Xw5BdWvSd~G$x9S2>0y>gHRQ)aY z#UPk>(ap8*UgGI!f|so#6h~uDhDv8?I}Ln`z-uLkXmVdrJ-??;jlBDrhKrzx6;3UL z5Pw0}FF(3LO3t;o+K=N(k!^S)LugQJ$iTvjtDYJ@HeO-<ct;a!lRrKx24g*=UPu|U zB7CTnDPJvSb||A#YV<AAyY}LP;6wLfLhu(d@j9-ELujfztnlhydqsFk_NnRMj_tVm z&+f!k_ggGkI3b8{$L4fPZVwof62WkGaA#WN_wLYUkk8$J*M2d(-xwU_Q<x#)MC44c z`RY(}C$m3nh$f&8?sA54X+u<B2yr3<?js1BKdV?F5=tx?1QoNhGys#EsBraxktu4E z$zY_=Tpm+YAWcRf3nL);YTBEhq-RNY;Dt7Az7Ae3J$g>Wi2JcZoRoqx!~L%0$aWqX zWR(*{AEt#XG!rL&8XRh416M%kY#yPh5+Aixta8)Jb5z$SI#`jgMNMVW`@nF6ofE?s zOwiXh4F~k-qY+w1l;z&u5jxZ)e{ci;%VGcjl{4;>`un_j=lm3Y$qWn*PDizjt;+me zRcrBlaz2st61F9cX69A_lQ>h)1aISxaQrUsQ&uD#S6&oec;d~^9D)PD`5`UF*|q;= zjDm83vWW8frbhA8^sh8&WBKsheX_O^dp#si@k4=JC`Pq*9f3y#UB~%3b2SzCyu&l4 zKtK-?NDj~G*eBQJ=<s0`5~D}^Oe{_xGnMCcW@1jXarbXxh)TP><K7p2I3dW5g+)Pj z&x8B+nua#v%b<8pNd1oSfKH?dab^M7$P$>VdSYRa>_DXKYAZfDk$SL)dp*fBQ1$7D z9PA<2rj^jpz04HK(DVBJ>j~nA2)aRXL6TPm53eG5Krvc4b@2ULAxeZ>tdK*L=v*CE z<Vdi>2*7@Js96dD%UJ2eMA~xQ1xCc2ami=k!?`IaqaXSONe62?uDrmSC+1NAe;${& zALRi=h~@b2a`WQVuDz|#STJhVMAd8dTs(DewpsqAZ6c-LJJXO(yEtqEb}>E@Nga1y z|Brr3U)|A~>$@@qCWy3HSv9&!gv7|v61r}5nUdiW;h5QCD51Jt2M=jZq>2~l_Pfuw zfA}{%`q&s4P?c8n^yI_btkq51rVZ)U?bY*F^hP3D3hQ4W9>|zqDKPU8XACc>;+FxS z_-z1>w{`_hEZ%boGIQDGf={oam6sQ2;>htzK)3JXb|)KUm)Y4zh6@fr4$3<wAY&0X zDv#zhHBFF#%ldTRI)s~6Ozv7e_u^Ga|H}3`WoAEO($z@4G`Wb*O)9e6RXV{7vx1qN zpuT`OMoelrRne7~Jm^!O{`3bQ5jB6M+I)@;Yt5hu`wjVG_Y5(uv6^7mZ@h$XEJs3& zhY~I4L}PsY)`1BslFVd_3*M}IN<8;(+OreTx2Do{9W<LgKab}#F*&yncc(NgSQNN7 zT(X6DmuTK3Di43vwJHJ1Qm|mx37KIyWyz<njIGcbQj+L3X8km4OLr}{kL=pB@$?TH zA4#C9jTs1g=G1Ip<Ya|eFfr+AtH8PNJz(}1i{Nw;+ciyz5>)})PZXPWU0~J(Bq;Vq z!g#SEjG(bN?Fq@zeNN3XHfn7bHNj`RDTnuiL#Azo!-AgcxxUKL{FKDn2Fa}?Ci1lf zB2uOKCa;Gi9k!z7!*K`9DT#>MSj<+p%SZlrd>A~UrZEeWEgpcOqi`0&i>TXP=}*dV z$JQFqWDT6~MZ|mSMV01`$L|^D4V``#ZFhQFAKzSTy+{PX=n>;m$Xhe-9@UK@C>x-h z;58wLN-n>0;Q#Q2C5{$eAbWcx)Xjtp#F1{_|AN@s#a?m0$4pymNqMp<syr@_2N40} zsXi<Jiw621T^58wvi*h~Azf$R$)9xdk5ah5X~Q%HQC5ZwUU`BZeyp;viIp%RUuLu$ zBl<^hV}y`t$}{s0z#0)#lJs+x(sHCb-;$I*OTcRTS=H7<U<F@Qm=+Vxyd&PxKB4L% zVWZ`LkMq*<&8<j;1iMZ5)bYFZ+i;gVN`530{@Q3|3um_Qu);F0$RzU3yN&vtL)(W6 zIXk)<e5Pfv7()7!aTPuhrDaO(KJ@G>oGE)Dy}kJc_G7MdN5%9gPq(u?i9IkZ{gZJw zpTdjrri^{W9WE(A?Y1Dt?)`-RT@6r!Evdkv5e9n`Np&{O$-S9d%yW)64TJW=T$?O; z<<l3Yg5C|&2ruey^5K`4>-=s#@{5_tHWObQurN#(q_82+lC>9zk78XxY$YqA>5*os z(V>OrbMQzBj2Jvja#9bL>FWY%bhnCqeSQ)=E0G~e>OycFIGY90dWXqZb<B?~7kl4i z^DEcuN*g3?g2%P$?D96EDZj(RDtNvt++$J&7&5(y>xE?iW5&xYSO~9-;rq+2k<{$H zqw{i(&}D6N${V*={CKiZDXX?>_q40h@@v%NlR6Qzl5do&Y}~{7;+7o=bTNJG9s1Ku zUP(h950=RDZTbVB2wr7R54{aq*8m11ytLogDNDQ+{}$mAd10AgWHr;<(sK73_4ve} z2e8_UICu!l8%5%RbYl&w$_zypQ1s(Rfw-w<z}4}E{&J@Dtg}N~UW?{LySV-4yf=2r zRwlX0oMdov2z#?HRy)9LI%7Be2ZS%ShvKI8@Jzp56<r#@PgXFyO&l4)qc_R?nL@`j zD_6_wf&1nmd1R7hTWj#3UQde2CQ(}9ZFx87f9UIM6rj3qxhWf`71+~a_X6$W6P}P( zbeqPY>d_*@n3czTvr*SV7#&U0NQckz6o<Cj0cWyV%!iNU%p{4SPIVKvw@kmeEQ{1* z6ZgKfMDp1fsX9`9jU^=?+t-m^DWclT!a2NPa{pzsP=IPHoSi4K=h$y$vonkg$1L58 zeYt^0$Y)XHZupyx!-llPaN*VMrspRg61Ijsl&Jdc<$f26B84V3&f=SSpMMVD7~JL5 z@1UO#*BvpSF4da=cjE%}J<}LoyL7_<hZ!PUI~F&3)1Oi3cXHMBrhI6H3hRVeX#JY{ z^d{-YK8hWma{NB%9p!gF=kC*g>y~~Z|9bwo{ludNSK&-|xjFs88Jc3t|ALwR=d(pM z!-l<2iLoh#w+FB^g~<~WZoey#7Ou8f!lm`ojWeK!-OH#h4LXgOfxkhERH0>dhH}fK zHl@()etmw-hc}aq6|vmE8H?5HC*{sX5)l^cNgVN0hNIlT)#RM>zWEwr=lSPFB~;si zWzem}{39;RP8oM@_O^fmmC0wH7pKAjuy<b-@~lt**bXp+CDKU?RwnuM^{>ZIgcU-G zlHOx?-_wT1g66$z-Z-?m&UaYcp6#@iV>`d|eb#3ozeb{VL``~*pPF=g;Y6aIB`zp; zD{xx_d&QXb@3!6V(HR)gH!_`6v_oipG}8rZ(QoD5L<`vcRUtPI33RXskH(-ZY_By} zxxnzgzv+gH&`?=*W|H>2{vUdj{*W$tzGpvj`&Dgo_gl+0jX=Gjn7g}{?wudkZlmjG z1}+ca*Nd{?n>5W#G2PYd=b2vW{)%-an=Jp@EitCp`vIZHogV%6UY$Pw6VgMuiuv~k zQJjc=3t>2KwISm>NQX5~Rm2S3R@rpe;+8$BRAn!z>aFY2izS9=puXvCO-|j@5I2eo zBRaADY`Q9h2p6O)M0aB~l=hPp?jW%q%H)OdpwVOQ{Tka#%P%9Ix5knPq^lvjaJ%x` zlBDo6d%RmU-Cda6u#i)XZ*>6wRc%A?0b1}qyuL9D^I-v<M(c`TiPa@9<4L0ozb!!r zNqk92tTV0M;#s4U*5Avy6G(|J`NQN(D<kwvq)kjoOlM*U0-9TSb4GFFmK`egRE76~ zcxZJ6g{EHhqME{+-c!M$94b(37&T>UQ#z^Gwr4`E(u>f;+<$W<l#&$IjBmLXQ_x(A z4yM|%6|gg@V8k67crui`QF$fpJwknLJJheIx1bI17*i=+I)5zjkfEpVX}H{gh5rK= zTlBRjJt>bw>Nsq=+m7`o>67{ce2d!-rs*Sev5CjVrfwOg;9N*(J57cYd*DOK&}uSU z!c7~sx|Y*69}Shxmz&Eh>Zs{O=hBOT3-ds-Rx&B-cH8&e$fwH2kH7W52_&Ga5u=Xk z{=KM8i3xe0N3b~|x-ZDt5S`vP0`vFN&ArqjI`#LYY2zbeTp+I(+4E*=>nhRf?7C$i zzc1si`Ia(?7pG$l)zpD{yi-Gx2BWM<+&$E^jH~do4WVKRSb1hzb4Mp!P4>rz6MmCT zW9;j^>dV>JQO4i-Pam}G1Y^r}&X@iZx;*B;@cdVJdDPM>d-=B6ckZv^>o*s=9&>|Y z|6$f28Fc-V9u(TC_TM54S?RO;7lp=~R!_Uv)uVVxX!={2W4(k(UPS0pmg*_A3nK13 zsS$ezz$g_~l8bE+CBru==AVgggZ$MCO<A`RsDvMTtyAu#;6mQ^o>6pPgQ)kw5pM7^ z2h4ZYgm4p^GWK!&C(`R8y7EGU!W7E{PyxGk_Vk>s$U?#_XJ;oI{{8?6X5tYhbgtxE z7z=-*c`$|#r<F{R`YyIR-|}!I*VFsVyup;ZQkq!QrO!V@iD#;bb1LS0FPLms$DlL- zv?h%gDNj-WrP@tMf^N+%wr@pl^;(dIKY2AjK=@>2q3MkF4V;t;>u)+-V~RPSw&@73 zboXH~J}Y|3d7rg}oycLeH|(u>Z}*5Yyz@=#eh57<B_rv2u=7S*bBVlOkVhtLUA=0l zR8`t*0~Rxr*M$_up70kotxSbmFH%1=i(f+o|Leo*jg86`=T%|!i&9t_!mdFoa3kur z4WVc%@TFJ_t=Jh31Rqfa?LJ9RpXhX$%q~CXY|7@ar7o2S?MUy4!EGP0?1JD1%2nrk zaA}kbobxKwz$flN!ZYQ=3l^%6wRTSjs;O!_(jP#4EO)v_&-X$DuL!ctX<-V2lUNH% zH0y!7x2f;^DYftfG`$|zD5^i6QBH*2%F<0XO6oMmwyQ#qYvz5^DqnKd<FmgE(f<kR z6BjB>vSXPK?-K}yW+TQA&7wADEtnqa*@MgwZE)&Vj17KA9ntRIW-KpBc^8jOY0ra^ z*iQP^;o~PGr`GGMSq@lu14nlWpJT*UM-oFwV9ijQl_zQc*mo{l?DKE4xgPwBZ{#2H zQO7$;@Yj{LJ5zVse&XOMc~6YCSe?qeXI`<8x=x>~43MCjHsj81G~ZQUBY{v<D_D#t zRmu_TkHwho-XUr03T~dF=#PihdeqrXc={}XH_<6Q6oe>G*foEk>ksStO3Y38<z996 z3d?bcXoRa0_&AUN0ClFh_=(vxGuUY9+3^%?qR346k%7+}(@%!%#P+1o4j=SxtcgbG zYV*k<+Mx#Fn;P%V<_`4`tdw_X{kb=2^q#m-1W9XaP~|mSt}8**E$yN|@>UzQOnS^` zv4s{YHPTwlP$&%udd@>!;@E3KlW^-XE6g2&VY(q4Drp~#xg>EkzP;5FHFx>?uSxUX z`0OQb_THDdzo?eDmNWH>=l}lAoqhD)ne%!3SN6}-zr80vb)Du0W&YQ9YZjrv^7#Zg zc~M#Re=74@ItD89-zfiaWr^9*$I>eY;5*{1g|8}gVoUc%CehRdq^iqiMtG=8odP_1 z%ctUSVFh`eAd5pkqt6-xvVV7i=;@h2GPE&qIPGsO!@jth1r^&x83_MEIO<Qy=vw06 z+aeVcySb7hfNvpyE)|WfOmeO)n>d?c7Et&$4>J8B6-V3mo*UA0D1fd9;9N8u4w}a` z_i)vjY_~a-U5LNM7tZc+CcBo5^V&1qZlhQTMt-=_&SPckdMl5?3k%vyQ?tQMsEq@7 zCH4Zp9wr6!44H>Q$ShuWEs-cq5}Yk03rLpE#){0BP7au#_V#jQmLcI(MFd|bv_rTS zJwze3%Ow-WA;!SfDU6Zlw*E{tE?2(ZjG|}Xd!<9mq@E853^BSP6KfdKj8E_JZa~<# zppHTD&C!o<gIK>L8^s{vyeXE9>HG{an6($CP8aIe4jkNk<)1Zm5UJ#3PkI)K!?1OH zhhfwT22zBc5V4<ClwhT1fP`rlF|Qeeg+L=Yy8dGHs7yzrjLI#1vpF+?cwA`DW%Y$( zTmN#I|5PZV&nis9e%rOkqJy%+nwK@>qc>!H9%Z>%Zxq)X^xk6=7Env+$0@aUk=rdc zB)^waX2guGH0Qi&D9(~t)15#Ce8W&jX3&3S^k_B&ScFG3eYXu6-78mj<vsb(Y35Nf ze)|UHtnJs_<auIy-o3p#*fh?K@0IRscAtNHid=%fUc}73oL?UyFHIRDN?M<P9Jbnz zf28j`bl-zM_rU%8)u9?Gk@7MQN%a2^_SR8VwrjtriqefpcPJqZqNFr}qJ)4n6Oe9j zlD>3JTAegfN=YeQf-sRT2>}U_2I&^r7i)jtx7OZgoOAwT495VRJkNb!*Dp7XlsIX* zsp^cFZn`mYy1^8CcbM*kTY-_^fh3BZN)&GEJPm5dzZ)`8Sbxn>gr&t`o}ny6$TT%k z#(&vRjDp;3ybV!Nepk1bnuC6n;6zCB1=)P>E;60SveWK6kpa5AEXXsqM<JZbWP;I- zs;_f<HwJ1@^KTh-wY=BkuX(TA^N?xnTBR=G$mOkDb9%Lb@sbL{qI=?-M%1*-za#KF zFpC?1X>nKBhg!uFIs!x1cK!YOBBq5Nb3~M_8)91W0$gK*?N{U~{`p+ZSwSA-f;upo z@JF!`U-f2L6C3g(MI<Yt&VP5_OPUq$62B#+Wp>NV&aIflP7c3cHnh(nb{0cuQ1_BF zj7M5I)9I~$`J}EQ&fim+t<9aFne8yhWWF&<c&V3U2Yvnw<8%^ZB1b}c=r268t>&N9 z{O6A2w#lNO4Bd!d(CB}YN_)F{IfLO#{h8H^g_^5H{%il?Gg^wg7^ufj@o>=DAqWRI za<lAs8lbGNVyS-9HU?d9F`7_ERpV(Irvb*cKjc|8Sy3NBFmv38eY{~6mEVZ#t3Y}X zM3T@H8QBRjsA2*Nk+%tq0$zB2o>;UPnw2WH=Z_2D$HU3Q4!Ryop5Zg7Cz;@qH)d}? zP3{pxTI&tntgQ74KgDZaz28S=6o0jhZrvSHM>67-$x1)7XLse_gYX<4?ouv`Wv>Qd zEYL2#{uQG|8QvMqGoTm#q&T8%Duw0Q_`o2oO$SA#B0f`&GqnAD^w39Td>};{Kiq_o z`I$I(<^bA~8MhJo1;El7tW56B67eKU0$uKL7f~A<-(`84oN6ubjDMgtKEm|VZTn31 z;BY;zz|JI7sLexL^=Lb=aZvS$Qq+5mRhim-9B5hQc<$Y+?)1GD#Z>fLtL{}m;Q(t} zM~pen@7BHV69W$mo%hUNF6%Lv8`>~?nTS!0mdqOBXuhDrn;<<)$#y=XPKH+6J+?E+ zC#PbLwJ~cg$Pn_Fc)}-r)mEg-Cc;@ec$&yU>iCogkQCR(sIAKVP=t!|M#POd4-UrL z_S6ryobBY@_xdawtU13K3qK7boly%HDnVFmU?_q3VGD^;(xFuUV!do@=AuH+QdsYf zM=%My`>0r(laGSk7B_u=ip_crp<fXsz>sFx2`?%N!*USEs-T-{J#A+%@J^>Q$f706 zs%rwf3(i7$8q^wFJJK!;4xw6xvWUgE+d{M*SC%-IycJpGH?6q|4bX6W!%_9gZ?sC8 z)n0@ax(Cx<6#5t@lflqiKB4vXUG)7Xk;E$DsvSHa5j8o~Chb;M)4RV~eBmvb3)$Fh z$Z+`{JQokL5by3Y3)O|z{e-r@UqNc$$4ze$FJv`hgCWx)O2s;qC0Ih@Ex+1ml{JnA zr|rLT;1yX3`HXW|@BL$^8>jk31$*Zy*(hq8e95xDWOIcBKPm=`PD;Nrh&f2*-jYz8 zC6mo^-o{*`spDybJtyHpz?@6cXUf|iydkkZS#64Hx6yO7@vR>{ywtCc1MmB2Pb{T0 zQtq2s_*KdS@wxmos|9>3Z#C{K8+C5_YM+=AiTl3YGi;U~80!e1hekH+qvvYKbB-UE zf=NyG4)XH<oSu`Nhi#r_?uPx{zk^Fd@Z{jGMrogy`?<B$q9js$ZgoX%9ql#Kuk?Rj zxsBTxy6cK9i8nQlvY1X-{I_skZWXznUVQzxMdk>n_-Rr9%g%q#(&>LAM%6c$m4$iQ z(gSbA07^#Lyv0<2RmvIgX>jllOG0SoSE!uureyQMVz5L6ziTT$<e~yRBZRTJeB$FL zDdQA8ZcmYn6;V|YBTqhpcf5>i*ASKOx95s}tEY^bZsQ7>!5&?H@2xYnoNi953%@>m zx85_0@1E6+m6c%U0Pw4FOwU4X__egz^IerC?81E;sV~UR2})Qv3&3X^sbR%$fLO%D zAcsIW-S~!^qV=N-%cI?KT{TqVhsH%A+L|lW`KChRSFvdFHCaBh+^q@Dy7w6KyDPmr zUa;bmJBzWqjgN0#UH?$%*vqu3Cw0L?9KPSuhR~F%>njZdYJkaABs+t9?9Egh{_s$9 z*09JPSH=oa<(TjJZv?$zYdTGp_RY@|*n#`6_xKbVFm5t&l%;uh^w_5f;JHgScFEFp z_yuyzwB_51B9AG|;*U&^kSzt%Wzn4Lj~T$Ymn?AGth(Zwu2oM<-Zx{H5?zPl6}}V| zDgA29(hznlviLw!{l?V9K&Q7eSG8atGFwjFc|#Nwjmh{7@3Tx^$n&-CUZcCs>{e~{ zIhtnYK123PEIglC;|hq>_iFf&d>IElgywh#!DwN-2?UMV2Px{*N`(q-%j=k;(Z^Is z+tNW7hs@Q7C<_Ob5HrV<v{fQ02wKFzY_90*7d9Jo!mHFD+BB@7R~7$HaRUaE6$GA= zU^8B<4-KBzJWycNkbXn@f`_fM@sLJQ<mDQ5XQ~359s!j7Kyv>CC<vEE_OO=}na#=6 zzs11BVV2*p7`@I-%*P(C;+|0``b=-MMAmEtkgt?+j;VPJ;g`y_E8h#Uy=K~wbI|R* z?7*Bif26blhsKEpPiEOCKY*6rRf8Z600ub`?edp<H6$5Dq6SpvFJJHxgu06K#GWSM z5aQnsY&oh(E{om<r|$2be{Sw`-RR^|U4HB5Xr=9vx%0X8;CmfwNm<R!@OOTF7(4CU zhC{w~Z<>?Hcv#C7^dtk`HV^P@1)i!>OWu7#2l0ae%0IKc=)$fwd_Em`F?ms9=<slJ z0%A25FoXr^t;kN;jL5Z!TJQG3W8J7Gc+0kwOm;zpN%TDkUbQOCXvQ2jM13+VVoy8K zJey}!jc2*s=gNO)H~%vF&%gX5aYTD|thBy#{`cel!t~)sjsNfw?d=+x49TQ56H0mS z<^M-qY*W{N?7I(5P!qMawKgvycg|_IIK#z3sb>%36$M8mAjf&h7HErrVq|sQ?Ac<P znlQ$@C06$ki)e|wq&F#ur1|gLyI(Ml?Ts4Sg5+WfJE31k8@rK7J;x!(VY!0Fdzh;` z4h*L(5!fZMxl@gxXAL6N@GZQP+bW>#6T0)c;2B%UeEJTfjz}cLVWX=$@@Q~`)y0cR zUYW7b!kfT(fa_@A(t4m80v2g%3}3t4w{jU#YRx>gq)8UVTpKs&XS$}!z9VEN*H(`I zN_U0)_xjtsDfm<0QtKN@QP9Kx{x)Q;4v*7mMb0E^Hvz}{(Mp2sUGET1_nBu*Csc4O z-}F}75Dm!(K!~EztoY!YH6c{N*<Fv}5mq8o-(KqFO*5dhuK&;t03S?!!j%N<HtejI z`Sv26)}?@+h3KpH<r%g!o_`F3V}=nTD~XG*sCt9byK7XQ>hS|I{(Nmm_Px@HrzKVk z8vn~{nvYeA>sCerPb7v^&aMd$2vlR)G7+W%7*0F0*>wQh-X)}Frm3I!0Sw#g2=<~j z0Plnj&~Nz6@*h}vD|5=Dtp%jNymab~!)_n7^mX`~Eqbh$DG+}4j?Du?Rp7^3lc_hp zC?bGE$V=EV`@mvo01XjLmf7;nfDazIdo_!G!b;Y!mcPbGt@QB+Qk7F(pdeUzHhI!t zptQl90q2sVx$f3HyL;bs^5y8Uo`(W)=qlwEibwk?4<-A)jMsb78-KO@GM#5_w$ceC z51o>0|CvQZ>^4SOeiYdWj>g)7<h1S-ZNLxI<|%9K16Lk~$4%FNiXQvj?%&6m;u0YM z=bAz4#~8m<2{ddomP=pOD6=uh5n|n674O{fYOPx<x#d3{fMhCj-?CjD$E_@mD0;Zq zK7h5&veX{Js^GxGon?AM^1Uw2P-MefQj5jv1YTNaKR#AbsW^_C@v|k3F;A8P_DT`e zdnybQ(qmv|I1N+|?q79Py5MQ#n?+*`grP|#bd@v=i(8EEIkTG5jw}=_vGc&*%6f<z zVN?^iOIMn0!&K*<DR#3#*F+%3$8z37Qa3>RcTpsqB3bzTYV>d7uDVj*f7|ZRf}y1U zxt)<uDsg)v<F~-8-OfMP?q^3Y-9VP~Bq`{<sS1nqIi1b}C}QK;pY`U{OIv@{>it55 zWcHpP3(Ndr1kmcF`?$UN2))yM_L2W+TV{LmsOsgpkM%b!MiayBJw+9!f3W&9Z`U3k zNw0P{Y(CHV4?*P0Qu(yk5;P_J8qqabNNrk4Jz8}7yI9(_vDW-|?XHZ>`5*MZ2kt$} zRf7HZ{^gk-3`H`ceuB13>+8j5`~Rg_F1&L+dr{S|OL-sfj_21r8sS%#0vLCJ%Q*1O zf5n7#1{z|g@K6vT^(F)TP|o}DoKhnI-_UeRacX9DAoXwaj(L8qq#0J=R>z}?#*o%O zQ%>2Nl~cAbc?!3LRwWx*C}3R}9w74}P9|O@vE1qL5Hec1OhgKB884|E;JTy`yzB7- zbcOPEu9qEx7pI7~a376e-{yTi2A5~o!FXL-kQy*55r5Qw+4H52@;(aAyHK6W6AWXT zON?3`GeRvv*8vo$g;B4ZFzd&4r_?gYt>^oS)^a3fnN*=T`}D3Qmh9nejzC673+4u{ zB!<Uz@Do`j#23DUdMy?DT5EBQr-Q$~-trq7`V?ZXHzD1h%0)2t{1!>e+eor^`nkQp z|Js)7)dxyQn9jSt^H$!tZZ|ov;P6<S+$?E@A*8rgRNj8w-8YVRydK3P{EnYT(?)MH zjYk;6`n?_n<EsY^CwW@w`!N(Ewj_G{LrC$H`0R#EUawa@+qm3lX9uNU<;@3lyYH7( zo-S3GIk*w?DYpHd+8sAK@i^X<eJMu4o)NN<#rlKlo(aQq+aF4#r4D4)l8r2hS!{rW z5lqH%8n#OhjUy@{dM@pz-HtUj_gtrCP^3aOro7@>khK-bw}6gL2Oq{mK189XWWgiE zl4E$Wbj_>R8!m<NyoZCq5>Mu)7Fd(glkJmM2jc&nPd0V-Vejmzm%?EQdw3;@-D%E= z2;;nIUB>cllf*{**keJ=!6<6HhW=rAJ)gou&X`wTEy=_kJaM1x7Og&~GYC|ljejsy z2;38PKLy6l9s`S+!a3CKD6bwEmQJvcD2K1z2qvB;^^zpSVyw82pec}NE+WG<edl?b z!MAYC*X{2UwSIy*{YgfR6fMB^SP3Ok+vlQWs~qROwq$A8Qse<)+q@Fn3KbkrT7^fT z?3W!<Iy}EdSv{b9xPfs0?efD{FI_O+hf|0?EV^6Xu(k}Q?{Bwm@Ik#Q4-E2;-=Mw) zq!W}+1z9f}u!H^)2*14KGJv0RRWt8sv1bHGZh3ou8T-W_Klr&nILp<{#5-+jj!Yd< zeels6`*Vn~=2rnd7YEF`p`KcQs*U>nEjaB))j)2(p(Cl$_Gqc>(EniO;kkI;%a-Pj z7w20ubNqg*TE44VFJsQP?xgQdG#@D+4L7f$<Jf0<oK8eV&o?qpebz4>?ljMxpB*;E z&unRAvNrXc`im9*$EEJiXjlJZXKPMAm{feJY}9|mQO1bf{@>*-k7N>U8>}3B_AJ`f zH}j!~m+*TXYLdF#E52Ay0WlA^J12P%Oo%P-d9wwf`>nvbW`Kv0o#2vpMdXh-TDo~* zhJ?e_U2BUF<aojKAlRvgJIK9dI&3u-$ak!du4Zenx;W(8h2uO067}_7OqQgx1BTZj zHUk&?XQM?(6j|l7;Fv+C4~z*N#x3c+-^WQ;j%E3;)N+_+9}u#(zkU#O$ntF1yEC1} z`3Gu(df;%)jW813dv%`jFcFjiTZXTPsY`1dTTdUb9X~q>7HK+<=ArHqq85>ke&?8J zC<eeXfv}=ka=~qg%gQD0+4#q;(R@t^3Qfa0(}r+{4@a*S9#C^UJ3jJmjqBvxlPr{i zozOr6)fo9Epcqb*=-$h6SBq{Vr+Yvik=~6o;{@zU(~KFDiZ99Mxlm#s8-SlX+jU^x zk&R$h`xm-}saX-F!46q?{p(FK{?)Yb^d=m1#V09zePNx`(N{0u*M$LGUsIV??a6$R zu@|!8W*53{guz_fy@d`imOMbbkv5xmU8Oei5&1JTu4d5DLCy5@(U;TZ#7@qG+<T){ z9hD4~WWyab#!QIF)bSRHr#`^^+xSR6SW^GSS6r)NLt6^ROZkNG9jvES5GnM^*`oDr z@E5O69pSl-BAmfX1nDWGYK*xAX;itbtS*Krf||%;aHJ3=TZ@nJU~HKXp;E~rgbSA` z=98MMkb@<g9;ovw>8lJR3zxZC%T*PJX;XEr+M;Q$xk(zC;x*QRm?fI?w9hh}x&`Jq zz0$9_EiB0DCS{7=&rQW!vJ0XGWexF0yZhgT`}SZ2nC>Z|{+i&U8eZl<s2+qzSNf0% zha1wCHAdkv)S)LNYlV%EPg|g8lSA!BRcu>gH*FN5QKkw+Vl0ThR(s~XCyB>iw12^r z!e23<nEI>fx|2~~I!#;$aw`IVZ#QE4@##R`=`-&yMJq%&Xn{Lsr41@_=bQ1KqQ(_f z*QAxchR%hi41sP8Q%Qp}&(N>ONL?hg`SfsHapy$66i!=EI`pZ5nd?|!_DWoM*$W5| z$Dm~%{T3+aIi}8R^t|iQkP*ANP`Q3j^W(Kf6>Nj6vBUM&_Bc7`;>*sc;TuPuOm~dq zJ42gzkGEGZhv24H*5+Tng}Ae~^k4k)gV(59<WabCZ0m;oTUBMMsmw*$meRkCFHt7v z)h{KQk97YI|4A@8KDG8gWLh-wG4j85c($IX$A`}7kNoF!dh^UUnDozy$@!YhdHMfv zR_TB72447$z1aRRbMhhc9C7LIgvqI$?`ic*pVQOk{p!CrX7(P=1iP7O9v5*S2o;}f z-T8}|nVoDtn>=27c~<&z@bG^CxIK+Xkf}ArI-OQI&1+?zT%Y;7G1K>6dY{X`xAa&v z^IYH(XCi6&@yIu(b67ccU+!rQz3^Xp;r}=G-WeNv@DbjZKqpX(&+JT|%NU9wK$-B1 z=_yIMv5+<ge)r?oAIjaGx!81A6~l9WD0ex{;|q~3w+HZoG60NkE?GXi)X@gY_#gOr zY?-p}8=*cC?X3js4oOUZ;6t+2W6$;x4zMb4y=$#-@lwm>nuAH4E3}bBDzw%<-zYr! zw#64VsU=W9&r^mJ!`sg@Mo|8yYIbA~N@nM}P~RtbF(g2UwP@?Ke10||jpfBmRuWB< zF)0n$*|a6B=vy*xnAoTuz8$oXXSIJTYebIsY)}c6kxyi&TNd?cGMzy)+*I$IG26Dt zRW~+@(D(azwZ&dZJ@JB1hZQl_OG02O57Ky|=gD_7!Y>x#Wl9m9Dj~s6i5-E+e*i-Q zcEzt*P3%Go8y}QKc(u+|TUSdT5o5Q)F(`h|6=Zy>ocM`~t0xC9u^W5onr5(vC+aEi zx4>(q<gHZNwXgxHEmj4PA&&v%dZEz2Dq4J6q#A$r9RL$wi{|ZA_~NsFtxt_N5R9KM zxTN%jpVW`$cOmvx!7(7EujLbR7`ST@y`NwwY+mSTJ(umZJb7!*lxqm{#+JVHx$Y%) zz2EC)(bpe^%+12@YL7#V(%qQQ2sSJ96cKFowDD<pGrg5Fg7uDjAS!z7TX{8-^x??- zTB>y)msxV^Wv#}XNHPpQT^Mcay++Z1lD>Ioc^2DgJHDiX+Y;!+NLdzLWAONC9#u{5 z7?uK!DIcE3=hxc0H`ppPED<WS2mI5-Mt7vT2)M_~Cvu#N?MWCqcN@EJDd_bhDiIDo znRhc<;Xg)au+{m;(kC5fBHh&8TQw-#HQ?EpAm$#~8>k4neT5Rnfbe@5YpRMl!w)r8 zEGH8kzxD1P6$2UCZ6(LDb|AS_VP%F>Gk&c>;LMo;UqgnNR(+&|!!K;Ru2xW<+zd2) zkqo^vnv!OlTI9T-1yC;?$JjNZ+)pE>G0W?wvrL&Xgp>e$fP92+D67K*2%V{6wHqb< zl{6tWTNbdT0!QHZQ=q-}8LVtq;#%RXmwe<%_IZjJq(WALt>UrqpV=y%4l7Nw>4wJb zd<>Z`>Gp;LIppur*YQz}w<7PY(|VjbHSCr_8nw2VZ^j_r5N9_?t#tRe5&dWA<_4na zY@ccN<33%}%As%HW^+>0TG%<i%-m*GX%qLNhKXi0lgrENxbvldnlfqp4qv=HTsr^H zz2CoN<-KjO|L&ca!lR5nyiNE1ohvlluXv_TSCsyDdzFBu=+gN}{Y+#Vf^`9$_OEaU z-@hg~%Xr9s8gq5DoM0RH<Q<14A(*%EI@GV7X#bqJHRC73vw0KbJJDAynD+yd-xf4j zk=9c^gs^ReFWMWo{K7}nL)zPyN7$k{LO{^WO_c#dXFTJin++$-Uy=_Ni;V(W1&1fa z>O3g91OwjhsD^t{GOl4QB;%^F*pUa8r{V?OxIywwdQYA4HEz@;Z4n(<-urX#*tb#N zE_3iQ*9hi_`HP~7pvTKGY>*!RN8FkUKP|i6B;po{z0o6<HS3hCSZZy{!<8GAeg(pn z98^SaWMhm{RMjr=+cQx-+#qN)U#cKIT^A<j<)OkIiI)_3%rQ-HfhSxhxlkpk|H`=8 zi^nwb9@?Th0h8wGWUxeu@G1OgI+Pn-H|nxm5!K~fzo~phthm;+COsdfPU;x8n1Fk; z4Hg^twp4`QD|zw}y1%qH9=FDus#*#x!ww&tSN*Gk*eEUAY)Oc=^hggPjw~ge<WMVu zj}ELqGnl7&EXehg$E<A_Iz4N3pLg}-gA*vD7^tV$Yi13<TwFVLtuUAcBtLb20<5GG z65$>4@pxY>g`q*vqQZu#GRNkn;U<s40P=@s3FCckLV`&W`D?9Ph!N<?oSyZ4+ZtOs zPv$Gx_>0X=jz#Xehh8eno8xg0?yZftt;`8Iv})YE{5`KkQodl(^c=<CQwS1RQZFrN zj9IjKn;FKvjzi^5)1#vg<WtOk!Ufhl)*2sv+o((3i3aFkuUX4=dEzy;brPv3FcHI* z-%1R#Rme(*43&!4ZF-M&7UOYKT#XT8E<-hIa+|Fj*C$#h13#va(Kp^0imlr#Q6kEj zIHIbCtG83)r#e`$`xQ1WR<RVW%&&ZtZrloQtJN~w&TbP%z>JN97K(iZC6R*VyT`qI zkw&@2AJ8!HkR)EaV-<cQCc2lVFrk(PyfN*pp6i^g*|<UM(dcsiJ8{QZmJ=U68{ecj znkyXXZRn3nW9e6flTG{SXO*jv{ruuEH7R6vrE`s<7;TYl_O@$uZ>El(sgz?gc8M=< zJMyrLpl?VNehijAXhUGfC8j})f0<u;*Y9+GbXc{7J$uJ@{(QyF|Ga(ANM`4>d3MGj zy{W7zuKeU<V$T1I{VFr$9{H=oeR3$ciP5VyUEZ^JTL{YPLg$vFD9l4vd$p(OD@5-> z+5PZ=9(G~w0WHUsyKma~*GhYnqPqc?VfEZ4()mtnYJi5e$~`|uRt7r4ngO;IGU)84 zX4hvIjIe5t|Kv+v&vGq8ftr|)CBh0w2s?w>pPBF{jCdzXX)LBC$=X)pJ$`C>9hYpn zLl)ev!deFOS#*PJ)P-1gtb(_NFwtUww(E${fqCckaQUVnwOzC>7{8tgXY=!b5_TTK ztn7TWLbfa_T3D7l@z*$b3}zcl?c4xxvGgX*5q;TE2YG*8UHgCyvtos;1;~j_C7WvA zWv}-9Y$=RUl-HUIELfw|$+dPs@fdv%9J={OWgnM`?Y_ph8%rE?XqX;}1y{$B?XqvI zuYB-zxYEAZV9G>vs7`AOTPk-OvqbcMz(0OZGo9^1*@GYT@@ke>5(NJoJ_!z4skWG& zxY3X>eJ!zT@vDl-fn|u|j+r0kH4W4Yh$}ElSTa~!G7%n#lzh<+y)_Nlkl9s8S=|0w zW1Qi88HlL2H@V5lZYkd8g`LR@LbTOD3c*g|tC#8G%vEH)ddIju>AS$KxF}~w=p_Oj zn5D?9Sc&PHD|e=IVHKfyzwH9Wqi>L*DJ$O%U4XzJs!hTYMjvvM>`hqb6(*Z0HnVXw zhrHJ;Jj+?U1&!vchhRdOB7QvX?9hdkrv`UFRKyW?iqqCV2(E-DZ`}|(-j=Amf+gWZ z-2q&Hk{2VhUxR<F;6#AuhSo`L-gImb4Z>@7Nd3wRb!l(;#ICnzufhhGMK4@Ywn~|T zJ4PUTeN&~pK+X$tnuwPN+8@5RG0tcQ>#YZA#39ARs4=m_65iR4^AYJ(fW*8nI^7VE zU-lbmNH!{eK_f+ja$BP`K!>ngGAJu&@q9MRWx<dgisvpl80_0D{oL$=GXW&gP=ub~ zy8vo%CRv~%W%`nHwwR>Ko7+ZBWl};kb!L7dt5Sg>8y};7G==0tsLO#z|9&Kp2bR5$ z-|Qhi?I>)h21kG4!;?cAtNupD@xmUnI*wHok{7dbjr-sp6W$cup7xx3+P&%<K)bRY zNcmiSJ<RKnxn|Y&fu^FuZ03ain16e8h3Eh1S^DoPmW#xWVf0%NlF<E=-tFaRC1RWy zLHa@8tG6qZ`YQ~r1@hrGiY_*s?1Bl^aUOQgulQ`5$7O0n$c=G|(Jh7)Vkyt;7}>k4 zPKDZ@JjmSwO|lBTaHV3TDLzAQ<m)xTJ6I(>;tIyA16oMCP~aovMg{#vspT|-5AO_1 z@FoNl%NaVa^BdOpC+T-sn^8p+Q8X^xuQ0Xrq4%B8G;R~`4cXAT8%_GSE#q_YL~y>5 z*Q|CJayo!8)McKMKSedyTZ+m%gggUc0@gY`>>S}dGC=Q^|ANfvcl_ONR_g@WjKwG% zQ^;`8{>0@4Aq!?gOJ;R%w<Bw52Dnp5+$KTqNL?fwenUv%i?q`_ZE0YE)g<1=V52#b zRwk*}BqR5JfXq>UT~?=@z}@T=)X{}^RD79<EFW^x25&LXf*Py=-=&YWjsB(4-|Rfj z7eI#5R6nU<8hsBOKDYegO098u<y|bD_)gh*=?6<HbF~pxtb_TI<h8(Rd5t04MN%a1 zVbV{=$$Sjmmb`oKDNQV9<E?3b)0S>Cn@M3A?JoP9Kq+?>t0??OBEIs5Xo_s;$vBm- zulj~4VBk+&JHA-7U>14pnZjoKLLbd%5C#{tx%~^(oIoL`)x9QqzFIKjX5JYt`#pd1 z(HOA!$nlL7rR)Qs{3p`N%KY&4Kf2wG))nVh4PL;+<o`4UP2;m?H%t+3(*?h^j<3#p zNQf~1L)Cjd0+HJ)>e%?plH%)fklHq*vDonF*6YFbwGO_;AT=1!Yd(TQ0XcZ_eM7^I zTAxiQkvECfhu|r=uv^Aj9koCqN>?-u%NC)wqRCTe483y9D}Qr)=%7YuzG`j6yB)K* zXZa&#F?!72fm!_GXniMQ{PD$wTJ)x^{0c=?xvsmJT*Hp`W|?tW)VtN`ytHMa8=c^o z>0-c-x(*rb_vay>wLpNH|3bqWX>r;y+&vnu9!%sz!J35T1D(`(2lZxCao`g=lhc|z z!AU=YyRIeN-NVN@IhfTdQ6G;D%vwz@0CEqA^>A?&!2~lu1}=x#&&)DWM<CRu^wUqk z{WAY6MxH(?X_cXX5PKashWxvh#l(QeOygvmDB60z!+L#o_rw=#KkCOlzxIF6od2!i z`Y(mZ3HjcrffJdWEmq5Sq~eO!4mHC`amF=TE?W6Fq*M*%0T0qrFF(6#zM6Bwj>%@+ ziqAKkG_A0zm}Avf6fSk_4M?6aZ^+%ghbiR*1rB{e$Oao;ED2`;0zm**5oh2N;b8-A zD(|&V0)u~4?haot{2|6yoNsg%KS6!Ht<XDkpu*Nzh}&3BryHkKC`K)Vho!^H8vPm* zGY<FxB6y|z&bD0XS95!SoI%x7M}|{q@ea!-KNxiOHI?#dRA5*j3eap6YZ0h4-pakZ z@Z|*Mv7RS6l3I287=LW&^Sm_@41^PQ<YxJX%+nBa_4YwYZ+PAYq&DSPw?+SAyv>`Z z@l|m-+Bb<;C7308u?`0xWOjm004y6<yyfQxeB8w~thIW(6j0qIA?!kXyjivY+XnMn zYQI+~uk=3@UKN(4y>#g>zpBE0?VswU`roh6)LZbNnH9tHJO;mgNW*xmnuL5ERM4{! z$-Q#du<F~i!UjUYQBs3Xp`4p6e}tkk?`DzdpDwJ}gu7BS>YZ#1zII_Ef)6|jJpsx~ z@4iB#PEA@i$jk7RJR-I<lP$Yj>mpOBb&Alr+~5#{l2hkpTvB9zLCNO9Om^coJ;Csj zf|FneqZXyNdaPj2;ZJXA+IFqV9Cty_yPDO?S|rRA4^c$ZS<bnwt`158Z*{_IVuVrX zo^NmBr`TL_1%KabJ9C5tn~Xbv_ReZM$=QDbW=$@5rzMY&4Noco=LRQryOe%ncZ!3g z7)A{Qv*Nbd2kQHL2dklWvns3pK++H2Yg0e842deune1CIZ3v~_aLCOJQbnTp`z!=b zJ~>NX=(F7MN*(w~=XU_4E~}C{;LCHx8?!=1{i;<oZ?qoM=cN6FyS>Pb+3fpv<2J9_ zWR52bU(Jr0MuqXuY`kVSn*JWbsGm=Slu4I&Wyiv9?MFf9B*VBOZS8gz;$Q-$|2>=I zk4FPGF&}kjK!PW|ufWGczIhwB);=rL2%i!a4z?I2lnmJ0zx6f|8Gciui#!oBtgjq1 z>(|7Ap~39*LPpsl`_vwhcJP75nPDbqmwaBn&4~=>Dd;(?_?|nSv;<fAIrfr9ASg}^ zVlxYd`_uk|9{O($*8fI)niO;%<%HyHXGQJG@fY~Xt!Q%Id+daM$gEv0_E;%)$V-4S zyWA^xe_FkCYdh+N59+R>xw#?x=dJ_2T4NCtJ7T_t2|_{Rp+wO6e<?6d>^41caEOVK zDkYe_NfBBwF;BK`6ncX=ES%GcS?6{FNuk?xDgPBkI|7t$yf}Tii{hk7q4}?c5aWbM zY%Y34Wo&s4%gK?pQ$B)T=(C3~zDxcN{46*%YsC<b8~*@SJV82H_sQ>RRR>lhGi9iu zSlSw;=2a}m!fFxY3Xi+7^9aCMey_(F2<L{gmwx_OmBmyA9Ss$WVvHY+P#i|}j3C>7 z9tsOl{SCK4u<EkM`%(;$zwK}%y?4iFPXStmw{V4QYD&?9S0-Ews~eJy=NfW%QhdBs zIk77L-1oywPy%clP2)0x(od3Bn|vR!)P&;P2ex`wBjrGnJ-#G0pCKeaSrKbb-3d|; zAos^El+=g5V-Q7OgoW;<=JHkJV=|=e{0@2V<)6+*w>G=+xqQW`AlSdi&sRhybM)r2 zH7}!K*A(#t@w9XFEx3YS&^)&V+$Nf+d}Pe(tHgp7cj?_HlQl7S_AC|2qni+fqMy~k z_P=U8iS{lOlYFqL_dPIOtyUNd5^X*(gqCPN(K;QVoM=NDuW^LShP{t3(`ijq4Qd-s z^a%gGp8&|WyUW}6rxkMGV&@60+%S96avlEZpXgv4iif)xJL&v>RZC<KcuJmCx#O`> zhH_(8NwKfv`jy|YQdyB_y5OPj@%qVae!Mk9Cv1!GR9^iol+YlrZ*KnHk&pHPI!@92 zZx;%Srj$6~ddylY8`4<AYa-3G!Gb1?({*q_mlBKyORkst5_PEg9=FJjxP*UUtFh<I zN_~}s=ja??qM`T&x`q^X&h&-t@b(Ra?Io<EbwT^39=uk|uXZVo3jR(I5~8{uOl09i z%}W~p&Ul=WjS?GIsUkP>#|L>2STsDv*djVO6U{QW8GWay!i3sxF@@bBH=}NUb(t$L z>z*dG<|Q?De^sDJ#J;ZE8$1-EvWW>h+6eRR3$ma=e4?vRnOdwcTWNLvtnQ?0zP=e` z5x_y+^LjXKg(y!Ah6zL)lKRuJFWzQzuEG0K!~YOp{13YNuP;mjr~OYIG|dne*5TQW zg7adl?zc!Bt}e9htrSJdiG1U8k7`Ob7JRIe%gdoQHV=b}X6DtMC$v>!H>rqtCYMw% zij(&gm@_g&g<ZdI2`K%}SS8XFKj53!c3@87S02(Ji2D37I=;M5EmVj!k64w(mNxJ* zKo}I2B#qJB?jH{<+b1Y{5I2|lEcHrjB66*n@5n0`MwLTp<Z}c8Fbxy?NvYDYLwA#{ zYs%#l#(iL^f)`#vxO_VjEKMMRjc--vqkdY|-*uzq5;=}zZ@7f;?C}1zXk7sO1tUAo ztOXY0nWdt!ZMbQ#W+;fOqf8tcT8}>GZ5VZV2(zN+TuRwr#E<?cE5Ez>lqz@dYptWw zE9t%B62lfyMU?q1zU!CaW!lM34xL{n#~*xr5?spww<uh$Tev$a5;Mt{s~-w%$w`)* zv6EQOfdT<=J&jPlAt0m+Cbm6}-RJ{5IvEVmi4TDKH9&NeXB&s@fOy+DMO7r@YBc)R z94Lzj8h`m$<c1G^LtAxCg^K^mv2jDaKFgP0=vc)m*A*cR9aV$>Dc0GtFl{MPxbbH+ zFCl?7FGXckn@O*lFbf5zLh;0v+w@G`j-80-CHJ?BlU*F-4wo=Dzy?E6$pP-Y;R}VT z_6Bt~mI1oFDvRLI?jx12+TW}59JFBjoxkwYP&9(c`4<RGDDn}CH8G00#HWSko0?*L z#g#bTEqbB1?84Y7Lo0d4$3fdDhg{@zuWPcuh`j?*4yw(G*-(D$w~jCd8KLZqP};Ky z!SUW6mwB+5Rw&8{;<h^<i)0n?J9t($o+sCu>3wG9G9nM-BHr+VK}4lJG-;j_bN)tJ z@+p1?SUnzn!zK$;h-s_-3`_4V&|}gN2e26qhvduiyP$euD9W*Tv_if*&SiMQp7fTx zcr2h8=E=S=V%>QTjGeKnlYDV$*@tpToq$%O?~L8zdeBy^D5Df_lB{Y+D<iCRQt|7F z;W=Cr+8g?l<8E|Z=YAq5FN^E?6Hi_-NjJz*hDjUuIwG{)m}8&YMv*r?q+=##PeM+k ztNI^@&IOBLkg>nA@}ickfLXeivK}aaio^XP)tJq?$KrD}Pwg>lTZoAmf}85ZAC|<@ zUb&vbbebI?gCZt&1k!~QPCdU`P(@EsFdUpdk`ey@nLJ&#xG-wqWb=T}AjYJ|$>_*c zhJpx($@}y`dak4J6o&5x0j(63KyQU*wn{Fy;rBaud1_@UB|W%nShcSr2Z|=pluO<r zy9q!%GOJbbC6z%z0H9~EkCvjp3I0B$-lt^^rmWPR`YsJ6w|unNg}-`5lElFyiVXSu z@snRw)vT(Y63dn7I|(?LL6Ihvr{K(b;rW#ts-DnUTZ5mX-=TU*KNn1Z2~fe|xa{71 z&dDp#rq&X2$u-aGF~AghqpJUO|E`@u+x%6yY25BsJ5oni$PP(8T1v~meVBOd(!B!_ zM&HONsj@4v(VO=9#1OXtFMVu+1mpYa!GAob)Sg~vb?^I&^vi^#T*zcXC|R^RBSNQ? zx(;XM-Y;&SrLPiwFCP=p|LAg!xFvQJT*jt)Gs9VIhqDQzU%k_&x0U=A`DjtP#SXCn zgbZ;w=&Qp02fzl<rNWH{-_QZ`s}+9#I+{U+6Nh<MCBbJWDjh%Xlj4pDH)3B&KFm(u zF3x!JHN{TY%1+p^_n&&}60vf5_st4t`*O)ga=PmiH!Oynx46bU+f;tv9ib~(4}Vd3 zD$c)!``bL$Zh_pp;-_*~2cc!>V+N#DBPV6RbRrae%UM9+e9NWiP<xi3Ij<79E^p8q zKG>j4wg-N4f(JyWK1`!p8#>5G^aiPJ&*g&mrikH5j~+`~g>qb<{ks@7PFD@a((hf@ zhTO>6%x>ED^Q_#asI(jFlYI^2j=ZbQ6~*x=dECuchu^=WCTzU3G3`wzR5sr-ioyTP znvxAtr=SI%27?*-j_{2vT<im!k-NH9<kJSI>GVlyL}k>b4XB96sY(2^tC37~&r1<^ zcH<>qPV~S{u+6r>22~Q2q2M6~^+B&T1o%Y4tj^B^HV-o#D8vE6-7L4(M5FXr;Q;dM zj<#2&;b1Q&wh(lcpa{((d@>0`>p@EG2HRHo3vZz8ugB=444Q=4E)9tXLrw(9Dd5rh zXaz$~eAIx%v*TdJbvws_>)FKeL}G;g^kY4GjN|oCo(tVEkf2oc97*}`blwZ@^T%Gj zU|wPK05LRt^q?wGX4C(f+|l<#f%<95EIgo~CwVs(KE5)AZ1<{YWxcBtAeWwcnJzUE z_si4)P)I@4V+~O*Ke$>@)8m2Qezq+I0ZGX7i)6z2IPt5MW5xCY`!dSYFKwzHnUw#3 zOtlZc#l)rzA92(<*57yg{uqO+%OP27ZQWqC<T|Z#;X*eI{;PGH7fYw2%+LRLmVxp8 zuF7LBb_h%6Ol%Q9Et8%f9yvQuJB*lM`R8UYmjP8zl~!X5vhy(`;7H)xyr-EVfxgDd zt*_`NnzchqhWCx>HWT#OjuKA()mh`f@-Tf@U2GVz+d^;Ku;{f;{YiR{(=of2E_{sP zMY)@BZ2Tv1BG)n25}v)T98;M~TDg6=2SPH2OCa?#6h)*_rLBl2+b?$mOzK9_L$jnv zS6+L_1+d`oh}7Tv$N3x20a=G<e$YT9D{9z_Ec{vOc0;nz9lzh}q@<FMHj!ylf?9OM z(v~aUw|GqwWu9C5^z7Y;GR=PgS5oSCj>GKohwB^e#&P&?9P1?wd_ZRDibzw}u>^ik zh)QYHm_+^n4qux3vz@L$wI7Usapk2VQ5NnS7k(EWgRP3>i)XKkvOLN&4Dcen>*?3C zW;`9DOoa-h;Kd$6!MuLyq{5=mlTe$+M}xu1Lf4SJXv-^(-dC?1jwC&U_Tj}~9$`6x zuyfv@F7x=drM1E>4aL5#qYH%EsuTzp0{va^VgW**W6?LA2XzQqC&5j{5H#_dLoL_Y zfzXYQ4ps@65hZP`{(PR(5pzMB*%4T*4{dZtM)O?px()FfKNXx*gU#Mm^*Cf!-X5<* zb=g5&3asYu?+uhismRloK5i96ZI@?8-1!}%VsB7Z5%BDFu$?3Ym<K7fYUiO0Md7bd ziWdh!9`D8)GK{tE{z$Q-Ln9h29C7H)gPjFtbV1<KM=U-}=dZuX5RQc<+_*5Z7YZU- zfSH}S>{7$>&9x0r14J0RrCyJT2rkxBjp^S&l*9%xzaE2M1dNa4fh4I~-W7}Yg`Qgy zWPrNR`klQ|%yky&(+SjI>o&9g)%gt454_tzie0iTEi=|U9(YctzJ3vJnY)FAdYh>v zGAi$A7DDW+t&(jrOok80Y^=;lHeoBa5U89f`2FN~V9dV3_AtNlc3i7)<XQXcv0vGE zcI+h!0mU`w3y~RsQ_jY1jl9$))m91{qChoV-Z&xuC!FEE1p30%Pu5^y<ZJ_+O)vO^ z?;rq(NTdXtY6O1U%EZCXI^s3fr1cAQ`pe?0*pz|6Gcz}g4odq%=4or3!U&DCOG3sX z6#jwIGqPvq|M!bKtij#vg>F85F>SVS`N8xt!OMSMp1%0&_&29{%Z51feD**51pYCr zkdR^Jh%I9L<TyAB-=zqHBTqi7UCPClb*MKJ-%T52>vQG3Z3hr?v>j&_0sDcm&(V+} zK$3Wusxva+UfBySp2>Mo(g8}%g7Af$D}WkWKD)B8iX^E)!fH?bh@xHLb=Co$7gk?K z7XzF>UVBYoh4oqXHN9bEYkcQG$Gtd?=eFH9htx!3AlRCv%y=teU1*QBi_=pQ{%(D( zd+=c{cPD5y+B7$pHY!0>G97(jDSw8rR{cO;xW&9&L&0vK#xMSVX@a+<_uOw(Eb`*T zH%Xw);z4LiM${@ddP@>NtQDTPsqZXwbf`Fgc19n;s$n(|7-r-zM@8~tb{5Oso*>Ev z8IS!d+K}xkj7bF!0+lIX>S3mQmltz8t6nE!pyjTX0hG)k+X3mWx(j4wgZ;a3>%Q2L z429qt!w8T90@N-ZX!araIaG&SAUdEp9&Fty-wSP2iw`Cq_Ggdou#Hvx*#MveK*ytD z2vJQRz66j-%X8B5X1VQU7z<Tn1><h#jPhKMF%*&fwyW~OaSJyWce9+IXSB-H#^=L* z-Eh*zXLYj3#R`_#^z24!xd2&QCWMjCEi%-O+&7o>P-9b7@ue^01gE!>g>@vZXZUm` zXj4PiT0vvvS!I^Yr$|3&@BBP;&^qykGHhHY1wSY{bf(b)LYhX!U|SL6d%qodA?}9# z00=k`2Mt{d+8+uQpTXFrP!HS1ix`75UdDLlxr3WyZ(P<rfjfS@30)!LR+JLY*R1c2 zm1FIzhZs+F*^Tl6J_XvZ=e@7qb1DQgh2f3z(eEk*2L!}(-yO5FibwHUJmjRaEj6&+ z8@;--H~YoId&|s3HJGDCDAK2OaO%UnU3!O~I^r^Q7nYQMe7m&vZTfnolu?Rc=zxR$ zW0cPFlF?)!G(9F#vUxE_b@<Yb?Sl$<;xbs<ms~5T>rWqfk+J$I_SPDItT3yQ|5*T3 zIm1^W1^OsX!oaWiWD<@J^q<9*UP1vQ<I791`M_yN9~h6H`N16z;eq?Ap5)6lrhdNU z0s$CKC0xl4Qj;fs#`#Lt|J25rxCgymdmy!TW563N`^$UNdzkamRC}}XsyN}}<Eyt@ z{|VX+4B+-k;stKbym=i%8LqM@je7NW>Fdjg|K~efxH0o5=+AGNL$ZiVr@vofHcuL7 zqJ6ZtWd1b0jF$OxHb;>BpYLtS+K1|CRy5J!9zIz_<-f!@Uln`VhrA=oviJw~Yiv1x z4T`%4s|<lG&LqsZO+)vvR)pdK8s1Jr(RtbVIjq-<_{Ah=k-An2fexw|NCgnaf^b3E zH$C5oV`b-RGkLlEBFPzPBqZ+eDHC+-h2;0p37fyG%FVWk_?}TLaLd1;u0u;0ga%+} zsJxvtc^_p%qz&DH$0_T8pLfI9QXmpw`srGzsko>yC>r}y5(hMB5Vj<I_kX%bw;A~J zHnw<m4jmW_6}zUScZ=(=w2o$jwAf=E$<R$If8y=QP*7r8%tbGOcD2OZ;-yku=1eOz zqD$ote!d|0J_q<jx2_?OE7PxCBUcWzEUZFl3%JBE<jUG{|43rtnM4#{;gE>THD4j; zb7z)SF8sx+zYR${sVkHcXhfs=rVyYLFyCYPX;i9HCU~j_t&7;AClf_4;bdkj3M6pE zL`=`eeYNKOF{Xw>XZ4F{A|aUBr&#{g8rFkM*DT#%*)7ULTh>VE2;XJapT)~Xa6+6T zN7UdqEPb;l*DEj`OX|T{2l%SX1?mWq^-3BjY!JAERVCIY!*8ECVFULKUvE;xM92K& zO9F3jY~QbRLzIu(7MBki5}I<{W3Eg8<t2!3>&@R_^ay4&f(lsD;ZyPS-3Q)uIcZvu zT?<(swo2=UqZ#}G@7-0yS3J4Is?Hb<A8_A(b~UHmwT>g(<4;4L21~+^*BW}5zQ+OY zZ`#o(VAP7KU@@UX?+yhs{%GRWZy*0PbQ8%xK2E<WAMC+N`{)~IT!m2EA}4E`;PY~x z1MmVsum$WlRPj~xUn3j)FQgP;X_tb$5e^C>9_S%evKaalL}$s~!jlQX0hbo7WN9UA zH1<>C@#jZ0#lh;+RGb}e<6;a_Uw+o_O)t3Q^><+0;psHe1Aubx$-VcaME`PtSlaj? zXXlS~)V|1kc&;ZGwhwzW#66hftWGSh8zGxtctYHga3c$)SlsU_jTOyzLWEhMDV7js z4o1lH(Ro)m+6+Y#^rLa<9=f+r9e9;C&7Pg0Bqn3yH}z3VIzXt=o<2%d$tTgFmIR^m zDbk3VA5cex2S}12(cyp%$nk&L5RGq9L6>Cz*kdV7^~3TD>?W+fpQPvhE7oRhkFw}L z)WP@8*eeWQx_7S7F|oDp{3`wPV(QPknJ-L#Ud$}Y964N@Iej4=DO~(-dEvdYDP2Y% zifG+{pNSG8F*o;V<UWsL?^eVSWtRM&XB{~z#@kM>)CK-3j{(f$u?l*SY=#?4F71mK ztAGcg3qVx4v{+x$8<&QuSAn9n&3Z0}k>dsGTZT6E^?>nvw64m#IixJ_hLD|V!dVA+ zRGs({;8<z*xxcGVmZB`@Q0ST4T82_G*LVtd?5HKKB<<J%lCzcdQb?4xnY_uHTUR2) zqQ4bh&kAvM#DRf`j?TIXfm&8&|57C;|Fg{4l`IEIcRf#Ipfx*qK~f)ruO-m;*S&t! zWQ*3>mDZw*YpCjN!4-R>O5;Xv{O)+8mvakqeYyM%PgxD^4=uP`%=$3zMsLrp?FXsJ zOS*_W0bTEi1btu@Z*5d#q#f+WVQC=qv7+v*kKDBgIb<F3_i^kg6V<vS=5CG6CQ9Gk zRLn|5Yb~~UEu!q3G<|HB-2=3cmchGn-A@N8b`-1+D9nJsHrKW1_p|`7UQy8fbyCRH zfJ~b{%lL1EO3%Xu`N-m#r|QzQ8W*0>-WoGait_v+YW%V4TCF{GfoakK&<tVuvlDh! zuH6OCloLLECXeZm#%$B_8_;@!tQw*kZHuW|{?VbtA0zLFJs;YPKllwXrp}*E*1t-g z-Vrc@-48l}o@0Xn74Fe;e3v>u{mX%;o#fG$4g{}orP}0>PpiUR>P2tb4j*iXE-!_u z)6!lD`B?01Gs|Ka8cb3fXDjzY)v3wJP;D4Hm}*DHvnF&o7~xtqkWiR~BVz!w4k~3h z-@(UaCWK>Za|*jRAIwONYPEtnqh&<co{Wraa#N11^lUV@R%2JSt_OUTI@*#X80+wA zd7V7aw){hu6^FaQm4&lmJ5oa87lbG24o{A{&m0rZa~$p^1Q33~5u-g*PH>;!p{`y_ zUNzDqD8VgNuEF-sw&5CKBTC0rTL_Hb2pGBv=L#r4ficB>GkCpMae2|hxUAw@2(CP7 zgn+~OrpksFM>3>Da1ZrA_m;nCZf?<I_^PNE2Ju%(;}35K-=y*oFh=+uk6Ie03W6(J zg@Kfnu;-TxKbOK0VV*|oMEF=IpHfY~LvwT?@zoOBh{H!RZvO}LBoo1YcE7K8cuC}U zWb^)=jBT0Yk>-D{t5jUKlf!xNZ^eElqmhx3pN>;{lW!xK^WZJ86wV6AeD0zo9AQza z3l%pCc%Dyuy?kDiASzbyGZ;uod&Ohl-sAz8`ISTXKcdD@YS|A|4-ig8h+^U-m3xrK zqJp4WgM^i68dp1IU*6himz*rSU06dlg+Ovz7o6Uo{lt1JzOTU^<cGUf-t9Msc#I!@ zaib2T@hJ&1vxJVQU!iW4tmZRCe8|!|(@kMO4L;DYhR9QV{TzT#mP$-^i%-{iYwly% z?_tvtdLp!;7-5bLRe1M6L2@_tg+jqbO&L4Utbb}RXk}UC0TNhPzM*IX^vCin#3<|c z@wE5}M1#4RkKx#bPC+v8LwBp-eSmvx*e~B13>Grpe&E^xiBE3&;jSa8q#WGbN<s?P znWEpk-YDPYf`D^Y!UBQi@r9a08}^$d8^=G!1OFxb8sZ?djF5-WI24-t`ljyEH{%?| zw>QW5_WVPw^`o{6MGIbUWzCNsI2*&PSdt>>1Fn1;Fdj^*Jp65_M=?#nmnzGF<>0gw zziOz6@3iE~9#czm6(Nx_jlp@ar|O3p4P9!0#VQG+h~X6{jLg6-uXqg!1NRreyg8S{ zb)KE9$aYtOhd;aJlLw6i`iT!^=yk&f8c#tWlG_R&y>R1SdN3&v!gial5<@%^kWnoE zt4uPkGgR*C&cV@lPTLu!Hb?t#{HLwkR-US?>UQ>x@y3<8MH~uOZ?+D_x>Ra`$<H%w z#Y5mm;x&01!iDF(s0ki-`lq;UyNvglz3EEFzo(I`2@9DyODDx)!djx1APaW*CRu0z zuj>3j8zv-Uuxo`{su2S6sBoRWf9i1Fh<tOS1ay(EKq-Ml6~g}@7)9F&fH6$>8}%O( zlEm!6%La<e>P-W7Kn@|AIV#7}@*mPmJ~o^zEAiwbRD~S^utoP=OCx%1aq`r&@yotb zFH1JUd4zxV5l^@gm3erLKgYwmUSBij;2_`+@-+o&Pd-HP!3Jsf;2uNKz(d}U=MFw7 zZMY<Ch-L!_$L7HX4HUxIQb2+j8@u%HN<4{FkmJCK0t$);n@8{da6uwklkpJRQesNe zrx!?!dRF3e?H&giVuN74Ip{}*p16mOEVO+$y}u|{n9~=`^$#v3LjKeLtqD3&WfwoM zoM{>JA8YO`J@#l0kvZDQTrfGwJZLFB`rCZ|s>4Z|y$Agtg+VI=?d|Ql`=cw}V;6S1 z(FIsKu^)8XJ;*F8Z{hu9ETlC#aJ(!678Oe$adzO!9z$9O`$3Yl`r@Dpkx@>8fcnS{ z2Ch*vcFFg)aEpSC8&IJY!DmAUaFCJ|fdMIbI^>bg9aBg|sv5&YVP6qzGkzdhPhAb> z5bQ$2t8a^I%h?>w={H+A2LBNLdaoSUPCW$Y)Wi*#f-~@q@*tfkbVIR1j-Xq5C{tP! zLEZuBVUwnRr^eKFtZjcxm<c$=Q$xbhmvkD<+JSwpkR^&^Fi6N%b=-F9O$j1!DG#_( zVxU#DGv_7(jFn~h4|ey-3=Rmrp^`9v4{r2#ckCU)*V6MDB+!=ybPViGhw~963wj$t zHcA5TE&)dmmjO^UitOu{)z5m^!^H<FCfdHTth^elTD+0kNpECz#G&Ld<3i1U_zgm- z6j|jg)*>bZ;y9|UR2In9|LiI!93M$4|J-NQfAaO-!J+@Vs2%Gx9X|J+=_D4$7M0gf zI13<X-5)QtKN-tJ@E*gFKXl=)y;~#F5R1GGn0B@pd>;2S`-A#dBc?FcYw6t=nh;w+ z5IU86xgZxV9WTCw1Y{8USz9n&M3kkiJe*XuV_Tv9>BSH@pjr?3H_d$17t*cr-H-fg zV0Wq9fb59<Nn|e&#fUKYI3)wQX)F5I^iSzkQDH>SWs)|0&@LuU)ZyT8PeZF)hNosI zXL~sKSO~?<K((BJv{-a{3j}upkOZDxx>RL(Nre}OY@H=gC?Fu~wVojQzg<3k=KO2h zlBi!zP~9|6PZE$#CF+BQuu1a%f{C45nkA4&8T*=Kyq=dZ<f0|iam=2T*Af-TDLu12 zmZzbDICqkvZMY<*Zx;UnuTH@4O;tzV0*mK3hqm;BqOj#H`RWzS!n&anp!j3pL5H*{ zyU?kW%LZs+O&o~4)!u~qR7^YZtlX$dtMm(JF8FvUDnXZAOO*aDMxf_O-Bnfbz5-ky zb8dBk({wAxQ%LQL{^m~}MlD2>ud5hNCnmke0|uj@pJo--hnbe@R5gO~U?&e@cpP3A zt$BcJC3x*KlIE6gDJb(_;RfN45;(5ML5h0_f#4$Y%F@ir^9TP)w65HI?R#W!O!4xp ze>?2&nM{|-AGP!6{)$XnqNV4f=RD`9CL`y6!e0Da;<v}~wW85CQ=|E1`)>jdHEjZE z?@hej*-l@N->2Nx*$09r!UG0(tgf?}kiY>}AYgB<JEy{sZ`j&;P%9FE>(F53c)}vB z;{ZV8rse~*X`G<9*q%LSt83w%ag~=k#>y!|bN&^-=ysl8WcOAc6Bw=w_b7g8-J|Iu zwE@E&1W+}E1xPv<j)7a|Iv*`b)}+vDPK6JVDMFsQ<Osv(-pUXm>K$|mwyzJ}1%|Bv z=X|`YHYu;@252*=8wYs_n_q&gOdm&R$HluF^r!Et{?(fkb`eX#)9HY+Bl?lfN8Wg& zbBd6<Q!3Il8y|Au42G>7ad64ZRcDI&;xCNJ|BJP^0IRay+C@bLMOu(XP!LhNO9W{I zNl9VS-O}9%(%qfX-5ryhbazO1H|z($Z>@j*|6co?>#Tj|g<f7$=6v7hdB-#29%I}C zx-~Wt#x@qRyWIsC9spm}$C$?Sz~VN*!{gabTE)UQm%pp7@pS|6FO|eBY4#QgNMCx^ zi;`AHdRdV0)oqG0B954DL+Y3SyCone2IL!)aD0l;v(Z*tF9CCHsH0@UE3dRuL<txo zX0?!@2jy|7IOyMrK}J~8bn2k(P1*-O1_{28jSjjPGa;X1#qpv7(NyPPeh=?<j*+lN z`uF$v1~|e}uHA+J0=A|JjstN!;Dq7diQWWlAdi31fr49*Gd}$My@&O8e|8-?<|}fW z?9V`?B_qsdb-}Pu62853>`36-hFtsm0<v4%$6!3g&?()=<J}s)ku!cmGc)yB;QbOX z8f|R+Nv6Fae3JCt3^B{#%ZsEZYE);SkALxyp7(L;9^jySAu@HO1>++^?u^)}Q~?AH zplCN-VjL$v+brRw<7aY$mjWKtekySQdjov3#!-8qpD{&Vc^!nJARTvun^0E)|4_mM z)JKb-czf+s3eL2g0(u|dy!kJmfYAOIGWk9zev#{^P~qKS=8QXlSbf42N<~tvy!y-* zn9_KrIf=p<1*%BjCwbO4XMv{pgP-Lvk&H!t(*bj1XN9B+hp>aiqpTKBh)j}XwWlvf zL19q`Sf3k}W^dtdb%r373inUjvGt(B@Qy_?H*n|&90rE(okV7o-u?87ZZE?c-@UYB zM4*hVLm*$44QnUHbNGEm<=7%aP+xX3AV2E#28A&@%%EH%7dM6aKy2jY@*9V!cD7wJ zDyM7C1-1o{7B4R2`izrW8>F*&pgXR^zhYH2rg3~Bi`h8^*gbIqH;S(=yTz1h?nIot zeJ%I?Zj}Qu>lPB>&A)<3si9$oi%~Z+^W6ktomt%u*Ddqsx##CaapBwlEU-A132VGQ zy55>U_hEHu=k92{{^m?i>~NH{h~_lUQQ>1R=d#BAd%EHF+Xc>DfJ=<(tySaC$_Cwo z7jtK$gVUysFyAR2rW4EbK56xA#}?4-Tf%k8&^E7=x~Mt%WttN}nLHrt`K)71J9+}J zN-(Crr9AzZ;Xj+g?{2R9sQrznE*TmwAba?@EMjqARxn078rjW5oB4V_qS^?Q1LfnH zPl_o_sci$`W9MW|@&|y&wUI!P*<lLKp<dkwW1VB|c7AvdiyRwJ5Dgy&6^+LM1l-x~ z&5{lQZ3kTdtr|=(rT=becn@bnDVf}yzfFJ?GDvfmN%dg+w$Mwyxx$qP<DWpw9PfO7 z)Ccihka5-DW_1eh1#SZ{OlI#M_6tWGYkU1HP6Jbg0F3t4xLPt-&AF4OC4z?VN<xd) zj<i;T;2no+3dcT0^)fnaznt2go;o(tmY_{<YUoWqoHXcmL(5?_5hJnKdn+o&)K6|8 z^osJnh}{q&hs;l^%`5vNn>~QsoDEfk$t3~DR&DX}+Uz8_`z;mdqFF;INyXXN1oVXf zYz=_14^EE}euprG{=mJ!_l7SK7DIT(=677CP0^!9QWO4F2^?X8lGKA|#168cgc#~y z#gZmWDhEJL2$M{>*@!r!KY8Sn^rxU#T~_)s9E@%7+If;TDVk{@N<*-_1z)K%aGDLs z=tk(J%a8S$p7Ch`p3YL=$L6mL$^iFzU+pLt4WNYLC>z-w)N-J%)zNl%`hidOu=sv< zOmZ>c%o7$kuOlEB+w0Q?S`4Hf0w|Z9(F<~|>Qn`I?Ld*?C~DBt-#Hw>gJoK@V(J&v zTePLFhmuZA#iMO9N~^QU65tmCCNV(0jf)*Z)vv`zW7uGN!_j!QcZ+?y?s7?V9m9RP zb>4sX+w?d09b;qQ{GHPsGIy0zFCfU&HGnl|P#Gr+sraAK+>?Le*!v26Pi0k(!>ASZ zl>dl0Taqb669?+ua~}b650K&fwfkyct2oSxIL!vkiz90pl20kT=tG^Xse2P7F&dfp z6r)NP@c%%<{5Ws}>340iPvf%(YGa@B?Ysaq2p{q#B&%4S*VFP5mjv<Q0mA3OF_1An z_$li@BUeS2{d_qcJ`wOHQSb*m|CpDF>uX%6VRAJSgD!dtV3Lz|8Ne+j#WWkmay-EC z*bDSWQgv!ggl+1bzYO~Him$&6dyxyIl9nxB?r8Tz;qfo{y>R!Pw%0xe30{Y!?;bOz z{p%p2<2PN(PQ-UBdw25(jTgpu&l}fhA<MHCx2s8)7S{v2N5qr=Rna&sk-D^XE`N87 zc5qxzywG^pY;!SvHx>w}>aKA<n7dxQy6tQ{$+BGua-?-xE4+2NXyCrJx{jH@NZP+y zrL5Y^O|P7@_Z!OkO4IBB==T#Lhivtl>8LYI%@l;4_gz&W%L|gMeIr2awL8_5VFZRy zd0e0egeZftX}~hP0MrI!-jIP)KPxPd+p8fASm7-cPW?q-RIVmID<Hi$LCq%f4VW(< z^8`izx;kOGSF18appEGl9XO}wpo*jZvM!*EYe*5yoaQYY2*IAMj;|M;?$jXClt%d} zh94_jbfP8j%Hv&hH;;P2Xd*OMID-XQcJlU2%yeC78J)*>fb&~tEc6HN${H*@5!pPp zBO5j#qX$wFzD2z|$!}EAXa)?%kdT|RW!QG#0C=FPl#ga7x_C<9d39!>cM0^K*Oh;V zO*T$#%C`B*2|LJ_i4cjEb24h-i9kV-q2fI+8<^YVwUd^LaZ0DSU%ZXryQXjP97feT zg?%jRQ_mIK6RNfiijjhDetz+fbtbLXz*{zwQ3uT>V6GmhC(_mRe@B$d_12)(VHBSD z>)P+s6!RJ`8)8wD*C=`uR|6jU8ZNpo0xG<D-alEsZ30b|FK6$i$Jl2Pg@4PO0(8zi zQ#{((e2H0}MN4^F{A~h|D+4|>tyGYq2VAxbp%qzxKWh1yrmbko9kcvxKnEqd*U$TA zDEu`6+}A#a*XQ<}QPA5j9cjM<SxZI5?=h>FZ!AD-E*58KCCl;iv*p+Z11NB#9??l( zu_a4dNEEvA2+d1GCei!WC!glr+%$Ww&mh&eJTjCo+baF(R1S&)cp_#*v3tMzNH~wh zyP}!bb{N{MJOf3=raHE0PIybD;{^*~M9BQX{0-&xzRTs8x>MEG$-5%;YiHO-(1`N& zjko-rsyp$u=6tWqzKshb;7JC=NMqWdTnCi+W9w_<eOVZK^V?h!5VV65nvz#77hp1k zwgWD0HKT{^E-$D;lM>{;tCBPA^%;5-4tkItmD@2zGES0sEmz0vgPE^~9pmM|MpL`1 z<5OJ2J;xc(227VDANkcJtj?vE*sg>9Vr9y8mY<DPEQpy-!C_+FIlcx{;`Cm_+v|FR zRQK%V%e|2^Tcv)zy4928*pLswpi>!egGsCNM&-f)?+bA5;`Fc_^xj=MZNEWalX5$C zk&@`rZWSgn^ARrlvAfo7SY~E!)>2f`ans5eu1?nmnwr0v^adx9tTmQ_vPp&i;mtSR z^jz=Wwc8x7jT5g$DbF0F(NfmMOW!pSuSz&dtmXYny!}hWzcEtv6sGH07|#f~h#l{$ zG_-!X{lvwq@%u&YIgaxVvYXm<Zlj0kw;S1pEut&!`LofHBc1LDJoS*~4+ESm70H%} zXv3gY8n`S5#P*cnfpz<51L_F(Pv)9W=*Og99{@sFH!Ai)0zm_b=O__S!$hVmTv||u zfl$K#fD$K_0Y1@<DkfXSF!;+zV#<4vz;6+=Q%cgPPe*6AAgGbw+tMaTi52pIzP4ko zHP&SDh^bm#kon-~U3B~kft|mJ10c{l%rQ*1Xfbqp7`^kw9Knbld;pZ3A8;7MM+4X~ zL`on{V&THl3JvaHLjSpX%myfQT*k;(v<4%VVrKyHT(utWNKuSN9jGIGCIym>YhAI4 zc?Smya^j`MAkgO3S_A#bRpC&>zT=Qs@9sArSQ%et9t|wM<E1s;;hW#GD_IJ=@Y8$l z)i494e1`Fwuk{Lrf2vei4Z=z~G%>1I@9z{2?0n{TK*gHo*?KV`T3uG(@0$k$4CCd+ zLm3k50y&nrS9oVMt<P)lOkwDLTA=$KW&*gXb8LWuD2CL6GR+i?pta&kb3nV4^Bd}~ zF!k~q!IFO^jnGpGBACn%(A*$I?tW2j{t9B7db)@U4U~PyE3s*A43Z4MByvWzFI%`{ zB?4DIF>j+|eZ2dP?c?gFf+Gn#DVoZqLS_Z>z{Du*WY=c~H?LDW(H(x5V)VI*1}#l? zjG*?(i-<>g7@Et%z!v6R*q^8wqSXQ*e!x*XBrnTW0Fe|RRRxg9DORBh9M5ZHMgNCU zwtbd#)UtKr4C>LpQ2Im*U{BwHR;~<7#65W&5Ex(CH;;KQQyu(nNj4*ENzv>#dXF+6 z%mpT1T)4p~uXSAxSr4E|#+`e};)uO;0ukzH=DtmopY}=?7gdL@o4Jqr?-M5u_5$Pt zkm&mwg@xyd%)=9u_+xWVM)BlzMxdcVUjZM=_e@r0GQ$#F&0Tcm82Y{+&MVH_(AlbZ zeq3jPJEE7H?15^hK>)tDZ?0Ba1|2Z57DOB|Jrg3Ac`=}luCOQZhv8f6eileOmk<C6 zG|S&&BJ6<#0zmOdK`B&9i5?-!fwLHfUfn%i%5kh16QOeVuQ^aVJVt5B6dlBe4Rq4y zq_Ri&9-8SDbBCa_Wns92v*I*1<UL>?h=DNrSe^}?ntOiK3u>|l1Yl)EQxBx8*wi#* zHmE^-WWL?Vg&Otsqq=6RWDm}+!inlq{;+(`e>3=Dofbz?ccKk@^0yt=@-7SWzmu-u zbq|O`@JyW#!_Qo<*;Qu?bN*`r!%dy^3EFw%T}os3+dKKjh(f6ah-2HzB<b#!ZDUP; z+L35tLy_vKld3SUkIV0!Y|zekW#MdGua$aQEF)>5`;bV{;ma#t+Vx_-!>^_wS;+UE zO4`<Qzjp+i;EJ^#ZLmb&->M8!V!{5I4G_09Pyr+YV4#ZIUh&h;Oi1v*%2FhXW7O+^ zi<t_0BCfi@KxUFSpj(ttCkJ$Qw19d+3r>LWjnEJlb-$?+W)B>31L*AXGprQW6OYTh zH|U0isjp_TED;~B3p_H^cL4nz)kczo$Tb6$@1rE4eI05V@RzjwDeudkCKQ5JTlA06 zYiDm>O9+GH6HxY07gJ)%Wy$moNzvjZCkLatZTwscV%e7P4&XeJc1XWx93qHXt^>>& zY*l3ek7sMmdIMKaAJqefn9GvXw_B0v`A$A1T%q=$ny(KP!xq$s#Q=hfe2n2B1WDV# za4^d0wIZOU9n0-M7R^yBqcIKwr!Ho$ILLfZBz+-puntXgrkIbxfAum17sij-wKy=I z<AvfK@)T<wlnbrP)>e?cA|Jf~oT;O3-CO7q`KMsgj8Pr(O??iTZ@+%X%oLA7W9Uq% zA3{*_@jEXg9&}DUBGA?i+WmN5+5+cM)5welKQHR(2Xe@xB$~a0<rODu7E7%Hqvoj> z6c}RN1e_Y`kJ_tBn~OlL-NLXfHK?+D-_}qAR0B|sub&6}(wnF;D;U;8o{xS7>XtwQ zDgST*3^4vEGojyYgF3Vjj$}^(#15Xw->JUo2HAZfEf!|4#?FOvc2&B&0XM1~u$gcG zzh9R1amQY)F_8oW0KZT(x4=9ZK-~{%VRq3Ls#8rknswRv#&&nhP?veK?g9TKvv9B$ zL6#%%W>?myQzccSnsk<sibNAS@r(<Mp?t!Ox^GsXdLASOw#1TA24ivGSDn7PoT8 zq6Mm!zzQaK6yWTAeG-q8EesihSZF_d0bz$h0e2}}hJ<2GKQd|^7(4}dD7{Zc!<a#h z=N7~6hU_#V=P)NYySX|o`9uuiZz4c_;X9QUAsFIAP>dce@QmvPN}$>$;FtzY`fDW< z2l%IH9bGEOp{QD0V#YBYDIqaa-?3F)^sn>?Ss-Wu^0qCnUjE{e*aR7vsUIm10<<+j z=t<H>zD4~KFfGuHEVc&o;PRM>t$?WjAU0ww*8yXFRGzs8&GrS1gQjYyzWFbUaH`1? zCrJNW(;v6*haWeIw_WcR4L$p>9UHllhnHF9|26fDrJZ!R)_CO7m1MtycBFb8D1qLP zbI1EUpM4+mWMy`({!VBv5HLnpeq0+bOt(o{6CWWAd>oF#<q1fbf2}hmq6b~3#z@(L zz`hLvjR%Pk2m2R|wl-pEljC8`0!&}lD*8cvZ#I|VxS{?q0DUIh$A^Jw<Usc=X?uh; zEwsRwm-W;<`&oyWDFC5qq?0tQl0mcYV}wUc0~T&r%peRUbT5ZhGhlw7EUJJ96*k6D zWB;92tv)hqA%I<j3UD$sP!@c)U-nU-6PX&6gage0*aHCTdqvP2e)Sw&r`-K*6+sMA z#;ZY+T4quf7E6Vf8!~%*cZ(mTvznuOCZM|_#I2!#BqARs)gqWywgf5p4JjcDbIXYc zS$(hB@xJ)mplz2nV<wJB-@p%cojrz+Mtu_#@l!u63Q|+#1U4%U7Vn}yxLM~py8q1F z1Jn!cJ|hDi8w%4e*ElSFoN@Iv@5e)dS`KqV1hEs4&mwv4V!i(kq*k<ETW<92JXn75 z*>ioBe`5ctvzl5g32@hu0(Pu(0ET%XhnuQKjL@_-pOT`~TCpRHIzzn>nHE4RAli=V zVg(*FP)bNuZrkXby8}S|b4ZzkmJac~X_Jv8`x6s;`XTv)zk@;JmEk0Fp*Aa(F<R=N zZvAT<6flPiy=!xsS*A1AYs10}QTjY`opY1`l?G8T7N!WO(#H)^n7@#~=juhO#$f=E z9@J9Bz}Xa|osmPih<*F&dw7|sP?z6;NgZGr#mg*h=Awi#Pw8trtiY_JkPrI?_C26G zSfIpzZQ=-cX@xZ)ca7jjg5#ZtTxLWxKFER!A5OCv<a~GM@7HKUCi6xdQTg?O(n5Li z%Pd<&d)-e@Js(AVe(4;vLfddIcur-n%wu?pLyuo|z;Jr<c{ODFV-?mLFzE9%%#4~i zU=2(gnxHEJ^(N0Ii!9u1!7%Ng=omNYAB~etDMYo>85q?8h0!zBDTu=ifCB@ll}I5z zMg94y`b00`({M4U9y6IsYUy7Av-E~=T*uRA{DdD&^?(I!6NAcMFqfxqBsMWy*h^p$ z#BQhk+NqzAdStiJKsHXt0MMpD4d$I!k?IXNzX=)i^T>kQ{tshdq{h?luRc5zdhz7j zV?a%^$48t0VAW*cc~h=lQ|`pYX5D#wV;slLvaIgE`q?66cKf1@FRpNIO|LI(Y>dss zZjNaW@6N*kIM>~A=R@1{U&h($@^wl7#fZ&q>2+djW2?*2+dFuO?_G8{8f0+}#t0#- zmD&+aR8ieOZ@4VkyD~5^xlDRdY_CQ_36jBm8Pxh%sfK)ONxoPMQzyYKPr_tPFS0+T z&{A&dHRuz5R;a@fCS0BniuMCTivWA*ioVm3V8X{=5`b_KbZ=P0gR&|U1Tg#yD#-W* z@G`oim>0It%W`6~;Ff2I0_44d25C0)qc$-N?njfIFZw_b^oKyQ*GdBfBnzjosf@Xg zb?lpmFT=fvl2bR#$x1+mn<BP4LW07nWeAY}#(QlrhW=nlEkBK&7KRgD45oj7G%-CH z^}=JKbxQul=f^En7?IyN)$mY~N#U_I#8AKt59WGx!=ruNq@`fM79dg{GY73w>Hvw! z3FoUz5>U!t4x6l|I;BCdr^Q4FSXq!Z=|!g|#4KNflxU&%lQt<bMO4yc{lr@B(-vL? zgMLJ(NqvvM`%ES<4s*U-hnHsS7Dh<?^~Di7kV~nNrMC>&k^hVb1mS6`)?h(1$Ehwh z!$2&QGTrQ$|I0EnC@EKTYN4^_W1)wfl?LR3;ULR9kdn*0Qk(e$sgVof4pqj|+R0;2 zGIS1UEXr((2?5DA{OSJh*xR#5+dE%BIB+^tb8>Mxbo_)z&vVVDz(z-^_X?h~w$X8R z=_PC8bq$`)ICq|NA~w;{X=E&&?=qR_cl@Yo-F2OC+Wdb1QNpPB1Z~2WiYNk&q7E0) zL)j7bSFfGDHDn@7V263!(|1wY$VhwG@TQ5g&p17TG18z(GHk0)X2n{2o+T0+uSKLV zYo^CZ750{68ucMFU60Q-Q~n}i(3rD}3uvQ5jG>R5RP_8pyHz&Sw}9qiGKyRpqRd^j zH=DNrt2A5;cw%co{p3b$A#-~NH<P&NZ1wfYL*qHaue+*OvK2N&THjE<PT;}dmNFOi zuJt~ai{rB(oQV5q(-(T0d*iA9O8BxGZs}gmBHr1C8dvqHmGWlVlF?URt!hCDp^8SQ z_mu)>yFXj+RSl!IHH(!v{?5a4Pq9M(gKc39Fom6e=0W6Qs6I;xRph901$%!^T6Z7G zdOvebXa9b_4Ie}V(qvsfv;;o)inM!1k5f$fS)Kt{xNCpK=8cg})HBXjBr1*Pr==4X zdG<!*>CGr5ZKtdHC|9f=OqbfV(@);lyZ%ZtPt<1#H5|iWA~Z0j9p+rs9qS9k8tltS zG1S9jmm{KqK<ztyLI|?6=90qfq^N@MT~PJ+n9cMo>+`OY)iDoxZmf|b9khL5xN4Hx z4i>YK(C=n+KIg32Y_}&W*gYE7Wx*eEQO8fZ;l6o$XtPZeL={6;(y#V5<_KGv#jDt( zrx(1R;<E&9oe+JSt)x2uR+L$v5nfJ!pPyeV-<?yr(}{GmYRlDm8*pMfUP&TyqBQs( zhV8Dj?9{u6{qzB^JVxDDdk{-Hd73Lq(~nlq>+3%Mc%bl&u&HS2pzit;9u3WlWr&X0 z?k)0`X8u_XKOXycvKTp1R0Jz=9|Ue;Y3-~qb$*JcBf*PN0RdH?s9M|i*JASy7#Ui1 zusWD24n@al%1eD}ut&wCKXX1BHWOyli1rq>qY86f9AH-v?@+6b+R%q~GHmIad1%F= zq~p=^3i=!6Hg660U#7ovpo;9u6UM;PA!W~$mt*jmB`ni>FA{5NuNX`tx!7N=w=ncd zQe<L(6-HH(6BlIsi76>rJ<LSVjP6$vW9PnTHbMYywHy&D#BLn96r;z?ry3hYJeaDq znbvtr8aLadk0js59Tt=GCDr6XtJyo$ug?$H3iGU6Zp|HHd`|*#EPdEMX*dVJh9&Kl zwDgfIoy8fm1RIaasOw7V>!P1BelUzLVqJTKDpl9p_aQgZejKUbE9Zt*48(4TiP3u* z|8W4WUs|=+)rv#C7(4A1)p``6%JZH#n+Todo7rWI(U|YlekBN0tM;)kJr+LdftR0N zTxI7WxM{M;NDxoJOr1HX=x3@ItHEz1GY^!ND3BE$L3;@wpm4<e`*O1D6?YijYAi&O zPV!5ZS~YQ%NZJ^p40?9vAopot^RvT85Nt?=Y|sw=Tzsw$7eWEf<BDN(<vpuH^A?CC zXXLE%^V+7IOupowLkg(ua$F}SK6ZnSC3y(g0^fgG@Q!fk|5hsZ4509Gd(VMD87um{ z(3X!E+(bl}cm#K&L3M%%_{p4HhtJzKB1HbI$=;?MCRQ3k*uyDD5Z2eMjfIfYMMr9h z{8jDZ$dZMvdG&cO1icr@UpE?q<8i&=T#qBOIbCP*CL#gkRJ%ASM6Z@y+Zx+Xqk3dQ zy~eBiDJ~1V9Ce_fw2AKXqc!P*;?{}iUSI4YvPeFCsyIPb;og%HMvHt7{2R@~0tdef zDbw3w$K1ec9%^;Q&mIKnbds=ZsACB>I~yGBPXlHS+zK2fq>=WgBa;dNECu>%f<*4j z^zp7DR9rmCbL1{HJuP}P@NNdr#Apf1y2an>wOt=V=l0UKbh|R~=!b5GVC~J%h60|# zxj+U429>$@i85#UUTaN_Tpsm%BgYkCoUA4=*CpFN$?Yc2Lb%HeFIzpFSt%A%MlR_^ z`04RNf$i(`oI~0&K4grXCO|w`VDJNW$00?4o!huU#}!da|I#i#Rob_KI986|{U?M> z8nBFV>bv@}xF_Qod;@VdWBZI3rPm}5iuY^h$($7a!ShDeI(jnX^&UA^X{4)qnC|Ex zs}o#;$I9dD?P(u^^eOSP9yEE3ea22wN`JdRMTrVo3AekC6X8T#vyP$7XecT%1Sclh zh`20Z!`x(N9n)Gr&sZ4^={(E3*9@Igc#6l|Yj_RO*DobLoRgf*+i}ynoWg_AGNg)M zY+C=)9%&P3cS}<)cWv$m<3%=S8bAH~Ha;wHH26PsBdR)2VT^X!AVJuv<g88P_GtWI z`HmA|s)**3N!21kw`NRw9L7(N2r8dd8SI`^m1OVJPqdQwC!!q>9~W&rr#kAk(U9Cq z4_VbEL%2T7Yj^vc>U^r(AnUiIq@{>5GNJz)zOG53VIyJ+1)qL10sU1gd8@x#Ew)vG zJbr0{EMLVaPktB_Xb%ilo`B^D3e>oeRUY9qf^?^%pWv)I=0<{zOu$?k*Q3|h32)&+ z5!GbppXITz8_8ry+R*W2;Pm5uE$|p6jw;v9b@9B}4FNx%<S2DV0sCmRp_gT=t8_El zV(9)y<<;`Q;o8?7Jf$UFcOA*KbPSf)o-iNoABNtnLYYLF&1lk|*U2kG3M}N1jmgY$ z@?j$q*l~B(7@PWM&B+nYSCLbbOl+SF<fDg2TGXx6(Z~BAY@=tVk0FK`jun$dw$A9e z;XJkWaL$aC_hxb3(WM^?0j7;9GQf{DOA8#y4j%ZOhs;#vrCpT<h%r(c1sl3;V?&eu zmT?67LZ6bom3!jk8D{+lD2?fN^6<f4sdHCts{s{uuYw1Pep$C%W4vpD9+x^;G@%i; zEBo>0)>P*ic;g+E>RCijDu@jf#k_cz-iJ82{&)jDn+)84he5JMQM@HLX;Dj`mO4|? zdrl7qz!F_d_|ThAJsH{~Zpq7rn@)gXbVm+X=%_EFuTM)k*sNwwh2x4aUTZS_B=;$S zR1JKT`l95T=lQP&B$V6hVmuws;5*LeOh!iIsiH;k9F6g1ZlWD(@CgrBERn+>1sjir zX^vhgR%2%r8yO@ptqML<FjxaJLeCv4k&!f+V8X8#YQhh+Dv6QpC()k%J{a1_b0!UE zlD^~5lT#bGRlPs4OGsiR0+Ongv9fix_8n`kEP9o^zpM=~fU~VHI1(2&v2Q}xdB7M= z07L<CHrh~XEvlfv#yuQb;#-Za;?c97P!aur1x4HksMtO7$7vxKD0Ytx3G;kB3|$Rv zEwUftR!kFWmE+ef7*LVA-c@)KRS2sZ90{plJkS<r*?ANJ+mom;ETN0-0HP_y%9EwW z4s0VrNA0gE^ZMsoR^m?yFo*ZMIdr1~JOiG3$-UTlBnwoj2<vN06zVhz$=T~Uw)_+% zMtqJ7*6j2U-O-Df83?&WIZ@`6_}ld;l)gikjx>{G_9DpIT_6(&L{48lITom6h+N&W z@wl+-v$q~asyVE#9$R<fF}IGb7~E<~xY;dM^;Bnsxrqp@zvapF_Dw%$8x~+m?s*Ec zzWzFiCuX|M@3jLvi#N8nFqCKCxHY%45Eq)^vAEcBU0hHLH4!XQ2_wu6)GnsV*`b3o z0(<!_3zjvIL$1}<Nk<B^Sj1LfX5#pilVEuWQ!=HK$4ZKsk`7~$QIiFp3cp;gd6!t` z4O@`GxWn}g@Q#nJ5r+I~1~S+P91f5hu67-CsFWa6pYMNHOXab3mD{h7r=y}c#d;y* zs}j{Qv+fTNs%uqyqLUhyPTs1jANDU-o9{WgK-*4KqS)G-yH|};=Jfq2P~|ihizs4+ zMo?_EEl{GExFt(_`wkx(IYUQgggL2NQ@TaY+#i^rPcsAaT)$1hiP^z??Q9J0+Sz2g zZAk&x2Yh!y|H%+uUT5@Qn#nV0SZq`$qFzf+tcLw5B5nyIdbX)_gq{Jj_jMu$ru~%> zCRl?IHTbT`|8;Jxa%mruGJFr>Wrw1PuJlfNDO;py0Oo1qzA4$#<2ot^D*S{8v%K2J zBH#Euwjx5xZ^Y`|d6<Fs@-2h9jjqn9go#_z$fV3wfSz{Q_{Z_&Zv_;XHUsD5_uxdP zlSuMaC<b|))p)`vPHvSWD-6*YQmOn`nRN$Xfmk6Xf^;YyXnl4^wtc?X!Rjp1da^QD z*{@e)seD(Zv3pveWIaZDeYS@0UlB4H9p>Y2#xptVQvp3iW+WK5R-acs{1l(w<s&RJ z@8ceGj@3}njnNQLpw@EC72JE8=0y*$NhD-4-|)1dgjVoEO=K3Rm(DO*Qa!J?yAimX zCc_uy_q_GYJlG0EI`<Fh8G8kXU{8rWUVLTWh^~UUtpmG1>MUmjd>#+XmP6H6ux^a; z!-wMqpW4b5aAC{iP*knxfHq}6OGe%d)dn`LHZyuU*Y-g|Y$1!-wLYWR!cj`TZP-dp zTc3_ORnTekXW&54xdO$V&8=%5wZI_OnleWFwoYK`xj_OQICP3se&Cwm9{~x_89lg9 zq+`m?*7{UG#Cj+fr@wYrlPti93C$l-1+FYDz}H5#eeYr+xHf8gW;Ct=oR9CE9)zWd zmW^VEsR}ew<1I~ZHkH8rSw8(Lg}dKP@&x&ZfHe)h*s8#@=+SlfM)2`^h6!)hN`p_y zvEsKAwYX(ywyf-ri+)uMgYVTl?h(z3k=l$$r>FYqu>#D27$G+FFxxK!1IA$fkX){< z*{oT-v<RP&uFi&wacKbonXnOl(-?WWof$>B$DzOIhM_#d8OrWF_Werj%_mYpyI#s~ zGg!a<s^FXhu#UcII+VcdAKI=|BR!J+tzZS@hU&m$qemkKwh~GJuqpOdf629ZwLvT~ zQ_DweOfas^2wK(EC{Y&kt`dAb%STM-D@~*(t`v~5ERU#mCH$TPRpKanR{l;O`rP9B zGtMP^h$NFzCkVVyZf6SU$6tF3R7~>JW4`Xm>0lzn?)V-<+?55qk+E+mOt6$#6TuDK zy#0se-d})a0*YybO?_49s5xni1LlvxU{sQiz;LZr6@XJ@VpbQ&{C*o5e-_=#&4AbY zOIi|9<4E5@>2BI@B`Xj=D%f_spsOR0>)tlfYL)t1m$d5Ka+0!NnMxdK_BuF@ZDd(o zzTcrLaM47ab1Hs)|3bv-PO}K2`JFFGUIp8l()-;RavQaT+M}TeYc2x5aDa*H1`5$d zd2zG>=XS)G6UOk=0s&xR^>5>oAggJuz0jpqHJM&!usfY}bz-g2hAdGbFggN6d}|BD z(QLyI)6oGMNzvZ^24!4W7Bp$P9As^GJY=z+P}1E<x0H*=Ce=p=tmrn`S$yXJF%Q+x z6^!=Okv{0*njh1Rf6JR<Lc;N;mRGa;pNA^YzDlj77x(sQ*gL&#(Fs>-<Tq|uiRj2H zWAssHC@qd=A_XqaD-a;X=sZH88MVgkG1DW?e$6c@nj-7xCJH332qU9gJZtWYrU=sy z<=jB<W5AifL@LOc8ws4Az`GYVZ757n;=rK<Auw=PVfGpYB5tyLVA^1Hx5!%~!Hp>T zAJjvU!MdaNN2)ci4)ZvkJ!DSDlLBG!oJ#^juOM=39Bbtq;>8hfjU}?IBz{i{QzTzT zLSMY_D~s3gz{>;Qi7j|!MyH6|qbaEQ_WcercQz(Tj{z{#%{iYrTl*bP80N+5wlxZ= za^*vrwAv_8Z9ka~qwV4-Fnb30u(GBTk$2>f8VM@m_oNPqubl}$F};=IKA&MSHOL%Y zk17iQH&?<ID;g0t=SUOdd}<J+_D)gGL;fMF!lG`feT+3kaS9)se|nI;%0HDSg81oC zcO3^VQ`IY==u(}{IA{GAE;Aeq6PO~~OMKKXSH2o{F%UdGKRQxk(~8BQbzO}uD>di@ z&J{jOCO5bC54ATc?mgKh!}@0Kz&5YHd~ZynLTEv)j4W1nA?5c_7VEJ=tjC!boN2?< z`?s?_Je7=bYa{Ul)X9A!q-qnED3NwCeYeW(v+g~eC#A(i<0MA>*%kG6hQqL@7j8=2 z=Sm_K8}Q@G$VS{p<-e4-!4qZ{kH*EelcNSM5=39L=mz-<Z7w5!go_8i47=8_C0*LW zW0d%0-{t-^gCAewlSMQk!QL(C))OuMH3|W!;!SPk$jBY-#U!i>5}B$?96bj61z9}I zAQ*nnnV`fe7CFijIoTAdfC|*2I_YPr<e#W+?^gwpvcC^0Vx1K1lqj%Na5ozUgb9|r za52}wMNTP>T*1MVa|^1kEfZyhIJq4@E<Jv_0K<r1ov#}Vmzt+n_%z|8@nBMp%S-Od zkz?06D~0XKc)gu)Da@V&zDE%qcDAa1>XL+%zquNR61%!<Y%c*kH!X9f{>I`AcUSe{ zxtzzzA0kEa!@QBGPI}m$$VEF;u}OXc;LxX$+L)|9k>w8WzABzrjI_Qlt=1@q`AXnv zt_n<H&=GFl<jrTsDTB}}^3tNw1cT}g%!j4luAVHG&nuxBI9@&1M-UN5fZw9fA*WS~ zY`rUbf3F&H)d!EtbT5`#4e_v!UrNL?c)iOl^R2Vol_N75dyfHLApzqktTRnZ3aFx* zioY+x?0A1Yi!pWcqEMO??YS8z9V~({rMCg!Il}~sm6ef!ol}(KsvpKKwzB<*P@u{? zqyubE@CHm)VJ97v&IteJFb=rn`;F=S<(t1M>c5A<5tdxreMC_PdXP|TRp<~AkL6n? z^|7d|{j?QIWC%b_AG>B7mh|?eIwk)sQNX4jPwf`(I4M=uED!;{Bnaezm%{5DGp5A7 z@EDyXjVf?eT3vTvNYjC;wb>kHN|D(pqQdoMO2(~YioRA1%JtZU8v`fOldxoUk0khW z(e!Biw_+Iyz8;@C{iX1GGBu0b+lxP#Ht^;K;=c{ZAI3(vqVC=i`<{pJJ>Q-;Gm1Gz zpM@c<m=xd~OjUE&xi72{WW_mvX}#ik0YE)j>l#+ww8iK9Jybt#hU(AV#@Yv!K?DNO zIa9j~v)0?XJUH%&S*&w}r!n-_Vo9^{c(J;p7*^Ey2_)D6mLQ@*0A6Jz@V=`)0Ta;a zGq`U1Cgp%pCa$13vuO)#K!i8~I2;gtzqlaGWC}@v4mEZV$>CO6qDF@4K-WRI(vj1_ zKxm&uoyk`eYAuK2CCBW&D81~dhzonmy`cStg$>e_J%xB>p`!yZA@cqlO>?FwCeqI! zUJg{;)6K2{Mzi-P)`5ej1FzsnPZN^{Ko>9MP{7X5A!5+gNoUOwM$OH{#psX*ZfTpa zc-elxxiBD@L0_>(0J{<6Ol}b(D*(c@1md=!8n;z7m5Jk$2)M|$@A{UHaH}Q?J~i$4 z!Fs4FJ1aI3FJho7yxIzE{Id@PB3Z|^8)QYzo8n9>z``PvMq~9^q>X<lV)bN9A$kyx zB;in#sImQ4w1O#y`=#1pJ<j=cwx(fX=J9oE<G0d@R%`(Ob(4NXg7||t!SULzR471* z#MAl^iz#B)qQ<PdN)3Ff;93O3iAvT6qYc#r3C-&5WMSE&$$e1&34j^}%0HVZBBDE3 zQ-<$g$X+)N!P#H^R8YiteIZMfvyBYQVxnwE<f0b{UY$*i`sMVIHl8aB77$OIe)b)g z0<pXCC~G4(bIm89@gLe2dbx?#W2PFK;gQp*Gj@;ZBXt(zQxq9w+wcKoS~<Dz%TY-| z0txu9W2iXLpmb(k40Q~(Usz4kW2BTx#&b0NB;OG|jQBb=w`bE-gouj@*Gf5Uyl{^} zt~OTE1g=PL=#sI{k}cLC&>*mbp0ipW6n42sE8^tjG~nTEc-zSMtJ`W1mgXY>Z;N}} zW_28@QRCfR7l(aq?Dr@F*BQZZf|i@eihAlvJpn$rX@mH()zD=iUPT-5(!d9@A9t94 zSILNoM-Rj)^_$+iYB?2)v7^sRkFu$mo2+J6$@8<Ca{l0|UZN{!dvrRPHmtWlH=Ui6 zSR3CR?G0kx>yXLojJUy760K@*%6xZX*`g`op+I$U`)Gw4+q-eo4i_f24}QR(B?0Og z#ALu9;Kn6rH4j+j8Cc4eS7Msad1GWhsYEa4?mRi_HRuRF3r>ro&ZG9`&mi=AMY{P! zuO%G%T>%T$YL#MG)O(fsF;b*pLtDol?&%Ns!RyuU2_TYv3T|R3`GqyPMcPj6+C$@K zWY$mRSadtB_eGD#*z^GmM@!+yYNOSAvigV`Rc-;CZg2J0IAU{fJj6(OlLlT7p_n?i z0c{7+xcr1MW$8(46o%fX;MBh&75tU310VB+)^-?}TzpP3?@8g#{gOFk0J~pE#JOiP zTjNJqbDW50vkR{Td_&Op#`y|6c_e`Gb^-pF?wz0ZVih?6BuQB6dHuR7@F|dO-Pk&k zbjyMMPb1KykuktW#dzzg&*tfm`@%VxZ2E9D3FSiD=8^Z#lesip=gd+ZvQq{&q=(E^ z3sIW^O#P)w%bp-k(l8%Enwc(;N39%5@)(1Xso7dEaTI(?TZY%)if4K_0ZzIlDovVU zk-td_128Dx^En8|!4V6eoVyO99|zG8@Cy(Z1_11?CbMU+=o7ifLfk(i3@2-ifIU|p zq0hXe_M9aZ9A04eDz;QQURdiK9oS7yKm_xbqilDdE3ZCjX`Qg`7+FA|H&@WnUA$C` z1fNwW<sDbUy8yA?k2)STWWV=siN;+_0##c^n^w-Cr@cm0ncaQK1GMt9O!B%3#K<b^ z{b_X+kwO#uB_*YKf&dEv!utN&RX-N5y)A<(awS6h)T2HF2+q@W_!Qt(2*^dSj%T@i zu|bNs_;kqxbWfd_{++jL=0zN7K|65N*mbz7BU!VIMzIk9I66Ti-q~WNLPrw$qD`E! z*$RXq;<50k3$}OPSv6_OzX?rHFUvC^)A|@KXk0dTW|lNYSR;@_y37c|1X-ILU3M3N zNJJ220vK*!zZ-6x6B1lzp@)Z3Ab-o=amet4avQlM-#)UPA?5{j`V^|nO1h>xfOeK^ zAUY<UK2mG_>Oj+#fKWXn;ZyZ;{h1MFqJ%?_!yPjUP6soH2-D^e2WcdSuM^{SY+1RP zV0ebOl6#Lq3IQmRDaG<KGA2PySr?;;HCU#il!z~;hBnf7kQqrYPOsm%sEVx|pT zecqJxmh-DffvgY^-s_jz3jiweL@|XJw4(K$f+##uRy0ud$4cW{rgIA!`RR?h_#tr) zpwN*t?VML0`YCZgny4+P8<%1s{5#`9O^6-j;Gflac>Ahx>F_6Q(n1P7(${AS0Jb25 zKV=P4w_QVGFS<L~uDsjXcHZXNw%p~OJl%8|x(aj|T0W@VI2oeezPx27JZi62zPbtd zaJR*i3EOcm)$2Lm)#CCeWDoT*EGCKF(={H23)Z&F(2Z+A?`I%T1Q9#~p=qK}t8t$} ze#!7V<gYULJ<SImTmabx=#O<|(i?4E^+kI(2|`}y1rY5UwShbgzzggAD->uVobhCo zK^h4u^&;B42jt@5T2o4s1hy6;DyWgaVlt$Kx0hV^ek!~!!qH2vcGRwzboKjm#q(y? zT^shP_C4pLo}w<+EsAHh8O)5mPZ0)4%feH6UQ}#FREjZb!Yr`7QD~dW1oT8KNNjud zdBs}eaEhC9Qh;Bv#N(ADvRTifFNoYhOKMn)E#USZgp0qdctMJ&sp#ENkFMNA3_#w% zq0=MIOP>;X3qpfu_HY9rPVb7{jjAc92hSYxOHvGYB;Y3}9vS2>e&!jpcvl(+VCn!x zh5r`TLs;JGtn-WYhfYCKf|79-Bd7Fwl<x_Hvx8@3=x)E1qS|P%F$+4&Jzl~{y9A#< z{iM$ITX|R?aEAlLUB7esxh@8)+aATn+Kx*{CUI>%L@@~#Z~o5fJ$r3h5v-1Rvi8`x zyDSb&`du9-Fo=CpGIr1{C#2#B6!+#VdPR~HK7$7Ev;cnLx(Jh1Qr9gS=}QHPNy2ni zvo88AU;;Z!H`lSK-U9qu6WDiimBJ5YQ4vvNbrOYng*Xa1MT|ZdG3o4?QR?5cb=5B2 zMxqTtqzpiUPS$z?6aYy*KrIiHm#)z_fdNcAfWV+H)l!+(!cm<mh=ZF%Nne*m*Pa#r zF!EeGShGMNa?(fJ)@@+7nc=mG>pa19X(w7Xvvzr`w<riY5K6BPJ4A1&3~7C~>P>*< zvwzDEGCp3*+OHh&64dZmq_}IxdXNjrUHJmIgG_;Y5{m}{GvCV$Z=gXdX0B}TpFLvx z^az=bzzD$35~BuYbjEeaqroC%v^-Rdu8X`@<0O2QH!;$jaZlmy$bUX9Fa$t!5x_%% z<bi}q>g_~S2LteWE4J!`WGC=Os`a(LK`QF~7U%UO`N|UlqwY4!L8|#fZlGmr&*AZB z>2Fx@Ir<>x-9%8pJz9MkaDG%I$AJglyvbWyndfJ7)_HeZ*HSIV6<{*Z7}M<V1&9BL z?!oZgO<)zocTwz4FeEc{;pp|wb!Y>m>qxAT-^^R}=R_Nzv6_iHVqVv+kmrO<u35X` z-@}@opG8<nseZ0X?RfsOtQ&%@SYrnSMg_zgj>>GMORe3Zg1~r>YZ7IMvn)E>5aV=B z-o)||mG8>=o5}j^v*@jQ?)&teZvW>cFy_NxNJmgWz{@Y`5{b@yi66ODZK6p1VERw` zg?zyS?W5X4liPtG94?~{@|!nrVB8YXbZ*W!m+I5GXaOuVF<t&%%)R!D&l5X|yE-3P z#Pu*@P_7+a(Q0oum>zZOC&<-k(qj9CBqsJ%nJ-hkd#AoVQB3_Z>^{4bsWFr;f{e%D zDU~KDB`w{OEtQ7LVX1em^WgW&N;|DV=?zTtsU;PZy8Eqk_$R(v5|kY={G()gGz~iz zIS46yb-88#JKdhVcB44@q@Cf_Qe(PDrRP!SG}<W0t&%bPz{?>+-g8vHP93#(Y392$ zGW0rF?&zSEhW>Gn%Gz}1zOkB3`3zT`p3I-`b|JA_wLKL)-x;weSWXxaQI;N(a{2lv z#{}-yh~n?mw$l^x`!J2VXx$2WBzAFX`0;wJTKTd~*YRqn61Edp_;I=ZPPzBxPOOE( zeG;6X#gJ4e&|h_gJR>9Hz;B9b(22Z;J9I!dwZn^yP&4(46!Fg+bSzzLQ2w)+^;==y zB;S`fp=SQRyFp~f;0?W=iMA(__mArDyqHqe*Zx~?)7$LkI3mIOYy9rt@Fp<v0T&Sv z5cvP=BGH!XUwKrlh%Pae@2_$Hy3NB<cyS+smeUE(pU_pDFFY%7ut!$?auu^NoONZ4 z;6i2W@8W*%eRk^T*NZY$kl<;PVb1FQwM=_u;THP8R}a>$8RoAkW|{Q&GR<Ehc0~WR z`rV)k|1bBU@t3LI?CfkaIORL|1UB>6-s*Hl6Gi97e~Jq*_nV&()0r(aowq;m$7A#k z4GmpQdMg&q)98FtWbBZ!Bd2pT-6+1W{>0@qcH_?n_5IF?^0X89hF%%P3jW8(me2qK zArTQo&5l6hgXsI!vAhT)|Dw?u{K_An`DbY8bHM=o_JI_>W!6U|w6wI&Ax0X=t$Me8 zUqK2$lcnya`oK?a>t?9qcyjF7az{{*YP!Gdy>G2Z;0MvIZ>t>6q&JQ@r8aGYm;ECM z;0k13f1kO(A0&q_bz&Q1C8SsXEn&aa9#yl|>d`@1;h~f9b>zL2y^hN|p&6WT*9s5$ zKWr44{}+Zp`hPD|Q%o$o94z{j|ER{8$w;d{-nX#J&q1rTrdVF{3aHZg81n1vuuuX^ z@y}!B{y|_;^~zZ)4(r8>`xE%@<x#k0f@~T0-#^tf6wT$DT@Ge_&VP6$%AbX}ThqDr zR;#D`mph64uDM?iuh+}IYV42hkJZt;zb?ik7Or=(v|)*cVCc)O;y*tJ&{JHwu;_ou z(TufZG!z8(y7LY#MUIb-U_OPHQ~Cp$l)N)|m#f?EpDy&$POH3U{LEZmf5RZEa>YFL z%INa&qqE(&mv3wO`GZ93A}jP^%ltt|BI}HU%hF%Jjwp{YIbU3Ugh+`_mz^H`RGP|U z4#MQ3AxpXcb*bkCNiWLFz8Df0W@i{H9kC5AyQ@C4wdxr^##OMQ8I6oBi+PxP|C~y& z$rBJz+MJKnAy?%U7YH4lGd8wHU;SrKw|~AkL%v^Q2yE~&QqQRCy{i9Pp42NbOP4<v zK@zz?_Cn7u@83{23N;7Eo^kLd#Pj3*Z7hOqCceMfn~?P4kT&VR5azM>Rjpn#tf_&u zsOufhl}=riXc0xj3vm?O8xWeAkGPH1_b2fFmHzp!V<hJGmuPa5`rWR5XvGPeU-o@M z{QH)3Z*8T&Vd3J)n#}OxSmu5yuj9%y4`X~wx(V$NgV#U)ef?$L=RnN<+!nYY+&Ha! z)%EYzP^NA4Clvi>5m18Hvr3JD0S|WDi9{oL!a!B(`-_w)idy<Y|3kTEU^##r`IpT{ zCG2jn52Xy84obK@&9s>(nmoIsSy9ClEna5*BVYI1KjMp)TrrXk`-cWAak2B4>9<2U za;3D}9<{MsTlrCC+i#G_zC-r%oF4zLJ^a7ZVq^gUWRd?65Y!`R0O{4z+v=S%_3fHj zx#L-Nw9hp5(N84&_XndDyOsVrfnNVN2cC|lV5>kTtm5yi=2#0!mdeNG(QCNf8n~Yv zzqf)u-%BERg`m7?_-zXGtJu7oFOZW?C0wmtYl<BRM^tVSA*^lB<#&fE_e#K3|JtT+ z?f14Z(HMFsj^V8Sg`kXp0}1T=@0c_qtKrvV=oTgiXX}pyA6Er?0*(Ghu)!Npay+2X z|E&ZW<Hemn_@{n981{rC7mxQ*$3-S!p>qEA=i47U0tJsu$VTT(|3DM!pOT)QezAs# zNj^}h%5CKErQOlk`Dz@I@Mb}xZAm_#jAySjX>Am#0vgaREFqygQ)M0=9!_VyJ%Jr0 z0yM9d488sknKv@ty_<3Ghm2%PAro;hIWs;uJUm>&F*ajH;!gg)i)1->^6Ol-1m9ad z+b9*-{pa4=iG+=M<sb7L1e1*O>71|6&jq^wwt~g$R%4=$oW}UWV-pQ40pRLCU25*n zosn%pYw8|tiv8mB2-Pi}bN>B%-Ty=Rn;SZ>c(~ko^z?CtG4|Jn$Gvn2!jrvByEnI5 zGLp=9D7=bXBK`BeZ@A~s8<oZe?W6RJKK-W~PGCb6_fK_Y&5T)H{#&iURue9Ut5Wwz zB0H7co)RkOw&2Iy5!KcE6G~7UPa_mMzx7az(qq@5?#2BLps<p$P^f(Uiq)76d;XtT z^?<FsZ~siX1BLE*tXZez$hFsSLqSSg>w`pF>-Ix1U^NnAdek|cQL`a+zZGe^MYfv) zBjJHr*Fkq}g#f?``J#BQ*I-F}9~!!9{weJ#b!G7_&NuHM<_~2{eQs|!i;cP%Ec?^$ z1svM%JL-<vT1>Dk-^HP{_dI}FSP-x4KQ?gXkrfeE{{-3uvUVynzmI^<13A8<A!s%6 z{&_CaWTq;soPXuL2Pv#U=yW`oTUOe~LFrs-HCE8CinwMXA-)z0L@jWvmR}PoR7#NH z-<$E!|0maQc%m&U6R5TPf2g%*dv@<C(XJwL&*l<|&hWbj>TNWxxM&uy>P^>vHsc+{ z`Q6{oLu7oW?CPDmqrSSk+bhT0i?xHe{8DHRv5!C`Mt;JJ#`{VK7VUys6QCmgVLQ@% zZVFs}ybFV@xoy#`E*b7FN6<Ft9CM#$DY!`8FO#fYJ4yw5|0g2~(hVjBd#mGqIGeG! z|8DDg+Sl>5T$9}jDyCcCQj6boQIN*`d*$%|W?nG=ge{l&V&ES6$68jSgaQ{wbg?mZ ztGFCcI6e7LXX2by7*0CU?^pV4#%?X)`mFJ81>94r%iZlk?s&r1`Q-ac9V@4N7hmY8 z=zl5)nB2PeDolLd>n|1hx5J#!;EoA2m`Jfa#Lg?XpyuZjV#i<)R1OMftK8n3Lkfc^ zN8t?#*7m~CQ8N{sR=SZtFP6*GkeeY6W>A1B{`ZC>c^s>tY5JiREYxIm?2ncu#e8(C znb+Cx7=oU^1#1J3Q7oP<BuoO3x!mlS#@o!<9prw?-`X_|o>a#bn9fsW=}j8kWN=!F zD$jUR!_E39()j=ScO{C`=S_;gl2eB2jAsd17Yk>qwrjhM=2M7w9rPW9%azMjzuV`F zmy_=G#%p8i3H2Z53vN%okE__U7d{7j5rV?=k2U>w-&nbbS?*fq{yC<@cvH}$RIKra zGrwp81|P8mjtF9xYkFtKdut$q@wYpPf*;MkNiI%{2Zj4_?L~Qe#rz_Njuc!q^!bYy zFM#>*=Q^7yttK*W!#IfRBB#PzA^6Kt6>%b0N)7sl3!}>LPY?FL|3{J${@*7FyWQE* z$AZ?$Z^{^LX}|vHeD#zOm%V`e?;CQDjg6I^qHVk`ar783aE0f#4cekyY)4wWRo_4G zm@By$Uf}L%b-HRzUyHt4xs$3rC;jZwplwHdzeOc||F{Sn)$Jit<V#B=iJ3$BzQ!fE zmmhM2yOM7CnVe<*EWAD@i3cXVci_Ovx5L18!M%S=w7;dhzm8F~^3iNAuBe@-2Gudr zKlO%UX7lHH;{8@?5&iwRsLg)m|9V?k^+^9gblIK)zlxRdwfCRvr$oTKU)J(E%j?Y( zL|#7=y>lf(^}?ZXjiPzT=&7!Rt3!7?`R5l=|GrUXv+P9r$Z=Jt2zgbffXYUQ*bQ;g z1$Se2Zec^85Vu^a;$OjTa94lpRb^|%lNL{*#r!SxLCXmpmx%*m+f}Mg>eCX%3>Z_= z98_ev<X~vRD4vOifHnXImH10I^rf<s3G7PemllC*3WB@ejWQaR6a=lLxBX}z&*}QV zD7$0cfv_HkLj&oa>kg{>QUl#O8QTr}dKr=O74vT^Z$?$m8ya_-n}u!prKCTOW`6o# z*^siP)DDq5oo!D<F}>n|m0!bGYVF*AYQI8Fdz_M8e8=-hEa&kMu9I-S!qZVtSmPqI zjZtDy-S2{N>R;b+f95)qct)>TeMW9SsZ8P=<o>naxIp%3C`XJF{{*RRrf=^*6&LLG z=n0hep;~V=J@7@C?mnouJia{H`e8gxX*@3Xp9P_V2$lQONWWAL>DzDi-sHBz9pwIr zhT;E2pk<d$o5`O%mMZTRPzcQRFW+;^R0b_?Dny$}?v_VzaPA;iD`9ekDi-#<l53Vz zNB^@w)^{R;>4Sz=gh#_Abn=~OKV@OM){4P_v(sT1@>%9zwzQn8*(&_hW7@Lx^EXZ) z^HwFh${kQ<x!aqjyBqym6b9<N7p!JmiX0AbC>OKqp#;hej>cPBvusx3eKA7XMbR%4 zES|RILx#&68@9;k<!}^6MgKgV`+YimtL8QJE_({QnA>)7Bw<2*Vk6#s0QH#j0M9u9 zYDy-ee%GQ>t2<m^fo6Za{we5XJ^S_Gy!it?wJB1eqS?S77N@_iif0RO4o`Ujaou>A z{ja<5Z>ab@h3=N_c5fMS%-bUj?d!*F67mS*=99SmoGP}&#FaQ|XD%^&Op^i+S0bFc zXtp=+ZjaS^Flc3Vg%oGoLCO3;#kNy7J7M{eHQ{B`*Uf9)0{w)%xT#|KV$n)!T(fo6 z^TvAnVa>hV3q27TABQjFx0eNBT7NquN@cwjb_I2@NI2n#E~Pl%x3|5ntv<b@{rXkL zWGm=@QTN_aO?_M2sEB|Ff{1{00R^S^4iOtFO+`R@2k9mBKmbt@X#&!lN)ze51PDb4 z5PI(&LJu_r(r(b-Ipd7;zJJ|2?ik;<2Rj6kvDaRE%{kXx&wS=wUgtu5TH$&RgtHgU zJY||oJrG-NI{Q+=Xw(*8@>SY4=vl13lHAFTeov}QwC^E)Vdv1#;$mMRA9}h-T2C{n zCuv{X#~O_=@>srUKVGgmrd>+WRsw!kM(=D{LNvxwjdNQN&9V4r_#o}Nt>b5kfd>2b z7Xd0>c#LgN^7$p#_NNI^cjhnrL@WmyHLHRE@UN7dV*3@Wm*)><@Hj|Cf@gX0MWv{P zmavLsr5%B$(^XbyA^*>69O#4zgJRsVF<)2BCNl9{C$JlJ%|M1xHYpGnZGz68jxj0l zhnS73rTQ<21$+(zn;eLwU+?u+`0YR4rhmHvKj|25TzOheeK9zL&CQBaIRFV{S(1sr z9aicy<)h3ZlWYpN#ET~$>}Q?&!Lno<Dk$G?c#m+cM6veP3`!M+ZyAgke-lvH8I5+X zYpK27{AYY;pDTQk67NJpSRu}n8Aqc}0*p2h0d2Kn%cp)`Rhc_iA3-gTk|b&5{q)2y zWT9U~&3Uq9!Gzk4+vN4V?Hb9&f2vJjxL&BwE1!<&j4y0@+r(8(nTq|n=|lJ6R3?$- zmK=r=nSS%iUw*LF;2egTYOCaTe*pkrAUs(Hnz1CDjum;WG371XVIrC-e#a#zNTv2} zG#L`mK1_>`=Q7;ssdEu-ZZTh+`C#R}tDeBQS|RV1^Ke6v@zHptb57qKuCXJ(5@h`< zu`*0ja{A>ypZL7YhHwe5=~$%_R%HCeYJ`Nh8>rsH@e0F-jS;!%b|8~QiFtY<CkO?c z!CNHJYtF=f1KUdL|AR3-&k!nEo82_H_)+EM-HDmq-3l_obS^FX@Pl5s`a;n!1CyUW zqmX}KL@SAG!z(hE3uu`lQ+h&66yX&v{w?E#&Hi=x?wT4I-J>y;FTpZVtMC((rDVjs zb@%VUf!%q%g9#7TrGqHF>RitugWaJrBi|#TiE%}kCj`x0SpH0$pP%38!uT=%Zqm7V z{BC-aZc_0oo2+Y2CZ9%1<xoG-REDEZAiV!$l{ZcPP0|K<wEaP{UKq26aDR!QS@0vI zP090x2bqgz{YrU4z+}e^2d*kibInTnG=lgJgpf^*Zv>zC`N=PLL}q1Yzb~_dRr{#_ zvB#gE#qo++bzURldXI^~U)GaIi}iu;`>7;f5)+xAPo?dyHb_`dInVBDD>oL(Fwy`y z*;<31F-dGqwmplUH;U~xKD$J5?3YT9Xlw~CVSk=E9<?}Lqxn6Zq|Bwn7GYW7i-v(F z&*~D!aB)h@YZUQgZfnZFzkp3$2U`(x+*e&VmhudUhDegp!647gzVWhU-%jtS@to~a z)wEfA33+KA5VQLby^{+-pMd9GPf>XmipNUcG*>R_H28REWhn3Q%_*#U7r!;1U6+`G zo$xy>Bt#-o9`;#nx|JMEnPOrVg+`G*yk=PR{(iUtO(6}l_-(M^<b9i-q!wL6CkE)7 zM+SDDrkgUjtT)m$eo*>n5u=UsQu>Bw#~TOy96|+-CP-<?g^q^PaPk^>PL|!l_O@?Q za`J_n2_Is110s*cTNR`F;pBgOF)N9j=FQAxwMjT^7>Q>;-CGuz>`3bhz|gK$NI+NP z=|6uRk9R!I5sa$NdKg9a2)$#fT83y-5I@^WoiNAqP){!_MPUwvG?7!CdgHr&W!Bz% zZI%?*GG-6tMM}B097db@WgUF}{kV!oFX_(OCkTq&+x!wnGNRcSZ;pvxtS#wqRf&G0 z++?O8OihS>=8aT2YqgcLS)kum0t*K2)a82ef2=Q_Inb)Zf6-2Ub8y|os7XR!pl}%3 z)8XP7Jjz%C9`_uTewSPJLR-zq;ThJ;o;BA_aAf5A_>_gaaockM>!PTQE+g@Wo?BXE zOto`kBqnXfsHd=S?Hhmd?^?v45P_pI^_8fGNJzC`Mu_)ZXn;3I2feZLGRpGCYYj5n z!Gg4M4e#nXUvIDJ?@W++C$~wcaE|GPp4~h*WEI!$l<kF(lc{7&z)U#C<>qs82NS-n zd#I~~iAITZucibM{`rN<-F6R!vwMtn4&Xmi8KgT=>j%h929FG+LhnWetk2k~7ULDK zpwu}ODruFfr{k5#ogQW`iVPm2DCDw2DYGk(^PCnFwtQk{{kRFw{=jREM<#vSb=98b z&TNbgt~}lv2A$(4Z0g7*Vh)YM&|%uiTO;_N3H#Kb=MB4}k1MvioaE-mmZOc~_?A1d z7l`ipKL6w^B4|E@nSJsA>CGKhQBTxk2lyK$Kh%S@$BopZLJ~vFL&7z_hCxB*uFqkp zo5EO^7H$(mgO-MlCl~4|NE=2PdG1=CJ7Ut>L|Dc3r$D+|zV_2`nq(o{qNhvk_HW9~ zD5Y$a(-jbLj7)=3IwBS(zCkp`RL@-6<)1bDo#>|cAB_I^@O3Qo?&eTTnof7Sbh+d1 z0~R1;K#XtTvuEsOhk6uo{=fZETz7P21V2)AXMZ}McsOkq3F-QKWi7vWssGq_vOL~E z(uN-Bm>?vO2i}MsRo46C-W^)Sz8p#4z49y9<W@Lp)^Df+{!2wC=)RYjQhkwfZE3D& ztj}Kuqf+Nn+S2aPl!YhpbIB>soxukS9vWM>>Bc;EN|5r;G8h4bW$3r*p9V(`_@-f$ z(Z03SsArgC{#5kTlWB`#q(y%QV*lmxudNa3#<5spENVo0cC0fL;oM^4-G8gPyZ-8+ zboKJ-VP*AO&e9ale&@F<A2#Jpenv~y*lw~+0=vDpQG=H<40KiWQ3nxYG%7eAwevol zAJV2m<hnAo9mx$|I+Ub-H)2xt9*sAV%B{RZB$<=y>e194uspARgKy95JafB;St8M# z_jZt9Lktzy^5G~rVeHESUp;y9&9xAHv*EIv`o_R=MwG|yj8Z5um?AD--YKxzAq`?{ zc}yE&9;Nqz;qt)AL=4vHDJF7-6l|%$q0a=dd9QaS*DG09t*VFW>}|O~-7GDX=0)~q zL!f_7>~6s7A6<HC(J1Fho~WJyTh(53JC>n3#pnTR&xVtYuy|@=e*~Yf{}%DIWI;gB zt|F8O3<xYzpbu<+U3Csam&NN(Kc9Z?lvKV7p9gl>DrZ->qc`x{a>%Scqto4fK?AIU z_S_jC&l%#~*3zp^VHg|y8>+)TBX#0qc#T$7Z-q`%?<(I+TkJy)+oA0{Jp^AxEmNro zVXi!1);GO}Bhp>x1M_N5`lIEGX-O74HuMA=KR-MPuq=@Q_2T5mgD!?>1!Txohi|cX zOky5AKReA#WNmPAgdHO6oZMW!$hq1IxGGE`M#_`E3Vqu%!F)Bly%YFpQ7@R2o;|M3 zL{w^4@@7Vb`?o*Klj{!8JcV}J7;8KWxyk*FNrs=ZgZYaPh&xq1cZ;n3^o5{;c4oTP zU+4LG8V=j8KMB}ZIAjuuL~5Roxq%(e)xsy}Qw+0*tm~yvm)WRFGv3FI6mBba6oas% z=SL<`AfVWue~>j54$-5vP1S7on6)wO19{vI^^|>Qn;=&kBU0-g$}YEs+LCo9G&0xX zq^T88P1OqyQ4FbgY6SIkj7j>G_K2GRN@)w=uh-aG<|EQ!A0_7L)D{g}o3^NcB0{H( zWp^W#HewlW3)N6fBLlC%XuA(X&_RZ<Xo6CBqhC#4=`szQ8v^lKR=C(f;-t4g)?-{~ zW2os9O(Xe!A_$PxvyaJelL4J5CTuw?#+W}mF~1KDX7lbx2p*0@j-h*-@u5Rd5a_e~ zkwr9J^q$V@K~S;5lA+pCjhd5#@|Bs~t=#d;yS}cMLj0=p0#0USF&|9d>~-z1HEPRD z)gZf?5*yntP8)AYt=C`09<-8C?+(XA&0@r`pDF6xUA_B!N?Ht|bS5FJU`6S*HRF39 z?acL6h7RjX+k%<)Gnq<qF`+Vt1HUg9Pj{*!jx91lV6HX!ugadX>`}Gxe8Ox!y6m6V z8<r^*&vv+*d_68fjvcjLjvLDnYqvd0K@BcREuMIGR?P(Na&1E}QH~XDqQ&4quIjC& zDXP=Gj_Y3AgE31{>5~>1T-`Aoz3k>Td%0q+DWUDmGb;dN;fDl^p9Gds!#u~&e2p=< zxU?#yuE)LIr!e7wn?7sdU{QT1&mtnH@M7ASFh$TloL_EzxGTc2GHDu0h#^&G>nB-O zHqH;IaOJvSTM5re&#^!En7F&F_YC!gT(nZ*v}*QACe9KCV`eJ9tzNPV7Dl}=FzFxK zByY+z>`J;<p}#kM-ALhiv*W(QeY%+UuI#L^4{t^vtO*wKu8Ft^X2R0it7PFdzsuN- z*z6N~%)yU;n{wpXw>UEDN-1eSvRWQqGJU;oI*?OMHUTyZWQ4l1kK-^xO=ve|sj~PQ z{fx(NB~AjF+;>9_-A`8Zdr}TAVf+uTWIjplBbk}tjKG+)ItSV+nriyS#U;%2REY@g zHFf3$HJ12&xCa%nnj7J}c{csD&)1A)PzRM&Ehk+8E8d>krQdB_7dE+hC<RSCCCOtj zJbi0|S$>*<0h2(Xfmb|fjk=bHEo+Oz;~IGogcBfGzceV*R4ME%v~OumYbz1pJt@m; zW8AXE3GT@*s~K3F9IiXVJ!h*)=yy>}5D1(~RE4I%-<i&@`Y*qHf(>Ak+Q;ary*c+X z?zz+o%s0QpD<cKvlE(v6V3mP8t-s;VWzS5xgb90kYwAtO!Y(FV06ssNgu)G$2;9*H zTcdp*jPkJ(5RCb%P=kK22aP<#3`x~Kt42GtdzMwpehR5J>G>U2(YTP~{Svdqb+)nP zFSA0~lq?fBuC^wAfDWm1T71@UwyX$7_up!&N9jJ%gKW8K-1k`Gd!2S5XbDJdMR>b( zO()K^B}NJl-lKJI-!iWCU2<gX$!zy_nQd(`)*vJ$a%wrAwWay>-8`GY%T+M-tQ1N7 zQ1oAFZ+N*`czQUc-@PRhY31C-id76$KC}V%#n~dCRx4*2Iy!l}gJ~#iY?m%rFN)^% zru7CU>X_BIM5oU?=h&<vfG@nr`Bto9-sgxOH|1LWo}F(5rr<E?dJpeV)|ZZq_7Ts! z+1vslIn}*sDSo+qCB$;}?r+~-sv+4dXx8T#x<>a*)?19A{8QkemSQj$MS3$O24&rB zYPy<k_<RCcN`IGmAT+=^^?}m;<-3}KQz6S*fFRN+r7-hpm;NxV$hAf2HcSPE;{-X@ zNhC%MR_b$?yV;AC+E1g%9S4?sY<;$nq;HO<deg+M4C_%-k=nb2w4tO(Ck0tNyQr5V zC1>PWtW#g@doFgtG&30*=$^<?l@S{hFuva0l9xCzSy|Rwyj`Wo1U_{pzgm5@5rs%n zg2Y+NCGC*A<C7s082Gb-UE6p|bqye!ZM?NTrQ>2i-SG~=-5+(E1G4heYiBajiKZ!b z+;$8zU0Z7h0`^%yT)*k@3<;9FGmY!;28>xw3#X&xW4R31=sdVU5V|x4#qJdmFi&|a zP)oT^gloE^Yc_5;st*w|4#+7+(P#KhE>1Y~S>JD>Tr^?xoeZl41>T6;)B~p3Q`!lI z%?pqAdg}RSy15Ob77N2qesqeztwAhqr*nKKblH|^7Y7sTf6=g(MsVf|@m6;@h_;F# z8`_beOxOp=T5zi7d|W?b&tiCb{E5%iO`P+N)2c(ei!;sXsc^hC{L|!I`uF0k5}?sV zg^bqrHpq4EICh%p%wmQ{xq}kWu=0YbsU1LK=cIG0gc5eA6mBZ(nWxS+&E+uAbX0;4 zwhPai&<!%%VFRPVygA2T=B!n#Hx?{PJQV4`z8I-oB$!K&<{t0D#|>bsPQ>~iT}ed2 zQC~@WzXKE8{f#`3AJALG&Dd!R2P<`b4ip+mF*HnWK4zbC(^L`WYHJqNh;a48+GI16 zBbZk9PiV+|+C$Faw%f@THedSm?IHj_g49XZM1I-g)2s!tmSQ=FiKTDx7Tt)1)^h$& zBPvdJBy~Yrx}HSHQo1JgF?-+Qjuv2TSY-EmKQIsIa<&tJIihbmLtmc><+OZ|1uasF z9^mRf+<?(1Vdrt^BdmkI>)=~uj1@OMa=q`6w((&dcL8@f9Z@7%GEcu8*sKf_-fx|r zOlKYr7tWt9H7TKw$F!N{s);2#)|5SsnZ|`JpXmoJMeT@U5iIQTuN;fNlv&!u#MNQb zF1B2VdCF6~bv>OxSCc6nVO%qv;#55wrJ@&=^}RU30Q%MD5IiD1oiG+~muU`j(Xt62 zuMdb?YUml4Lo^WfAf^^Wop-+(Pt0drv$GS9>9|?EReA&ul|z1+oiN`jn)HIC%VI{w z?H%kJ9p4h_$e1<8zo<Zdc#R|q=j7UxQ1K%UTazJTX3ZDKsc$wnFB9PYkYM}xYITFZ z26FDDB*D?Dk_S*^XZ)q|$mq%eb{jB$TZruzOV~o;K1=02!&jOnFq&+s9oY8$Jc|;} zJcIEC-pQq6hH+1~9qX_04>iG>hX|8H1gF_r70>)$BE|4!+YV#X?{_2VY<I>lnb}y2 z^k0{H_rCCM%%|`w++#&|4Hw>M#dr9|YV*BM3d}VF@NHA#ly4oL7&Bcbk*pDrl)gSR znCtPZPVZH1PQSx}EVdeUH$U)m#mQXk9OSF(BoJ^H;&)YuPTlMgn5N`-y>pVRZaXRC z3BoK$xaEREUY?t?ig1Y+vh&&L<dt9Ni^uHe8cF~Se56QIxF}{gbFskmC&5knYM|gP z@j$WHqwkpCML0f%Ulh1BNd8l(y;R3Q`%!F9r|k(Td5mRH4CIcX=Wg%ZL%%rkH^w!& zHH}H_o_MH!hyt+r3o7Y;ZU5MjBb4=_SI<T2gPN(&*qrb;xsO0}lf>N(f=3xrlOLCm z_Ahi637~z?xRG!@<XyK&|0~n&Zz{j_81B|jgfo`@^o?p6O^+rR)ufyh0}^GZM3#@c z0DEnf$YdWF{{1Y&+D*qPEv#5hX^|h+zRUhQiu9&icT;vRHf;Wf#xf`23^V>{g=$w3 z;r4?M(1sWWTTPv4`(O!I^sc<El{!p<6mIx^77IlAw~~=rSykl)Xu4>E*3@{lGPbKq znwAln9BbclgF+2j|N3*`3LkZ%?%{0%lOfd(1K*5aDl<?qy_!F2nBZO$algPMF4O1W zIttV=oYVCds(lp5*}I<kdD3&dILX=n-a_rT$JO!idL#ORZRmz=`Q+m7X&>;6qzxFu z&DW8!GBXVut{vLHS?Mqz)qQ%HZ+8|EC1keyApFM<BjRo&oRR_L6!NsI<*M^GLn2U7 zeDw}`vm1Uo@2KDms>)4x`Z%FI|5Q$Ks!plI6WLiXt8n0oK&8cIK74s!pZ0uK%fC^r zPHsCQx|`^mX85|RW!Htxs(0~Q;VYW%lGQJo!l5UUau!q}4?!$PPPPwwg5TU|8`yE> zj&&Tn(zVZ<Ye!d#J>h6;mYiKfayS1t&HS1h#$5V#ZbVYdxFjW;80gMzZ{GaKV0{23 z^krq`iG%Ev20O&TV2qdvuI>xF*Ikp-Z;=;K3RZex|0R<S;m-@wJxje58MbHjGw%^k zeintrLLYO=zrXr6sq3&mU}@Ah5kO|!mpbDK3-_0{<kE?JX^#l#f@Y$VCaQ6h;@6;_ zY<W>r^^Wz&8|t}~Wn{>`9*kNFDbt1Dy!*drIm<+sUY)=zW)3Z`VmO;v?G_u+@R!F} z<VV${+FH6#FKgB*I-+nfo4>)F!l@NfCLxT5Y(An&yo#+MaS7&-DlGQsVMARfA?`I% zx8a@^6J>X=##5mevsC2>*$T-@NBn)WcWy%Mwkj7>N^PT7kHaeRqaKJtzM$&N1tpXh zYzBd7^P|%x^Ig1;7+p<NvdCN)fsy9B6|%6_X<0VM|9JN%SkS3itaZint?HBJ)~Tn2 z&*zvg-Lr(Aw?h4<uUb7}oXtFlcw&lF-rjC!oX<%vT>}Wd(GW14Z=~Qsg%4O$R>ahh z`tJN%q~5d%b_k&($o!#!RO*JCKKru<WnQTPCZU^?x96b>>=0Dm3M!epcGa$UTIuSz z+PM8(^`R-gD<C8fIQebvh}nmi6X_}o`5>sCbuW%r83YsAS5po(a=Y`PpQB~>A<fzz z{jSBvm_pp>QA7M6cUJsLR}$vRI9nsDq1VQvlE%Kp$RllZe+b`TyGZ&*`2+pl)eYm? z?~S$V9pDIs09tZdKw4G_KEWB{)lu+Z$0Zez7F*nZ7^r~CMyf<FrQt=K<!`ahcz8ka zWX`i|K;c<iwR(@8HqB6zzC(bXR3e?On*Tp$TBUIBuzP&w*VgzBOXXPxj7R3gdixXm zM%}2g(J73BttsF#{F2`ILhj_Jy+yKsxART(M0_eS&L#E!*fXue7HHIWpmv=pl7L4Q zp2>|Z9akkdSV#p(;qbDf!@jG(9&XGRu+G-7^%PmdTnVe7>k$eZKsXRR9soL6W&jNo zsF~6P%q$)e=2{lX1lW+zaWe5M(dB!?7+KH$CJ$sanL-Adr18mIH)VQce7{Cf-Jf{< z+P$$Cr1w2NrNWs+7NbHr7xfn^`jwXhwE(>WBG3l`0q;2j(^Pb<ud+{7EoUOwAAKLa zoYJg9oc^<WBR+q=LI9~F)oR1&`7CadLw4&Ou+^#57zE^|--=N&W|!pS`=xPb1NC96 zjtFKVV#WuKcU;*{J`pRlVjKs9I74Liw_Jf@z6Vz1G;Fm)<wR`SX$a|Ebp13!fWky& zEG~2Jgnc|AHr?+Wr%gM@X_@~A2OIT#x=Kfokw-}>-EFz!oJ2iQW@)I%OBCK1jrQzk zaW}=SE)#L?A4DLW$g&pmSRX+5Ug(6w!%atQ2!6X)`xL*we;m$87xw69Nl9LDan#wF z9}6oBWzL6WB?pdiQ{v`jlrr;vd?8-bA1d(sw^i92IBhxWwEPp#P1(@9KZNS3Hxjyr zlPtLs<})R)+l{t2HyV7#fr4|kHx(#!D~eJKu1xcuKq`}K5`MeXOiJdZAv*&4(&SlX zsv}%D2z*(EE!4A92A+meQdPab{yj8Q_a#}{quPJEyxn_OaC|%>Ggg7ffM|;aQbNbE zEiMd!d+-{-KqE+|dfHE*dVPkgN#R^+?Q(i~O6^4!hZUmC5kjCr$b5_<he8a@S^i5J z`XJQa{+?6eD`{<~w(9e{Ijy`4oP#8Uc&|S!QHF>v6>$p(VBNj0w!7rz=2q89onLWM zan<%xDq&7ShzeF+#tut;&=$<ul=(4+Ze>7)q70asPH7dYFY2wVO1<4NU|b#X5A>4X z{;FAFyY%5XYWgOjoybvMpM`j1`H8oPgc88<;$Qy<a>`G39&awkOMBc~u+0QT(Gw1s z*7`HG1Q{*6Vqe*B*@r#ht`!~`9U=Cc_Lsxv=}Mf|`b-_q_ZLC2JkL9Odj4s9%*-<< z$dI~FS5FV-BEVh#4BppgvZ{t73fTru^O3Yd0SM~wH>lltHa!qLss+GBIMvK15M|+& zw)R6$9pYF>{k9PMF?iR`&RqTmLu^b;3zm#3tiytO(gjcsEMJCPr<+_*#%xQVW`O<D z07jy@)Fsmmy~@f6E&9~SyF<(!c=O*)me)6L5=mx3%d+PY@IL{n&b7A>DRh|x-!#(_ z3Dbw;ruvnxTttoJy&iTgyxr9piBTFBr~L3>WpzdT?aAy-S=U=T(=~ibN=kpnTR&u! zOxG~&4}$ziI#5ndZjQ+{7cY38<~TV)jLVl1NGM#-h(#Fo=kXoBOh(Q6wwb-jw(0G} zv+I;8t-qbgwC9|&)ShV4N<zVQKa__3shV0i@=vjsv5+Q}^I-ZZJ-n;S9FINiZP9_3 zUmv4x`}7aYs3Lmvw<vY%q9_>|*%5L)de(bBJpeTsN(7k_l~5BQB&6h}z0%VIMGksI zrs3t#w)(JhXzsSkkzPE}`RmMlQ)1G1PFX~4Px=#ZC;lh1-jsF#Jeo%>K``uZBj<Q# zC$HKcnnVnsZmtnju^gpP-mi?gU3t7YDgf3ySI0j`s^DLy46%uSj<E-S=@sX){O5?N zdhwS>{I733vJ(1B^Z3^{h$MEZ|6?yBO%g7zNwQpXY)||h_K&g=%SHU_=3_MO@Bi@c zlf_Z=$p&!PX1wf6Mo7A&+Qs_nW)^3ltZBexc%5F$WT2<)VIfPOVpfENCLx4)epq^Z zx<Bi5O)XK_daRI$F-e6J<K*on=WN%>pa10NpFiaCuFjUyDRY|@y1UQ$CWO+Dg7vL- zlb@Y^Qy2Gw-*PGt{VsGMI(#U0F+J!At@+BCNM};S?zJgmwksky0U4|=4Kb-MP066$ zx=^A49Ud6CMmQJOn8>KVgpI!gdAUvScMtLUJdX_KCEY*f4m&f|76!8DA>*Fy(g-t8 zQ&660@zg$M32qSmShZMA+=hn5hbZT#i=mvd+of%_=%sLGF^fw?)s~C~;ALgz{UvCX zj;?7b?q4FR#lBWz?@WJqZYxBl^|YfKe*60-KdX=DijO87I%~K$*BNgD3`!*jJl@#8 z!lC3j@*MtH+WQdEe=epy8A_>gz_l0J+Vs#ao8^9w;;w&KHh%@RwWsse#GOZHn&wkG zmhKj%!AeZ3`mgOuzx7!ARJF?~wcc>zyaOr`)eXI1qpRyLbMJ6SO(Z5Y6&}Wy@pQb{ zcv(;T<;xa_lEw~gEv5EhEkI*ba)C4)>=PbJ04wvc2i&D#H)?guGwA`~B{Jk<&`#r8 z+XW!mvmhKZc#f*aZE2i0wl{)LbGaE8>b8^xxE5~O$P5bD)SfxRx9^A79pl1%iGS^f zkEb5O0=8%IR&&mmEVOHFAVsxD;lvcA)T)!+)J|y(>YFNI39Zxn+*U_)F+ZOzV7Y0( zz~D8`h|-rrsq2-@uBUTOwW3~jQ3m*!odb)e{c~a#6mm6E8KGT%pY~dk)0sVB)Z1ts z))(%5$Nj4RDX8yt%;>hS->!&j8<di+5E!P+uF49`G&*yMR|`q)I;s<+DSpORG{DvH zFv-kKv?=xLc?3PdnmEy4huSk}=c+GeMJrphzNg$TSdtaw@TOog#$U_g?ak&MiFc~r zdDf(qC^C-@;@p}+^W9F|TFCZEObv;D_bcQ{vnjyD4rd=yfa;%-zxCeyCfxAbNv81A zdS$PB8)_ScS8OzlD~AqRvKBTr=9VKGL@^QT{h$*Kqo$Tk6JXn|Z3=BYs~a?HOVgS* znC5Qy_+!HiNbLHf;)(jJ!9ZKOED_Eg8X~5K0%gDpfGH0wgmX&Ldz@_>)qKmr^H2;8 zhtGwzKI1tP|3L=<VbB7J%e0NK8UT_Q=Z$;@Ig%7VP^dWOP<4aXx{rDNM3s0~fMPCA zNjbBODxr=I22qc=9cmxK2<f83<nFKth6lNQMjY%ZVazk11^8e=7Ys99sS<bQ&9knw z-a!}<{H1fn82)V^q%Pkuu=4O)pK}uf^gEa>wu<NWr_DEj*N{~DuMPT`v=PGvt|ZAj zmPvA~YXZ%GSp#3t?LsM{<`+%Dr>iV#^z~Av2lKFwiV5ir*&})UAyl;%(+BcB3KThj zLbR+P9;BuBFl&#Up=hfpMJrhfcJM{weQ@&j9A{AshRwWmzks0yBw|ec-xoY#YiS8( z>m{;B+Fc^A;f`#c7YAfMXR?sUTsbnw0GrKg4t%p?PfC<N;Z6Xb1TuX>0`bR}XaGmt zCMim(C(h6>!%=|PwvU{hdu`FH5ds_wxcMzy^ON^=mYhqUhocrt7u)2}dzP{r+XAP^ zaUJ!5_1nUJZo<+u;id%Ewv+kHkmBbSdp10KN53((ek1v>WnPQ>j$NwubET^G1B)8Y zzAYV%B#*Pz_*VZtwm>z#dzc;>4)S7YBQypP{l$_|{BL&1osABX@eWP<YWGb^ve(NJ zy0HFG{ZV*e#@@(l6#HOcyM}H+@77knKk(8A0ln)Tox8A@JldSls)Ga1!2|^FtL<ru zy0b%4pN-V~hJYFM;zo=FcaWjn$C#5xb?dnyozV)&_xV4Ak|n-3fql2edWm9_DmOe` z{cJTAyOX4#?~V>kuFp=fh6Z*~jk7<hskCYctDW!?Kbzg_MyThFN7(91?o^<43h2He z7~>nTOVPbL<Y@qt#dZL3H-?Ihi((tnK9^LHUscP6laJ%kK-}S^XrRuyKl<l*TEMK& z`^4l6&Y}Jg7Y#kcAOl5hciBvQ2^39eFJa(XpZQqfWRG!a5<8Pu+cPS&)f{DmvbTfW zLqkLBM7JFKi;)<677aM_0OO9wi8jRopkej=1J#%`o0x@&yrgX{*}WM*!}?qmkB$l> zZ(LjirY>s97-iX?AqrZ8&-jgos27@W-Mxm19CX1y$EbjY__99hXJW%)0KxY427%Ds zxe!Ux2&@yc-)}lLw~1m8dpxgHM~w)e_hiv&(rF>##v7fUOxt0nlZSHnuk>;r5Yh15 zrnUeX04(BWtyJdW3aN`&)sLjcD23!@TFxG?QyoDgmhV63MNyODtfV0kb0BSZ;-#Aq zjM+{d^LjNlG^3+V4rFcFAKKoxnYY?;U5u%btHaIBoTzHwknB!OJh7fGfZAKztv;EP z&;O#rG}A)X=4~C?gxQNONfbrpwlNP>DAi5Mc}$?pihW(0Os9r(j=~mKI9%_XWVl^` z>@-|es+mcI&l`U7zAZdDuh>JW;B~vin6Fyth<sNb$a-dizhk1D10U+&T@)dO3=1oy zwhGZM9K5W+d4}nY@I(*kGl-V6b&Si1Z~`cwC|~kqxawHp60K8i5Ej_mW<K<;;3I=B zKY|sPrdB-@1w=x^+G?D%yfpPt4J%G-J>YP7=+Sp$T^c16XV)bH&AWIt5)sZ&D%!aa z;~M1Sl3?5YRu}wRY5#T{p@ua;ekCT|_-SSf)4@{D<!g&LHGC@+j0qvIjfQe4o$Un@ z(nE(ok56XEq?XT34@$fp^o10;t@V8GE3zG8=SdFeE@CrG`)%4I2Q=%t{${@;Hb<>- zEW3%L8*bhavGy3XjZD&&_ySF<pq(v$`2G+w7>M3Tt5j7G`G(Lv+=2F6WSV@ivRxgv zECHhDwT`c){|0E*rn_{TA|i_X2C`1@Gq{KTgHyQ<*eknoPM1lmr(@eVap{vTM%|_0 z*}FYm+%<<$Y(PZb*Hf1w)X_Ba#Od2&=;<YLWHr5^Q`yzfnKNbvyr1{RC1+(vhtKX* z>%@A#GeCHm$IOl<xU3OZwDsoBtGfnQ0ge3wO5~+)4<M4##X=usn!RA`8hcetXz43v z61beidjRYu@*F9r3X6LSRgHStn(lq0=FV#4?+v?Zq0SG-vog$!NngNLph$HX7p-WP zr^^6qyv{tyzY-~lNg-Bm$Tb@u-e$@29~2QxK2%a$!?%c0IKy@oysS5th}Hem9#6i@ zw0ryZ_RVrPmRGpZBBnP&!p^?RumnMa%1`Cx<>>Za76E~u-YrkJ?(f@c!z{3S__tt( z_cJ)*#a&imL<+=tA<3CnbHis2SMKNQtIm_i71)@p)^{pki=3w%juhRhksCO?pb4lI zF>mH)>)c1A!Rl<Ot-~3XhEGF85cuhm)n8E4-z3I0HopUCfy*Cw(9o=?#Y(uUs3__7 zhvB5^-(--Or_>QI7|Gb{%X)W1-TE}5U3*I($Rj<uRd>FIhN+-vR9#WN2saeh^p`S! zz0`CE+J<PJv&@V4=a;}(m)|gfs-||_1=$~jdqyBL{|@`|$EP+&9v`s?s;10+W*O?z zr}Jkw@W-cu2|B_n!wysX2l<KnXIJjE$Mgeou@QRcr7h0WwU(xc`gI!R=nGdffy<OK z+Td<XkG_1OR<X1%q6(0LF!ZniwA_PX6AR%m@fvq#0N&P{Hy!X!H87Iaxym>i-;R|8 zGcx;{*Sbx12ak5SE{6zQGNEtBN6IK)2JY}ty^-IMmWR6Yh7b<q1CWH2p*wNt)ctFT zfHNS~q1KaAn;u6RJd#g6Lpm}MMfj}d?87QjCw;#r7IYJ{_3GDi=xWmrU=@3qVHQQd z)C|g8E;KQ8?QoDtmU7?~$($lH*q5g`bJRd^LRT>LPr#=KtgVJ9uA?@bk;JL1Gr%c) zg<RXYmP8qQ&BWLGv>e^MiO6hQA9OwJ?F}!?fQbDxQ}oUNvG#*yKg@UQQh%-c+UQGi zr$)zhh!y(s<-S4*yF@fJ(^bF}LVAih)GO1*$6#$c1Z{9<bcs$iXQ{3%0Nj@ke9)d1 zPMd?iQ$w>A>V+i))ZFCpor*cR_%n>=Vh1H00rP?@+gOZMHJq%<V6p90?>U>^tAeXr zgb=+%YeAnpzPI`#2aD>vyw-H)3>=V(htdnk?@YAGl?RH+EndKZZXC4H0``uEwO}sQ zvCRoEcSn4xA|Rj6V*apIKrBkxTy^X#V15bo_{yCvquGRFN}fcV^C=UI;KzVa+-GIT zob623@-SP0_S+UzC*bFTV$V!&{aJCGzl2#P`kIPDGfkg_YR<YkQb3xjeFH2t7$U1y zFFi1C+N%8e^j>XMK5b!#h1kX5W6W6Pck@%Gqx~WG!>2OMPDZUuqhoNV?7~78rtlxm z#+OMi)ejV9kriv`>$e{?|I$&f5jJnWt;9o0|LL)%Lwe%1i$~ivLX#S9vmL(v*gfks z_mviE0Qwq@(weSvzGsWmx2Bes&dCtV=;@f&loH?l4A#1X)?wn7PzvD?Ws|f6$DBwN zFWKm6wTz{&DuH+S(qPS;Fp0h57HU6l(<dU6iD|AJd`Q<THAqjM$;F0RTbYB!4~_Tu z1+z;_zbrL6+s5C9NK+0VYN=!^E4+7Do{&H|fwvVrdz!^1CJ!dmWSh_e%Bj_gqx`kg z`DqHGOr#+VjVHE<13PsA&rh1Z=`yTQE1!Xw7)yg2+u(bFN}|IeRGWJ+2g2$hNg{CT zWn-6Qh{puxitsGbcFreIrL`n{UrWO}Q|CFh*l~<$_`Bm6|LVJC)5F$Qnr-*CuT{3B ztYmE9F4M`XTlWo4cx3HgC~aU&e&3s3HM4eXe;Ml1--85O9J}RQn9gt&#?;gVQJ?KV znKl3c{hVUA8hBLGN)=|yNpCI|Q$x2sstG9VCKD&sB2ao!k;qDL9K!Xq3FO{4PO-m` z^Fh&b6teBMW%oNnKK(m{)&iO3Y_T0%1y!q@;tce;0}jNxot8HRG>)x=a+*zwyA+S| z>QlJR*D}f7IZ@-NU$|8*B5W1@J#lZdgw7T2d(tJd;XhZDR{c;|_f}?lf8*z@&AGMS z%rW_Qy$>L1-DDsppO)Kg+0$Q^nVX!r%!j!HVZd5+=}me7A;9;GBJi$ldY#ZlkbVOv z#zi77AMoVcBE1O+`iV}DQw!-4VwPua<hi@+19d85EqIio=qp}f(|gejk?w5+#i4j4 zB!Imnst#09%GFdzWx~C9Q>A`ZW&+G@y6{w@B<JMw>*sxS#j7cuQ*o?>0G9A#g|Cg8 z;EaqKr4D8#J<i|rum4G$IoE{puu=g>Znf{_iXp)YsM~qN2{&7MR#`8Jmx@nIxDE(^ zRRxB9WtEM5cKKrAV-ph&27x}(+9)CpR98o=43J7z&D_~nM?L{K=pZQPRmw?Uvz$E2 zOqx!5qM{;AE}a8J3}3jG+Mo7V`X(b8S)D+SH?geBd=$%mS4l5b+9>!tk>A(!+AE)p zz{%m`%@PhgS$mhdyEF&sGrRwhq}JriSf>ppZg*jF++-0NJp+&ALq77F73^qK&LE?? ziElEJIbN>hG6pULunh)2!dgVF1Kv3}1U)Oj`~dtmkqKxeZmXOu@5yfp_2MwRbA<7Y zdxrvFpe%{l9N`l-Lu)o}j8!Qp`Eho)L0`W#tnn}G**0=d$<v{xEC2C`dqL1x-4`S5 z;TQ$T9?S=RpReg{t)sF-WBpJQ^&$ZnRF2DhdaXyp<HB5b_IH>f;6Qsw5^*K4$#2kP z_g!_7`!i$YQo+mN<*`C+idOpBRix2SKkdh&;AAaxNNx+|HJZ@7ckL0GP!$8&t1{Q^ zxGYC+^T~itk@libMTgeO%vo&@y5m(vT?=+ScE&<7Ky$zKJgY{ErAw!}$0s|@$Dzt_ zbeHM=MuA?%s_OWjBQnOw0L>N%5)I!{Mt|iyVe5Zf;|na|9RXvA86~0~>j&2R%mttw zvVgN@XNZs~`Fjuzf*9npSQ1gYn~9+dg!?7a<teqgl(qMmPBcfKu=hv@;11{UuT2WV zUg}kKPu6q_-u+>ADnh0P!0-|CK}nS$UOAv>A-U5Juk7vZQ%$valoHd{JUVW*d{eu9 zy{$+%r?M<bm_4<aDg@h?-YNPP_vX$Eb91gm*Q7Us9iQlU*5{!BB1UA3wQ*CI=k#SW z3_xF!QNlB_M_~YdC98=){w2}4l+KCM8=C7l1pq{KZ`=~%bP(L7fkXe>Tf$3ji>H1> z@(3ogEmRbfQFGLi%~sEUR5ir~!%Q(@nvH($>n$NkP;D-%ypQ>rba&(xCM8CSeyK)t z^kf1uH|<M&5cLO5>ZV)|1)^fA6!J0}nI0#!y`yzmI@0c2J}3}g#cD?{XRBo{hWdp& zg|c@ta{Xij(I(=SIh>&fye8>8W{kUSdn$4QmvjwnRv5mxyi>wF#2+{FDB`DH^BbaV z0^5UrvgR*EYbjg%;jXaCs4o-`<2!nz8-FL2<nAB3sJ(4&?(XJo6YX+H3^lL)8i2ZS zqJ+KKA6O@wukt>!^>^N4Qwy8#K7McHz+oj{W+52#r1BaumFsCg@)1JVczq~`Dt#Jp zP4eCQcVa)va`k$@*O%Kgnzk{N&|>l^WDo20*^WkTfHM_R^`TAh$A<b_BQ^RH!Pq;8 zZzkBVE>?@!9Pqcf?1y<YD{QW`ad}#{_4D9#g-orIsi^lIpM&*W*!q<XHF7!+#7A{) z$A&Dx_7jOA!W=hhY*xn`)DrtVI*qkkhOOM+>>ZJ%o%jasVjOvah@Pbr5oas2Yp#u~ z+|))$vC0ikFZkRdlGfI}eV!t2e_9J$w(7hc%btz-mTunRp_?i?&lrdkpyt>ndz1Q` zLf3nO1T{$^+~{#yE^F5wB8%zyo~=O$PS&JrXCIneor*rKJH^_HgIZ{38ojTPil#VU z&<|gm4`0v2E`Oy6%h;En@6Uj5>qGap!*<4Z0;C|HehhH02{~TLgM95b4f4)xJ&V>c zbRrtqqxHd%*4EZF>#bMabK9=6uoF-w#&r7Ka@1zivrE&l?!^v`ypG_&CGOpP#k6IG z#%>+&fUVi1O3LXQ9R~kKn=j;5C#?Ut9AnCokMCQhui*)tgz`<FTrLMe6$`%ypaqlq ze~7%3#NXr+FCfWl;%`dLrn+?T2sxkG4<IOlb;8e3JMb|>m&PHcrULPM9DY}6XML4J zccxO)&g8J7J2DAF$ttRB&DG50-<$Z{4?DFdybDCBpx9585|$pb$9Ibxb{=@SXfhc{ z6d;1re9TOzlEae^=2#<G03n;BPdKR$P)g}Q)YfCojZ4H7HwpiA2t7`BM(Z0<r{%Ew zt8Yzw*X&F%xd~AU@va-b5AAGk-q-;ts_qPAR36y*%Whs(PSPEFz&LMX(RvAOqu9en zOV474I*84#K(xK@!qdvk)uy~&8olhO0Tl{dUfw?}3trz&JUvm!Dd?4S7OJUEnTim0 zta{8r!q(jZXn_Mt3@Jw!`cz%tu6yqKZ-aiZr&^oN!Es0#YghdvdA~~v0qzodjpFJ2 ztZ5zASk$DUzq|sSYE!xPlN%C?;fglBS79agV_B|r81;svyu+w)(+})U-^#uRlS8GR zY<phmxbrZ;Q^+P%`AC>L*sxbdOBueBTL|FEd^h8cPa6HYSld(rl%jWTO78}`td%|> zEl~6ROh5;3MAE1Q;**~y7Oxby<xKL|)qP2({60W5ra3_&DwjjeKb$<Z9V@_Et`Ke# zhW+_jvqpMOzlL()K26XlRCtyKJ=9c4N<J~^pr22mYrkV46<RXK0uy<OB#&+AWW&Fu z@hB$EOGv3_^E=vko<LdV>$3NII(%&BM5uvDm8153o^xQ#Jd4o}D!@V%tZ5Jayaf5C z%2-8(gk8bQYU7H^c1jA1xP;zM@-q1+B&yg$9%YupyD)D@IN9PW=|!$$Uo?Hfol_=( zdx-i32X5(Qy1sgIN?RhoIRlHVvI6+=)@T+V>P`*&o_4VM`aTgTZi)OSsq)-K;7*OW zsi~n<c1LV8PkLZa`zr=k-+*#p)B=-QXF^6aA_vggJcDF(X`Av!pi{QO{7M)HXm2?h zAP!vXAtF(Cg@xCCW<@O#>ug1tR<SVdR0GneT)^*bO#?#*kx@%Igt`9t{+sGG*X{@X zAPHPdp~zT`JejjSG88#L_u5vNdINsmVEY}PrM!|gNb9Q3M=!boZsm!<uRk<_`rlHy zP(g|@!rl^T!YOlt(R5jyiV4EH!W44{9Gn4190b{04!+WwwS1vQ$9F}b5-Hv$I2j%- zxky%1+?VJ%0#n{m<*k9lESH8%K2!e??<axH>oq1z^EH{Ug<_Kn?VYU6%-#TaY8GIn zEn0bDqoP_Llsu|2*@S7;)@m0q4z%%pGULmzNP)7RCV@yC5yOVP3(k~Xu2j^uLDMvt z<Z!ReevXh6M5WAB*|hXlQc-dfA5SJEWrpu0PfbM+Rez^rkEfo#T#&kXW=Svubo_dA z7m$>3Dp$ExPY;`sPaqrot*SdWeZpUz?8BpUg{i&7Ue_QU_Wl$nm$L8Xz``70!#6ZM zoN9<_HoUG_vr{j=A-BYtrWZ&BL6$0DXq2K<dr7uOZiH9*0k`L$CjlRG9vn;o2P}bR zN+yVp_q>6)Bl=pLNV*tF0Wul8+#Hrxy`@Qw@di0Jxc`(11acp*lTff<A|r#RZuvR2 zTT`&FIBiLkPsPb0eDTu$3ZE;)?`{T)i`b@hQE6p7^B(@T{z=t$E5)n911o*Q3NdIm z9a6V>Y?@CI@$O;mo?{}&TliLq>or1BJ&nxO?5m5P6};Bkmc7iHO&;FF*W5drXxysD zH8Jnptvk`zEIOkgRk$&<wUD>&{@c}^lrbS@YCg=z(5Z@nm<{aWOgQZi9Q*!AINO`G zc_G;F%V<I^zc7P#1|pa#_eBg=TLW8Hypi$=+YIP$_>gi)=#_%lT$?#C;^3SN=IdkY zLP!PS6p#SyWln6F%G`^w)R!+8uj*)beg4aNX#03Id|vmFRUGP{LR|3)8Yz;`h-pCO zllrq5<2W(Pju+>V3R$~<GVcDDQd_-&%jea$z6<n)*1T(IXh1)9vc+~V=k=3PQ}fUY z(o5WUZ+5{|w2e{In0h>F>B-ekqf7Nw_ZbMj7KW~%_LC%!a7Lk}N!v{8XeE?c4Z|9l zV~XAlfc7y_uPlClqC481h4|Jv=2DY-wKzm$uRs(pKoo<@BB|nno-NQwEeJGJPxdGo z_By~$mYR(D#1>r)vn7}95?=OfZ(C$ID}LeQu`NbPL4Rzs2@CkgoY+t=-8jLag&)N> zTenzZDt0hDXv>kX+l$&2I$+F>%taDpbpp}oRL^=%qcx;i19O2+1^dg(F4E__1K=O& zGQB+yzDle9cLe_9Q6{BK;S1h!29{R3)?-7Mh-Mg(WTK2-AY~LbdWxKD?CS1b>R@%b zeeLo<jf-jZJQzfyj5e$H*tkx39ix%d_D%#~g=Y+5e&JZ|GjseEJO73zbMKCx3q<oY zfIF2PQ$y+h0>VzQ{o=mI7%O&Xp(5$9#>E#AA$+fK^1hXEk#OlRhd&u7=M%LR{k7ux zDY(3GboKXlztAdcmeEQH^jeBBt*sC29USWRTB+)G>$hr&rz|n7$?!V9_lw$WKVi8t zUH;`jvC?$r@f`)+p`Ebq3myFLneKavu07HoZ^xrFLyE2YzH9BRUnbMB9{#cQ?-n1$ z786(GDk0=<#JWGgk(a7v$R^AyBO-Y^xzncg$BA9Pgp&$0JRx5DY|Dp3&dy<IS%&_U zo^spc9<u+9`eeEFSCO-@6K6ogZt8LNP`TVc#j^hGcKlxz<o<Kl|4Zav^lvh)C&`~& z+JD!>leXjZ-y<QVpfR$WB+`D4z<k`P>HonQ+7FMjAyz#4-%BD5VP*RMtN3E9#z1Eb zPu=22)+MHzXLfe?{?rv5pARCL3sjAEHhHb9OI*jc95}_^X28^)%z^4wV%3(I_>B1b z?l53(J;qFKcdY)V*E?f>{_%Ah+(t(D*&Kz_jFzoDOyqgeX-~9irLL1)qG#1q05#_> z&b#|-d}57CD?ng;7){g`rh9++9DgKH+g6bc`bb(gAN|88UZgRO*y6LtUq0PPSK~*i zd`4xt*)_i2R$U(Q+p5Uy!xN;Xw}8S$@t*^}{OIpK&iRkZ4ZM!Tw7liTQ4yx|VEgeu z)qBo^JDt4z%04WdFP!|?py`gXe=0RzFD@(;1iyThZ2=(m&jtG<`)PY!wgqSQTL4Sq zm|8nnQn)Db7cTq3KV8m@-}+0?_!DQ0(HLnep>cK&p%4jds9!C2d-~Y7?RC7pdOP^_ zRORujvdms*qgX{K|2_Fc;=5Phq%hB{DHo0>^@vRTfE;2o>lN++|H(NBJ3}u=pAt{z zz@u&<@Fa{gkd5&AyfM2w|H0Le77L*$NeSM}pdCkEbTKZ)A{Yn)tf8;J%Bbt)cMu;` zj)tKK!}<7FqxaD5l!>2##P@f|UR7nj{-=Zg-7;lZrpRb5SLpT~xfLu==!;pQ3o{4% zLMuj@4^ic85v=aI;CGHM^6$DN{dyIdKN0;rwc3RLKgK10N{c^x$>>!X?W-gGx~Bi2 znoK?_y!qP6FYW4U>(|<zW>VwM3?vIvg_m`lrF1A>$I%<$*@*p{^eF5%Du^ZSkNGFn z_I$t`xpf7%rm?aYj>zXo*D&y*pvItx)oFMK7sKjRZJl3Y449X8!~Ytk&$zcn1}?^^ ziu_A5<Eutf{O2P2-{bW{yJIsRVoGT@-sU`hh!W-@@qx@geG28M%@FW{y07welgEEP z_?XW>n)Dg>v(j!W#{!T#TN}Z_4wYSe<t9vgpMC!qD(*_YY~t(fkQ)KI#UlSXE-zhJ zOWOt<d@%zt4N5&!zc@C}won{h(+Uw*p}68zC(BjDd93m2zczw6_b<!C<VQXrVY98@ z<D3@;N}MkMCa$=yC$Y*NO|v!}gG+U!8~(oxY}i|V0{jZFaBhE+UG#+4XEAqeVe>m+ z?m|mybA6ZswAS)8&MHLhza*D4QtiC&=SnaNp0YPy^VRsP82>|V-iZCI{~UF{iC~I_ z0WOM!u!c=b=bYDM=nXBwMF#@p67*459QXqlid2ycV-S2>sD#6Qti7>)Anps_Zd1Gh zM?jn%gGPRJWDo9$8SlHbqlg~T6AU{Ix6D!Z-B59c9-H7#x{O%HCu)dFTyL0YmWw_8 zPYjRJwcj)&=QHP9DUOeuH&-HhdHGU$g`giV)UGC8lM65J5-ZO)!GFE_1H5sarQ8gK zF412>Q_YGipCOj9gM`<@icJD>gj3l#hv2C$MSOpkhurQ1%^g5E42k(9&SU`qz|)Z* z<hI{cOxCRV?)q5@)6f9tYvU01C#&03G<*R^>57Nim8(rM*Z<$?$M3|8Ui}o_Rt!3U zB|q$~7{+&jLKn_oba)DW*5_aGwi-R)%SlrqK0G<cP8yHPXK~PrBbwGrvFyxE4xn<# zHZ0f>-@^oW9ELw41Dwcx!PQ$0gU1)QD_7KV$EL9O)$towl|GrsojQ7Vnuz*}tEJsh z&!7geH?W_|HQrRN{N%!mkD7fjUm)SW(kWHVP@^`ooO|$bpIB#e|8vSaej@Enfb31| zac%x>E9}7|<tE}xpbJqPjMjD&Cdvpvv%T)djT^2=Jf@`l?|+G!QfTA*gR^AENLpHm z9Z{dA#?4V;XJl}eW{?RBLl>$uX8mX_$Xl#8QHl8f!Pk5k+TlWe-^9cO`vXuj@tQ*s z!{g<<?M_bCl1va!R7&a?tzp-UF+ZFhW;%dIdAl-u16Nz)eD}VZym7wgV&cgf$u#@q zgsIPV=nJg&E$o716k?6a#(g9NbTIj$WDxOvYeMF##k^v(+%oyW-hM@$UwjkNYK269 zU$sh?SPXdOBWr`NgNy+wxetL|Ngf<YOjd5`cth@^e7MZy<kJ=kBBYDo0r&E{{3+z{ zwd_xo({p>kop1fV^*wjwqlT}v+;pig48E8dTvoWgzxK$JNAk(T_YZl$ONM-^5p%x% zK=KB6uR70-&)37w;8}DLm6AQ9DE2pQC#<jeyIFI8y|&~>#r^6jd!6=o7Oj|!RMR%Q z8}=WD?5;z~i4+4O_J7W#pR&Kk%!doHfEN>4m}bOnuqi4f8C(yPKyjyA)ZIp|4#W>W z3a!U;egkD%tf^;eP=CUTr{7Vk&bIu?V~DzIeHL-~|Ecb+qvBeY|4|YGB!NJ1hXf7o zZXqYQ1qd#KySr=9L4rFZ!QEwW32p&`y9Z~23_AQaIrp5Cd++!C-fz9P-XE{mVzU`~ z_wK2#uKHA0b@g+@^V3-z*rE8RpjI9{xy@&BKzNl=6(CrWv>l}WM{Qf*cw0i}24T}$ zgivYT>waN|>7?Hx=3+UWl`~h07|1qHx|QA51{mDE47hCch@%9V1M4N0hIDwAdbV5S zH$E}bm?W*H&upXGkh|maEMMRe_LB8;KL~WW&g>)OAYTg>uvtI4E8bW!bbXoO<idCO zyeJcrIe*yTkK#KU*oI~kGWKTqemJai+g|;RFR9Ggk<&*GV8SEdqvo$|M=gQXD8`0* z?`mMw3*LJmzV#{r$Vo{?KN|vNNXAG*pa8Q_VB3-lM$*3WhX>D>!VPU((=12$qlu3$ z1wx!oq_2@1$-X+n7TVoSb-IM=NhFq8zbP#fhyAC-A8V-jOWhvO;sOI$ID<lWRiX_7 z^krYxcs!l*;~?%#_Sg3v28yq^i6;8x>`NB6xuF;F84B{6H)=@_*iRh$L$jDC2VU@q z#9ee3A9;5Dr`*3sEaK5opmaMx!`)++7b@3MLH}YPU?|jXKtSFr-=|GSt)4d&zfjP9 z82V^Do$h>S+Xp<%n6GmMTmIHpBv*0wHV{0XBIa?7B$ZF)y+#L$q!M*=^QzwiU4az@ zmIlrD@m0UU34lQdk5{2!Y-Zf;Du7v^=2(anehhciFeitb0-L<P`J<FIn5R+QRI~d7 z2qQ*>I^p53G^Icvp1u6M`E0%ItMCc}?+U`xt8*Q9_t=~-R5|~NR2U9Tvj-mPU=+Fy ztIqa5Kq<L#yxAW2kp5w69B_}te5L=4(7vZ*TFoPGcOZ$?xP_QlF|taU)mE0mFN()X zKe*4a2$a6y3brI3tJ3%J8SnoCjj;SpyAE-<Mj?PwZ|DkfD*k*f)ao&@qkGqsW-gTx z*8dIE2nYz^GA*X*>$&-_R)EH=1{{lRJ{qzx1!0IpfUfdC|IaUy7L$@p;I;;Ev}rYQ z(rVZGFC=da+~Y`2`Y65pB?T&Cd{ycHg9yZLItPeb?|g2sMnlLwX5Z3%46ll#x1RF= zU|>%!0CRtVg+E8ie5p6JN>%I1%OdE5w<?W4Fmr$A=P0$`6BB?sd~9S<Ab@?2+Ax&! z+zz@hl!@Ns0x_|@$V^WbPWevZ*H4}l+3f%O*v1TZ?*<h0bQOb`iFG>%iO~sGYRAX7 zK3Nn=bLAO`{8vu|2_Ruw#@f;{NxtaR?*MxPTM~%Jyi``A)BBTQXGy-ID6AtE$wjZ% z&#x>H<+WV$MhpIY{OhMpAOqPJskY6h58HKlfHb<bzvk(*?;A=-5$|B%B@Y3N)>B*= z1NfRcowBaS$9db9q&si+q@KJ(hJS-N=DWs*AMc^$D-<cfei_dzO$xuYa#?5haJpIh zAkz&2?kR{f-bc#N|4YLC8=YoglO4m>$19uBYV}_0O1<Tv8|jhEE&^^Vg6pI2DbHUY z7?Is=8#R)+zRW+*>RyL=zfD1{%*xsvfpwC&bj<E+od~+Nu;HVGKx`NK9c!;0&XGdm zgs<c?FX^7z5R%`X*u#JL(&LjYC-mQWrT5oDukQ^eb0GlDZYW6Q`u*uvGIBhI_L83f zKOFEM30gN*_d&++LgEK$ja6dtQ$c3SFNv{3|KETP9f5=}85g6AvV;D^DsmK?OAgQt zPUP|>avVUs;&=<$*#9eYMog1wHaAk4i@EUPFFE+HS=o12@4Bq7sEtYx;#)0)oimT? zc@!S5XsEW2Wr)R<mrRCjXpowhW`h;CV3|6NGXYktwEVjCT5Qbht8OL!JJCljFt~q# z?CaO|NH@A!?&_oIiyYOaCW)pZBZQbSoh5&S_(s2W7PQ~YLIMkj4)3jc|9q~s?bA0= zKDza3vEx!1+HiH9?`v)jrTr%0kNw0voj)Z2<R^d-3_@sy(()xZgvUW!A6*b4xLsVw zIIw5de8B#C{b(%<PH}PFgyl<b7`rkg9!=)mz4_DQ@{HHe;}6HnN#Ry)@d7LYf@C^9 zh;B4T-UrU4?d^3;N^v8N%;o5eN|xQEW)YX3*5rKd;Uak-LEsjr)~CNnu#GIK?YR8a zfQ9eL9yH;Kx@okq*gc&*D`6UpNuK4C{V;^`Rvs}XCWatb)Xb~^QWh%tncH?r@Xeby z2+YAngNaNNXYy~u(+A64O#mMG5EPUGE>Al?wgcQm>J@sTb@Nof+*VS5D<(EpsGJXO zTmKLeG68Wkb>u?0xw#n<yX?6T^nSVm&VCnpss{~c_JXOs;ETe7uW3=C-(u7sc}K6# zUqLUsob4)mp}mgl#{_41qHWKNMZqj?%wKVPQ`+1NH(nlIZ>S~;od_BCHj7TLAr~r= zvpG4Nwh~lCt1Ziz%t*K@EyeaEK2c!J-STyVWQ0IANg~OFQl~+_i`v>1oR*33i6^j7 z9J;DT*J(bdIJ%<G^sh<mx4!H#7=DG#)oyVGEv<EfhsB5hD8@r8_iL99@V$a!pzc%A z?&Rvvz9KOAmHVmr^$qUgysxWHmv`vuT5K=1aBg<7+Wde>Vp?Cx1bI4nqf_uc8|~Tv z7K@x?1>Q8<OpSMDkQpB64P8uqm{ZB)!eU&c_O-i>NF}zu@}LBfgm$K}E6zd%b)-aP zBzftZhB6m_cE+H@A36#nGx(-8{&91PZ5tUJz_ssetHj5?$8>X2>CarP_d-=kQd_vx zHjmDy7_pk=Lovq#@)gzglPZ2BsWpclp%V(*<`Zrfp))dH6pTC>LPVLML$tEWSeS%w z-@L7C?@5`@cW1W8W+KT`^CIhKY)8;tj3=kf#eChb#7`cy@ZPRlHuG#b_gGsFFOoiF z)!rSq^`qqwZyOG=ZSD=X2;5QpyyEpNm91s<%qVm2)Wcp}fKohy6<-Jcug=ps+^&5X zD;k+eqL^lJP$}Ey>>b&~H}z80Ee$v!4*Hii3=Q4T%)=~3^?$qa>N&#x!zn~9=3?cK zZngR|64~xsmA&rJb*L9_&J$r|y^C+BpV=bZ&tC?&@g!m%NE;xyeP1i97g@`d2>#hK zqqd_mhJ=vxiL9CZ+&NhICzjzd;cIIQguqy9iQ}=RF83c0jEj|+mD6beuB0uUp^<KG zefnp!Oil&rgIz??cK4MR@6bZo)fiuwkX;}nukGo>!^hi)=gG-k9U-W?@K(1x)1oAG zA?O*bQ`^cO*0DU#B$UkbI-RZMb9J7Dlej?Y9OqH`n0(A$QiSJQU5P&_ptQnU3`&P; zxYrJ~{mNnVivW`Pj$3a&Sv*kkpKE9P6a)FPVD>jJkjh!7x{jDh+{XU8QcR~+Uv(2^ zC8)`C6#Yd#$(Qz*r)?>Rm72(*NFzGQPa8<SA(=U7kOIgk?fWn<((!P^=*aKi@_C<= zf=YFjpU5|y2HXO4D`YsUT0HSE;RG?iWs$gPO?IK&$q3;=0qEzi>xPG;Y8&r*^-l}B zUwP4gX;QjJBnn1Ah8Hg%jhQ(jH(WE9m)h27Xh=(~??F$IO=WF=loS$Wj78;f4-1&q zC~sUDkB~Upw>kon3F6a_LR6d5b|mU^CL{lg9ytFj{or7275b4XAfQW({DN8997w-1 zFy8Y!MbKOE<VGOo`h=d2>VG2k;o@-j<p|-m(#Dn8PZggCZRh{)Ii@|<e|9h1ryuBK zwhx3#<jvd5ddq{P1&9BbYWHt<z<&3`%lfyzhVq7S<ncI7y^jRONI7lm*G&C$zP{pY zUMi~t{T%p@(FzTXyBF%Fa+5zITsUjZm-w<XfXU&wl?*<~;5g6iJCh-M^=`PS*nRZp z9E;lEe?1PsPPrcz52w;n0{-3-g^5XP-*Xx~l3FxIcwlBR(d;NLAXWxybmhU{7BJnH z0oYLc-K%6@hZEhcI#5{xhcH8V;%|@BDUm!$ONMU}EZrVk!sjwWyR=u49sX>Qjpx9~ zOED{rWxv{iL&4gkHhnDWiW*?<k>PJF(;jj$={h?t!)2hKY5&zKKM8H}UB8<P4_Rl0 zzi0{ENU#`tIAKG2sH3~~hJ&MgbWj8na`}VbZvBVQXeuT-`4NI0@A#b!13Nob7wh9^ z&$y;>G3mZ<4W~&+N=oKc6%@SEIeMGZ*T3tL^pb)iprV4+5$cRhMkcSWPJoKX*yoaV zZ>>EA0~Pt5cb%ZF>42)@cRjQ!L-xzc%7RFyZ|*-_^3rEP>=Ak`XGw1<LOM`21v-{> zRCAOAw5~PtRnjk|@&1?6a2!boi(OGP+l5h%Xj6?$wRq+^O4^|5G(FAYU1OHZZE-1e zcm7=O1~qVu0jLRaH^Sw71=uEEUKQ`@Apgm>Y6=||t9sGbf!jS0j@_2lcuuSR8y^CZ z_**}oM!a5DwUMBO59I)JDcNmIlZyc}EG7*|?-mHOM;BhzxMck9m$-L0!zsZ-k20Jf zJkw?G5^jw9naEiu>lQ%Ab=Ng`AULFA8#<OPu|1F9I%_XZ%v(tMOL_bs-BxC#8{wAh zlKnHwl#B@AlLfKOk=CZ9E4&?3q?zxFcTLLf4@QbLeX9C**ip_8yF!_^2bn_zx7_5d zP%?(1XL%Ax-p}sWGp6O+6#tS?p^}&e@2U<S3zJ>bk4D4eG030vY+Klrd1T;xD13GT zKF`$~Z^e<FOA3&>R$|57@K*ds#Q{wLZ$<n~22hAeijwU(awxaq$nFA<+$ymaf_|Tr z_pjZM{6|2BhT=#Pk*WZ-p3<DjbmaKZY5rIB*S}W>o|i=be^RBLA6P@<VP@gATR{lc zf7jx1HV77b`?MuPz*Xt<n;=<ZdwcuFr7+2uxXCl-t}>mb0-dHh$VFpVWMr<(!QB2* zi@?0~eL{6Q#<jJz0?pdp?qz!eL&HMN+9C)M0vQ?E76oR1@WG0M&*g#b!tQj=2h@)) z5w&rxn;|<4Gn)mk52RZg5TZWF4P6`x(6B^pY8Pt0f9BNHF1i+Vd2?}aG_-7owM<m| z>Oem^?W3UdQd_!6>s=6`47c4vK3=Vir`|>(Xr$VAw%qIbgk*}$DPQ{Fr<-~5bZupp z(R$6%C4AJqWG+!sFLF2Dj;D$bR3*Ujo#nE_-h@XHbsM{qH#q0%v&Zy4tEq9uAS2hP zg6OA#LZ0WzU`~U79D#3bp3grpkxTCk-;CLpu}5$@SGe`d!k$0*5$8?Ey^ZK|LyP-A zNDlw6lM#1DT)4<+hLY<-5qD0)v?N>NR4gR4cu?rf=0%8byCKXqzqO5P^ftC`lU6wS zKs1Y%Jok1MbYZvav%eKgg+W5acokt^$whE;s=PqfkdDzBMnm1?)4$dHu5AOOch-=k z_A&;m$*(PXo;luR0)IB0ayPs4H)R_dx`5z<J_3&+WkR+Gj|O3aqOwbLpVgn2M7Jq$ zHM%nQH}>hwU>SxA&V4v!l3vyMOu1-bqrWLqm;<klW#Vcas|?`D)pW|=8B_U6l{z1@ z;Am$y#<-?+mOGb1y3e~K*Zs7c?dNxv{(Vhcx&9HMf~|FhTiyE3-ANLa6>mATuJ-Ep z?$UU$Jf}-6oN9vEOqPC)OnmM$8R5!!Ytby-g92PTjjxGvAS3T6Bi92Za$Mx!X6)Oq zJNqc69QHD-uo{f!Q?c3u9NKm7C&w}vnnE|Xl6-^;nw?M9ydOgA5!8=iuGH}N?EU#` z_Gd5!-`4J|*GG@!sm#2lC#&r@R$iVD-DLz_M`2(0T1MQM6BoMgCOM`H{=2oqR-sT9 z;6GX#XjZ*RO6KnHD%#sURoIoYgK5x*uN%TR3g(nA1eIkmUQ;wVQZ-p7T@|qYDe!*H zdnL&X5#J^4c;ggF|8+^de%BMb(!Ie<=d>^xSv^?K;@9=4G%b3%!ks^ANDAo)4iD8A z1np$_6v7ePMWw@^@wlpKFD_Q(=6uvm@4S4^Be>ucJ!!eRwIv?r0y~jx6J8MbBH}Zc zSkaYO?_=-EBPqr5H752=Q5x~#Zla~0>2myNnAIsV$mg67gvQbz!E(3uHgOv)!Mz=X z#B(-yW@t2tKb!R*93uJhY^_g`QLFW4?JkK4Gy<lSFfO80V%4CVt`bTZJun<S<Xs!3 zwfDMHjAb+~)VL(5)Kd22JnuQol|2h@xKPWM{>fdJ;q15mNXyktskDgLMx}VY){udg zWQDgW(z;)zV5=NwZC9gEy_jBH3CpEDCjBd)8peXo&vBOS|FS=7Q|DtBsvUP{%pV2} ztoZw@T|RZo5FFXD8c8w$7>9W`X|F%k`8RHvilLNfwRi6TlH0SQ0pW7RAYDcZr5^_i zkhrI~^hWexF!)cKu%yhD5D;2o2XnQ<-P3YbR*bcl(<ZRP#aWyC^Zz9EG4b&wCW};9 z;8EDb#4^C$@Fc?V@$tQZkSm>JFqDkZ{veIpdTXz|P5<IJ|CLr=1f)o^!=OR&i-ivG zVu_YUe-hoQz|?4ryvh&;V+JC|3kwPcZbswP4iiB;kfU^CLQbqJ=W+z7y(hsJQ)`Ee zZ1)`*Mpk(I!ZinIC{%yAxz=qF{@A<7<FnbB1z|%{x#V0r%Z1M-a^lE><c>eacxkL{ z=2bUKfna`D+X{?pFHGGhiWy^BOb8Tt(&&Nr@Zp5|MVqY#QBzpZ#FSF=sP}0R*=q>n zRqp%OQ`<qNNM|xWb|j!7Qy`HxsPcNI(wx+CeQ>N*-+jPz41YF*a#pA5y9Cl;rjX~5 z7y%Rt-Jy&m-T4DdNlD3u7WnPkJ4YSNm^ao-&F&vQd;n-09zOod-oB?TFasW=qH^Ga zcve?e0n58muOq;!{{FC|oQlx!@Gr{w^7y{JPcSg@9k)leED$a(FH^u}X)T_xpKD-B z;6%qQZ+ev?qcRGmi<wwS-h=kRWz?j>@PloIxQ}c8S@rYAtA&B_98jvJ%eD0~1Pb37 z$#8}Ct(|DtrZU5JA!uAuFd=mH0KC1Ku(>-s8fQn333jys)(}qK+&btO&)$E%-RuAx z=vwy{#osnF0A!L?ir$Ak!G`yKcygy)Kra?Di49U_eV_-}Nh0^ZSGEqy-*JI7pr@#P zBug>VKK31hppJK~RSoOJ$@4z_hk!8FR?|2abJ-3B<N-S@@m{0<DmYl{J>KF#(8$u# zlAEU|Ha>oDgMC&?@h{J+@V`k8q({iCH#_;W4fd48+*W!Q6AIYs6yLPv?h)co|9`-5 z%o~eu?f!!2GltElKN*^D28spY7wc#wtnL3(-2qlKe%IZv*GDab$*|>Y<=!ZQ;GHGU zUm%6$H^_kFaJDy{uiN6WWpHmU^-KINgzvlH@S8z)|My!el>eVq5%=<HMr>cTLwHU| z7^Y9~Avid7FFX{-;$&->l8TB-S>yft_%c@tr41wJmci$kn4;?H$pF>?7?zfiF#-t{ z&!|c6o^C;6z=2a4{LYOR0`hKdyZ~0>R{M3n1;q;*njY;Oz&y7h(?EI#kSFKW008|( ze_^%0$w8S4B2rRoW-MA>=Utr7pFhtWxSY^K<Qef$fj)FCFE2L(IX-gURcn@RQ2+oE zh!mzbyXO%xMb+shv_HvRrmGtWh^FG$#6%Na>gg~r7<FuH?5S!7Bc=K?bo42xPhdks zLxtruvyNjr<GMEnIy!ebRtyD2F=laN@83pvpR-=AW-YIK3~}!QzGiw;0fx;G1qBcJ zZ@3je)xn>;`vIf2Z}`ps4sJ@u=#$A6ZeFnf#Nk2xtp%iv16$$UsT9}g+?44JhHLl{ z!M7Veyqx6ejexj1#T+wf;~kmO2JahYt1T6tu&?IP;}`x?=?=-$00buajlG^C%&+F& zn3|Dm@|68?fZS2DBOIFVdy$5NAj8Km#1`@G6Y;5Y=K3RLGIQx4625l~r&5}y6!kSe zDY@IW$J|RbO6sg7c%&k;@bXr=hH>?47Xb@Z+xEb?D0@1I>PlyATMLz9xw~?h{^%)* zX=8==WRYU2hqJ|$wR97F^ylK$hrznqf{M!Zlh*G=vzhhNMsRR={N?DkoRjO4w((`@ z^h+@2u*EmMK3ft<54xi*@5h+Hv=#SU(QoE^?roOv+Xo@mM~|*}ng&E@fK`rIpTS>? z689I#*uKPt<9EBfMzpoT%e@Ov=SOX=A|Firr%unrU&wjDs2et(UGa}T{-nIjot`d~ zahCEhbb>LX?m6sRYt3nM$GjWi$@|(_=5y-^YqdlHUnzu>#)p+NvuDdA@u;`yEm1>z zyyvK{$U(;@5u&96AXB&AarL{io4qz|A;hEb+*x5mvJj4kkecD4WbdeOTow}8Wsm=G z;<V)V_U$^T)m&qOTru3}ea5iY=@9Q!Ug{pMLmiWBR%P7U5_Bk|F4b}COl@Q3duJh| z%f(8g36bM^8Iy){;dtf)(&BX+-Io+fehU}N4!@+v{l&)Re9>z5P<n9wdaS~TO&ffP z{k;G+&~vIg(pRB+j~BOlJK8B%BU^9o)F-@L#5X+g_O924_#@u1K*k&Q)e{Uiuh$|T z&Q=QL`93t<d@XeIQT-7lIMT&=&&<AUs9v=lGu%-b&!sXFT(~^W?t(yMwH#N25PA!{ zWwr2LkG9I$b0{Er`S4UPL9)u2h{iuDGF%CtAQF%8w%5gAG&!%fpmwc{40*(g*ET|- zCd4Z*d<G~vJ&ow0?!z77R17Lt&tAAqP|?`7c?lL}1ajQz87IIOX1_&#s&mDjnn|(@ z<FkDP+iKadGs3IJ$U$+S+si*mvQ_X<ZNVwgy>zQ}q_B86y0DbEg8a;Ut_UR>UV%i6 zE)Qq>AP#F8on}GLv#pmGygGS+<tn>bD|+z6=9}M&i!19cj7b~%tzNxSv$Ww-HFvPR z>=Eg5Pn2@LI^Ut<Rh_MTHqajC)eCYaVF&#hyQi3=$d1><>x8!}qzh9mLI>9^LlNFd zS0gTNPqKuk;#4Dvzp>^BMElf*V^1ea=*E3dHXjlk4>#4_4Y&5;Wf)1d)b?M0<r`E^ zRdHu2sO^b8VRF#QX))&$pGz+C+DsCgi04V3aqoi&tt8}}O4}(jWM?yZAcxcw8{C0x z5vwkf)Tc8s&xb$IdQKFX8>Vtv%Qww0nb^O1Dzoe!ynKGR4f{-LK3_-K1s9CCy%DED z-&5$ti!}fCA~`BhoWoH;{Gm^fuoQT;I={`}WXC;XcOkKk^w7Aou9M?X>#YsiZ<2;5 zwU%FwxZ~z7VykI3<_6m})rz*!iRw9YgyTkW-=0RI)EGK_%g5=8na_ejVeP5WT1!)Y z!x@y~E0=Q@ra*}8L*-4ROzD@{1@B!bh%AY|NY;WyZFbulIA)4ZRpaXGpi$(NHa{2V z;}sT3?{jGRp}gGv{*uJ9N4Q5|UW?7-kl#S{w(t46XRvQY0F@<^CZ{}=$FPr8PL=zx z$;}{5HS^VD7p0jB4{ViGp6>Y_y3c{@BB$Bfcd$zvH`?7q2DxsNKtgiI4`=J-pX4H| z;>)~Hqv2I?r+qym{)8-;E;6L_2~2X3)KbXyL_+$|50v=_Tg~I(E78qD?KVn<C|~gW zz}fb81hFK|k={T7Yd~>gt`j7+#`~Dz3x~4-zf4donprJaDvle(PqTlWa(+#;yD*le zIfX-!St1n@0jyz~&a&DQEE2u{BD?eS`yPKf$Y3-#n)${WA>sP2&mQGtU5u+H^1Jgx zDJq1V(#?bwljcV5c}kW$2v?p$(j$}6g`h|yRRz%7SzV#Wjb81$xKV1?a1bGM<4FDJ zGO?SDSY2q_k<5J8mrYMzqdML2R@iWNA;`;n+g{jnjkK<oWbh`L0558<)4x*TSbqaI zd(!EA!YW){DqVq^{))iu{a$aAFQf5du%r+9Zf^<xlCka^@#Wk~b1@Q9;fu&Z$1T>f zVezF)rw3sOb)~XyKampENc-a_iPbqa`38nPqoz$s+eDSovM4QfN!Dz4<jN0Qc79Za z9#cahOL(3Of_bG(GB9BwAT65keE#SQ%A^|L+~a!Fq|I&(%P@_$R3wpzFOKf0>7X7{ z+tTcvUer+Cwx|NWb@#Qz*AwJOGc&MW;0#(ceI+Bby=msnXxA&n;l;>07T-=kY0-tV z?l+0dI(-dr<BF9x5M~zW#1}K}vW))X+Nt9!OJBQV1HBBntOm}leg*REOodlRVvNQ+ zU&!4WOnjmf@nXJ+|D%KZB2D5y!B9j_R6{ruea<KX1$gq^rzI|&%zGpo2Gc=Z3)KD# za5r*#cY=oa)`Z?e8|ggW_E%!lO`eKNNOn)YOfqfG)Ee`c`_*cqblMbth%WY*(Q_ng z%tx{xV>8<Do;~^GuI?&`FK5_qjxvM6=6c0nbhabr?1*RY!xfi5zjJ+x$oa&sV^<?` zN#T@M4=QM&v}lH-lqFQ0EhRZWJon7FVg0ifZ;gpin7Nil%My6SWRv4afh;+{XxO~} zl;nl;?0aq(c%n0k3oG?Lg6+~`8e7QG=IAiW%#E|mRPz<t2^NdsbUvMeSABpr3P$DT zsHY_SMsZ2Uo~+C6Ic&l%7_JgmSq!V7z0#U1zl$?2)J}G|ASqrVY42k?xO5oyK|e_D z#_mx=bN6PG+On>R|1$mQoFtPy?96<}_&g&nrG_rqzg`W(ddotPb0^5Pr-2+Lr?+C8 z#_MLsAp#TVo5zTtrkM-?4RU{9s7UAPM~*Tq*2qxz$0Am%67Fud*TYpbO`XVV-D_LQ zPERb}ezT~%D4E6)So(w^xvqq$<qsLtt8xD8^~s)Ai1O^rg}v^s7O8EqKiC#GU@r-B z;WZt63(1F&<GrvxvD(Vq8Tcj<@T5W$YRwBs%()aE$J?M!3qu_{8k7xOR3A*_Y*sV- zyBoF_X(8QR(Ro5|3e}1TRKc_=9zv2wvBVlpT<fyVpG~rw%t_6V!WHwKIRxu^tCo@L z<R+4_rZZ`S7o`b#P!Bf+*sbj3RENQhKl^6)sO^zfPe#Y`Tm`&@w7xZg@dvx`?I?OJ zANWNIRd>#+LuiF8o0Q5dS%{9Z`fDQb1Kibkv}4h$xLh!xg{sZ;oL}V4Q3=W#H07)B zvP!>ZRIaXRr37<5loJi|pPWpH&z_&H+9T)}XOo^TmH8-<C!N$Vooktu7k^S^(2$h7 z*yXBZc|ydkvp=(c4VV<=zgr{-!D`Pu(1^QSCz77G*kERz2@Xb&Hg^nx|9COMhoxZ0 zp8LpH+SsesbVaKXr<-}So>AA$Q-|Kp-uWdL*X>q8U6%|Y&kggN`MSK}QtKV~7JF=5 zEN>E+wYydk<dLW@f6=KtgFd9+ljm`|qqqZlSwIP8m5?Vl*$q8(+8GaG)@l59Ft*HV zB%ttRxV_2TvB)aQV6nsbZI-QU@gY-TtuYtzxj43WBj&JWnnXK)v`pN~h#x8`2CC$# zAA*$FT9I!hoIaH_p;FH;iVH-mb05?`zzdjL7M<qzcT+F9;PUuL>ycM!GD&6?h0T~; z7w!=)s4(qdLqMkT19qynYt*dRKX|!=A%Ljs9{UliOufazp%)B$&TGqW$-dZy*WNDT z^y0H==cN!kp`_tpmTy(|8NyXOk9W&nsOe!e2OaF#?6CAGaI!m^217_@IcIh#T&@f2 zdu(E>r8?A=UdmFns(x4*?TO}KcxfTk+cG21>?zJc=H^CuZHv<{A=lbIS6=LvyRbY* zy)EwnxSO-xP2ZDdhWG8XX;#x~_<namN!3|`@^AF`1{zFCYL)7|q((A%Q{*ZvRu*@h z^F~s;L4#j3+BPI~%|Jw8${1g`Tj0wUfp2+dr8Nh~&qWS|2O%2~*nOWG>Zfxtlgr8) za`HYtorxmdlI(ma4wDiARQS$-4#=ik=#0@cLzuK8@S=M{eZx%QNXwhmj<!MV6+C8j zsL5?&o}t3p@T#Wt{n1#)u4+a6&YN-*i4-BB)Dyqj!!EB2Clv$X#w_&VdAoV#tm>Q4 zXA7EaYa%cuFF5hSY#!eMN^|>H=Pku5JbE-YFwYxwRyfq=L(P6arQuc;47A;YMCX|- zw8eJi+?p_DJvR;?xvOHkB$2`w;Jy|HjAe%3kO)$QVhKs<VN(VToxrTiDm)H<+8qgN z#Us5-f@6S`ii9t<SPus)jNpXC@nP1=_2r;Os}-Fi$TnKShW4&z>Wf0w3sr?QnT-fS zE8Dpwn@#vFZuY81EY?y2<a!VS?0y#U4pZ+eN+AE%jaagohN&$WoZD7v0J`1!er_pU zt;EK7<47&ATl1+huB&BG<Ke^pzH>BJSHW-;tdEsK!2)Dug*iFA2q?6w-aYF=Zwf%g zc+R`rTdN{bj@)dRA-7Z#3Jve__H$$064^IjIRc+oqwpo$eFTwNi2~TpY&_@5@Zn7q zVx7^55m$Jb8w&Di4ciIKm@2P_)%>UE9L5hRDaTJ{A_E;=+n3uXK94|di!@AR#+n91 zQl=y;N?B9GqgW6Nlsz@8oRLy*Gjan;dIu3p)slS8Vy$DIwyiUhQrT$T2eN4mi7Tz7 z$AeD1Iy-J$uN3(|a@gCaLpoQ}Dg_e#ur4xr`&Pl`sgYeM(TakseqfE_u+>$WFf8iF z$Iyn0Uc@?5Z1<gYM5hZoA{kXi!<{d-4dq2#YNj8lD{!b~&P;|%P`AI{Tn>SnV-wbo zzMQrxWbX~y2ZR>N@Opa)XY&U=$HID(_BoE%!G>wI`aDj#CbiL?h{H9f!n<>^=IN7{ zImWia>S;r(kkz*|4}y8l4!shftApy*ZVz2^Zii6sbfoC<9;RWeW`tF%*P4)#*9-ME zB(-glpV%KMMrMvi8jgRNEV;0L<&T+7z`^q%L|<=ZWt`Y%yDy%{jj55j9A5bmcQC2y zVsw?$VYP~XmIDD%!Ujmt?)TeT(8Kn+gnq+b4$E7zDC*o84-b~X){L(n(fr?w&90t~ zwh(?kkY~LtCfpY|dU5cBz2~m^a9J7Iv^z#x$$-cwp-5?b(eI=w`DR;sBxTQdP<m3= zyRh~gRs6O&ORKXHF0g=jY$kQLw0-G4R9_;L`fx^)zbYtK#*l9hK^t(}Dhf{cXow}? zMM5hQvo$7+^59r<?@sbAjL%XbMwxlsy-4ewr_IPa)pNRV---7fJH_ME`K3lfl%N>? z4Ye-@^_We@h|B1VDZ<p{TpyJln3D)Qu?szBM<bCyx1WiDYbLH4zdBIP2=N8e0L6Ru z7(<{wIzQSJZ{Eyp%;YrzS+%d>VW*UA<k7&VZwQR|u+>g(4H>1pc$5y7A!F~Jy`CGn z{gK+{>7Hj@uf)OJku$9urY5CNHWCx53w<p)&RK4w+P;Kiju){r-&qK3Z_cR~e7p1Z zxmpzfgqGk55WHKiO7GGX8NAoaVbX&>GDn(|vDDQ#98!&jq_gWvTXW&ndSxO6<tEPO zk=p=ke5;j+vkIJKq^5Ql$wpHN@TxGN75<4~a@4ozZLULfx>@H3iMTydLQi+}6H18_ zP^~oUf-=@$dQ_2T%DBBpKx|9yO;6!S;d7+nFdbg+{X99#?oA_5?k38oa9T4<f=bxE z0m07{aHMfGjryF%6mV>8T5+H~P*Qu%mxj#TjreM3J*wNHJLUodb^C5OhKjhsU74bS z*9LE}?Xc40g#~l53-!m{3Z<booK`YCMpZ;a&`k^WjPJ@&H|y!mEEOX)y>kCDE=ibG zCTC<Mge1!1;$l6{<0GO(c|#Wk1^#a#6_7DB@`u{>KL-m$ooqCdu1c>t_=_G!`$G8_ zhv>3bC6bav^6q9w8%o7E=0q-Njo-|#TG#3g)2*}LJodKW^^ZHum1y%v^Eu^^pR^b< zu14POQ))%g?|4EYZ7!jXBBJ~vwj=K2Htn%=>16X%J<>BG?)-@rp5*3({UFw_fjvw_ zA6?1>hf}W%^m0|fc?}sSdFIsvcd42Uud8V7x%<<kxftFpJT$kTNa4Mf^muLZXuQx? zhFk6;^fE-rj_Sx{fL5fEn$nkHD$(;$u=lH)u;J$F$!nsp5V(oY*E}l;P-A@qcph>4 zc!0zA<DBJl(&k|<1WLa{n2X_dL(+v$mz0wIM-LN`vFgMMA>8)%a%0P)Qg|@=dYZiq zHN#<tbwTw{OCRC!2<~SmIBZ+Q*>2RSH6;?}jwgI1<%ysCBS@#Cb8L^Y<+8<VesIU% ziDeCVoPPFH&Lo0Ss3Z!@<@ZFI!!87+MQ)Ksm)Fe8+{LDlVL!dLGn!|c@Lkawlko3; zW=lOg2{!G@MUVF83wH4oF?qcg%!y{xd%)tQAlqDRs6u>g5?uXxmvmvGjFDO<vAH5X zum6)M=R8l~j#k-oPMT7RoAMJUl7%eIT=q<@*w_RQ)&^Jm#9)?<_iHYBE$%!A0mNes z-PT?XMJz|cvsh}Lg2cW)F+SF*-wNz4k#BcL{;+)p;gmZ^+J=d-o_CCJ+AbuUd}e_v z^l3GJn?xx|_;LAK4Lxc{a=mBReI=<Y{zxRCqd#k+O~My>@dQUii|8Fol8(WJ^G2&b zdg~6c?E1?5<v!>SQ?a+~9Bb?Aq(ErRRj-_p5mm7Mb0Q*(G6o8zf??ns+K(SU${H&w zD*o-E{^RZ2NBa8uTWfnXf`aKlv;`ic`o{zA`^9z~JfNb}?)ROwBVNEg0UQ%ItNqOH z#}6}$?**conup?5I>aavK9D3E85`673s$e8Vp}X`X66#zmQ-L>T<4~YL!wSy*la$r zptl~ntp}2qMazb#i|$|CGKVA9m6DHr-nP-b-ge|~dQe#G#^y%Q-5R|SN#jy?E0`YA zQ}R`{ND!V&JTb(dL731+yF09>J$}xyo)F@`dQC8LHJJyiaM|~D<Up*4_rCzWaHn0h zZEF{3E77z460~N#=dkyYhY<F@*y@nb!f-ITuEt9sQ)0VpJ#gv}e?U2uKr^JiXjp%> znyZq3<QNuR&bGTwSHkB;#<TpC^9O4@Tb9Uc#OYISf?3}9ESt*&YY^<~L~EM8PU>;v zG_6$%_lI$fx(uN%)?`5LFlpA<jYFADfNyWL+`1SxO|n`A6XNBa0amBOLz9yU{x`uR z<u8zm>%0{iWs15>Yi}imj`3|pF0fF@ll!M#6CmdK1x-bIlVMhO&Ap{9=N$a!sErLN z(|Ed1Rc!^4ig|(qRARoc6ziRt+zS1DOkmD2{|V2s$ZP_hT$;n+fg#__j`z~8?@4eG z()cA4WBAO7Iq}S>)#^6PXGOC2u%>SlCl^?VRyzLS%JkPFYs{M-&7+sCV0F3EM(2{~ z)ZTg)r#!FE4QxASrUc?0>ifOwSMs1;q=am*QeCeY?hi*xN0C|7;Km@Y`xROZAV}t~ zrut2RjXJ=>JtLm??G_py7^!K|hPky;a30#T#zeyF6xtQyf_XL%u3^w{`a_cRh)2Aq z@@Q)-PuT8D1Z;6|aPXdryo<noQX3+TMaOrrzv6F#iQS{`1EgZUyr_q%3jq-sQc_a! z^eWP#A=tqCqR4~>TD`A-Ocp1(*J_(`n2zKabcgdV+4@BoF0b0@5d>egOR+D(fDbWo zaEx@BD8$~X!qim&_W@62Nx*${j}neC;MuUF{DmKYpr3p_T)jK^Efoz-Y;v-hF7@Tm z;2<gs3riHKfcV~2>2UETzgDFI5+F3bLwyj9NUlXiMH{zx$2O0eLUD9}<@t@gM3ry% zexdL$_YS~x(h?dfs$}r}8gKX`5NMesP{qC#@Q)Z&&zgNNz|?M7F486^T&A_1sd!L4 zDP3zZIdmUo@stbboP+Y<@6HZ@5J2b%P#{1!0BR=CNbJXt?fr4I!^KotNRJ+^?Cll5 z10D{~0T_pZLM(>Q4Dc}yocaRv>+}M?<<+UVW6Zq|P8*S&oczyQoCgqeRjoQJ^RizD zqTf4neiaAhK6>@qWYqhP|5K>`4&-zAqeQ0(kB6t;(&s)OK2X-sQlF~-S=A;qLXVT0 zdNY;mU%M<ec>Z=SB8f{&4|MCDYX0><-upPI-%AY1Z@l&EAN{}i`hI=ze^lk(SBs7i z()HjqASao$>Nuwv?Djp|a@4k;3D)i~G(ys*|K6;6PZdc;4(J|qf1zbw+e@*QUZvsg zv&3+>yN|A{tZd%d29vs+$##i?8?4Q@%4y<(Jh9JvbG(5SQ*o$zQ&mH9G3fWOs(U)v zkYTrxDFpr8+*xQza-S5#bTn~z!OW~I>A^KRNUuJ;`M#a|{D$`fSr^`OyJh^hR&!mM z!>AX#{sUIYt;y>yj^4jh1vBQR+7WgryK43|J*D~TXCGJwxN$mM+5=H4b7a;#^gq<~ zb~nm%E^if#O_0Gex)iKlKq?MHCA_x5kz0a?u?4;<*Z@TswBnjAm_EW5CVFj-$}2Cy zv06Fuy<FS>>0}z_xe{;F2qG^p+|ZZ)+%s@AYgZ!a{3WN&6nJ`z{H0K|oH6V>{?1|z zasq?eXU&Y~$Z|6Q&)R{tZ^NTpxr6Zc1?pfe<krD}Ke#7)a%BVvIy?jC-{mX02Uygu z9bzOo$oiMx6Z)?r8B=3)>9FLneG49p-5eZNVNW@k_G);ZrwixE7NmtdRaNF;(eF-q z-r1N0hhd{3cEz;cBpt4=Uo-(>P~Q8xe2G1Zlx`~`zHuI(HKjM$*N!s!KwwG@_B@(u z-JAFVoEPqx<dNEPCwHaB)0vB3%dUd9ZJ7N1GyZ6Mw%w5hhMw-1?k{s^B}oUJ^nE*; zwM3VlfUj0xXX@!k@@Q08i_BB%X5U2gy8G-Zj??n~Yp>FuqXNhz!yJ12&aqHFj$xIm z(<y-?keAmb;L;o{-vIHMtL{T-!(fkdJ|yYuCLG>K=M9}0tbqS0II`}jeJ_wnycB~t zkylO4)Dmt9ZgOXxK|w@Zo;olmxx=_iuLxWXPvi1$A->aJ-r>}~EgGwFkz$OBdn>CU zdKRMl1vF_uK!&?>HonfOEfD06!a-YXPD}$Ggfk1?y^$DzXdOR(x)~I*TVd7XfW<L+ zpSb?-64S|8PN~9Timo_(*A}adRE*b#a1*OwC&;!3&5Gja<;~QN`s6SLHYVE)e9Y^< zzjmv})a`vd(r5gPN4pd-lo1XOfCSJX(9AQz#og&oQqi;*7H3i<=W!$gPd4e}Aq_FX zzRx#>6zoplZs|?BP(^h?9o;|cpla5biGuN7o?cv#FDQ*T^awWo7ET6CmvEeu7UgQg zGE?|n!Uny%bLn){)KYPZFi&xzGbzCm^%EzNukgU6L*G;{JCXc{(n=J)c#QGQoA$yP z&FM1-iV;U%ei&KsfJhf#X=Gkrf+TwuRl9Wl_Kuv_(nuygiZX@l@yrv^qlu*^XS=8} zLn2m}o4NyAGp&EI<FDU1CWP5)<y1{OzK+CYTg)z}yX~Qh!(l$otl2)GuGR~qScP6p zj&(yapK~7crn<GdZyYzm=Mr`4wQ(L!eB^hoFO5B6c~RiYZg$7?+cfv;DaTj+$cMu5 zjH{8w-QnGjb0(}yXQ2luvdd`^>o*U!A}+(9b?7@WCAnAY5HI%oVNJMu4m~{2xVMGY z=M#UbosNM&m;8GleGcYoRwt7rbhYPd%?-<9a}RZz+KoS3^o&OQOy6Ku?+&7e$s0}O zlk%PqQ#utWhZV_rvfuP}EjUO>NUM84@!s|fc85y>=|&4329-;!uU;+-E<RT~kx7|V zs5+dd-O(;*$7Ptzg}rqR_P*gg(_xG!z95IYN(hp>lu8Bdk`j_m$CbA>WDRVUx|EI{ zlZ)h^9J>Bc<O%&$6#0Yy)VD<F><C)>r(XEiRq5h=u~Lx6MBX=uXSpm){a~SGx|<)6 ziAtr?35;3OMLPMukrv*288Gw7GUdckj=ylO$74c5LMdPy%kbHs+U2jSO+gqa+I0JH zacd1+q*B;<iy>seJaTekU|_&rD)EnJ;1}&AO*D{-x1^l^4t)L9%GbC5S?#}LMqdni zmRwz2B=7y5X8c!!3ph$jN<(6^D8;3kwd_EU^Y4XjT(wL)#kiuV@LxNz{_6ApXCWga zPgD<N+$<7Nd#Df%WBuoEcrNGl%cz3n23Aq%F7r`wr&(wwo2ytSp#SVt21bSkf~tCe zO2|JE-uv^2&)FS9nVPf>S!?}a=%PdC#%|&0nr(YgwnNF;uLDMk_C|&UYuTj;1>m}z z3>3SXfC##22-V?E-5kvi&+wMJv`}1Qt;*b})mp3z8KVmW2C2voqXcYq-A@L}*UviL z<JK>MnD2iIlJ21aWj2M1Q0Yt@hQq~Azdrlebvl=YaFs6+_8O2B#ng{aVfMb=T2C64 zTGA4cKv^~)5=#1J<3vub2G9jvjtK_VY@U<ehhG0(3}OfMYDrWCg(_%!?Ps{NBuv%q z!EVt^b?YQDweLo%AKJ|DdO4vX;=k|l4HxJ({hqBgRBlz70%8>4Mkl}Z>p(5WV(muE zBCIuQ^61Q^Q@5_XA;Ol<*vV{Appz=4?z(vS60@R`i~CVDq4kfJ2KEOWbI|Y0uF5<M z;BoMhQ3BI?ZMnldNz;W}j6lzZ@J;e=d*a0tYZ_vLI6=r>dyr!0tc{k9#w(Bwr$~*i zs1sN;eifn3HtXvHl$Du*=rJ90!D6bVxW(gi)u4}k7#fLdecg3@yw0aOS1cuB5Icnh zn(KEix@y5k%i`hg*j4dwPNSO4MOZ@H=?)v@=%j|lFraN0)hQOUqbwV>xe3seHHEWW z7B(Kf`Yx05y3q&MPsN8^I`~UbF(j7X1Qm84r(yT_uEjA6UJ7c#p5+fNjN@eOM@`qf z*ky4K3I#jj(N?%@chzK&zOL-=rn^?N74JS6*t~w2W4)E1{BBpCCF&Z-m!72|4I`SA zy55ud@1X#0f@BT@R2B+;sE|=^zOXmtId%=tsNpEqNOOzFMn}bMrq>e@O7vk6hi*fN z7C=XT=+f`??~=mCP1k{)8f<wqUXnB6F*mU*;>Gl%C$hP9I0~UgX^1PFCp@PcO9wKN zP~YV3qF_A{C?5tR`AA9pDb9$G4@M$Z{aAZlI?H)Rwr?&?x&V}^ElZmEK(lW6l~{D+ zGSu({v!;?reW3|zaYBB{wxJb_)UahS?=br5ZOT$j)f?$fer^GTUR~9U(0rF5Q$lRP zOrAlHYV*5S!B!e#7E$wCFJ9^srs>R`*tOiTe}=vz%3(BGm@~bg<Kvl6?5tZau0&br zD(Jae2hUkoX5A#}k7Z$cLU&xyNiV|1$m;FY{AfL+BUa&&6Jet_Z!{XGgi$K;%k<;U zUM>}n5lw&HX|6LyhWf4FlndeuMdgaCEtx}6mpQ#sZOG`-U4W(P5SWl``Pp*C(p(I! z#o`|s@sNnH{Vq#d2aYEvQYIxwBewz+_6)az<llYcJ+^7t9J=-3Nd;!VYg`}@%ecZK z_lufXNmSRqaAPK^uAG_P*XQp0&uNb-`X-{EdA1qLrJ|5p`1V_>92uJh))Q{*=uN}3 zG!hM`;s@qhmMgf216`hNvA6VVMcDBA&t~*un>-k&xNupvA<@M+kt@DCmS69eEm3_I z>$5#inLh#QERY$s!1&fZ7+wq#306CNEf(dt;q`Q{+<ZP<x#{!;vYM3wE-C@D^W#$9 z<PKbvZ#@&SP1b{`V3t-@M2R``5ncot%O0nQje2pG<9FXO1T|qVH8rjFMQWqEqDbnV zp>7u4h|11Gn-y=#4hv2xMiW^=y79VFC-6gTbp2^t(z+{hE(HXYFXfS^2>M@;<11l* znRS~r1HqJRIcmFUWzBA%+%Axi2(TyB^0k&<e%tobKNy-gBR8^(6y@Y0Ntc=H!bDk- zeA)fryk?z5$}wNM5XD_&1Mvz%*sh;<kkX-;jX7F>6B)hhE9ExfA8%*1dMz~QKvKIa znbJLtg6_B7;`Pmq7pCGKb2nubV!4au6F%=~{=H~5s2+^e)g7{y3T(yvr{ugF1V(A) zNQF=Yz2fwESsjr~zhaqfibS`Ujs9IB0SUh=0r7TnTPyN|RrrO%QO|Z5_kJPZo=Bbe zAt?|tO4?}?|K+por3|rggC5d89SWb7quyDG6c?%=@nm!H%A2PlqZtj)jWj9<@EDQx z)GLVa7-uAF^R?IObTkg@m@xLAP|c7KFblg8>nZ5=_ZFuq`V<L}DTl9fnDU|?tW;!B zZdWEqSqUAJe0F?D#|<ISRYv?#=P1J6%QrIXP`P|AG&H}Ebv4mqm$feiJ;rOs%?j_b zkD~JIIeB&iR-=60o(mipQ^KpH;6UG-G#V|8(zO;?kAwy$E<;|a&__Xw7HwYsL6*v& z$ZBG3t2x5_N4FSdO42?;FD5!o{wiycQgH(+f^N4ZmeEX@g76R|!n!~B){7)$AKfY} z3zL75{O%Z`s62W_kQ+TqU?_J8!nwIn>gEyO!85_|JFJq_j~mp(Ey+|V=zEz+zATpE zS5|}ms&~t9kXIgw9@jB9UV@I%Z2|%(!K(#1nVVk=FY2(MO;<OpNBIjKFovZB@Sx@j z4d~gE7%O*vmeJ1vlJ8YCB;-a+wkOtP=(za3cgdKQBeIEyJ|5DiWrWPvkq{Cf`vng2 z+|Jbv4|Rl5a%h+%@+{|l=TOq9JyTo?pAVHO9J}$@qe!grNYs<@Sd^KMIjiG~_1z3| z##T?&PCyCh3Nvf_c$df$gv35MC_lbB?QS$L=+dw}LR$(qu)jWXuV?`8%%ZPh!|a~E zux4qBJ0K`~aIt++r#mW)@=89=Vi|jK4@aVjX*0y)Op+JQR(`M;HT+6W1A`&hkY|1* zulJLbX+3bjO~+_9S~t5cMcVr0nriTPus;~~hu899)q3IWL!Tnm=+go`)_?{UBhr{> z{A)ftJHIOdrN^7;3OagBszKp+#Qo>voad-t^j|A$TlcT1#=KDDNmXqQ>6v<)cm&5# zj<(gCC{%g7e}_ToT1LS{X;l6FOJ+T;)|zee?Wmep{Wgk8mT(}VTB=%O7R{6q-tA(> zJWq4~d|L3hYloq1H6n8cM5F*qeC-jL_8Din&5zMr0oON`@C8s$Z%wXA89?@Q0&2Q- zn{FQ)<}BN^_OC)Bl~nyck@JZi@(Uf)5LaX3fNY;FR@{c-9@6)$?JvBgL3e8}KU^eI zLpP-BQbIaR>aE4Es-Ic96CrVC2RoxMtW^_<d1i7oWo}gd=p9dTR)9Kt&2_g=b+@3u zggYNA=t{jGH+DoY6}<kjw}5+#)kT?Q?C>=H6|QtONp#8H?DlI--cd$RKehTh*|(h? zs4&&q6&w5RPn_Niu$&K+!5G=dKRfei8?0~3NjNOn8kC3^*mWt>)^TBE3u>)s=he!D z^`;NTo)BwzS|KmPPuSz)!tJ3S9d3p(h_ki|XZT14<YIv|82=O`)hOt+SfccMXoa3S z@%Yd*uEJd+XN6y_IyF7P$`((!dFk@%xxxIU`{0RS(<LPhnShkaUE_rjm7F+YFgJ-< z!L-I!FZ!lG7sko?YBn!|T3gJAdLOWWH<m`ty4=zn8~BgzG^JsLW9phQ+1An}qP;L^ z#4H5sA-Q2^>H3e&L`U}2V(Y=Mu?UGhA<1F`iIln>MKbl1$DnlCmMv=;Q`(pM%*xS+ zJsf(^%j-4!)HbCJR-^|tLB~q7L?jEdk#oLh8(kah@7Z9Q-18<47%R6lf0*g(^i^DP zJqgPMPZm?DPE5QEItXbqxhaG0433ni_)Z0zrtn-;d3X-cG)wJ4<OmvQ!(J$yR5QiX ziF`;j^<8bsrhTPm@o1TIADmUFs#<26Wf=dZ#F(S4SGemoCeZz`osLNLDzq|z!LZ}a zY&eLc8hXnqn>OlOFK-klgP)0-GBQui9HrLM3Dpdr58VE#bM{;*3Z9h2)7+;e(0SQA z7r!#NOx`PH5Y3`DR@lNP&+@Ouvp<IhY5wj3aS>P}&Ci1h0Vq;p@^8!D=mq>Q437eS literal 0 HcmV?d00001 diff --git a/doc/images/tutorials/history_panel/11.png b/doc/images/tutorials/history_panel/11.png new file mode 100644 index 0000000000000000000000000000000000000000..879b96ebe796e1ab331982773858153da242f45a GIT binary patch literal 822606 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�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�!wp8OLL!bz&m9Xq#YEw>d}rOS19(Ai9@^T&ZZR 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ᓉA?ed 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�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� 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%0DQ2@g1Yt8#+>FX4$ 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�K;7!N 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/MlVUKvy!~w(mc(% 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 literal 0 HcmV?d00001 diff --git a/doc/images/tutorials/history_panel/12.png b/doc/images/tutorials/history_panel/12.png new file mode 100644 index 0000000000000000000000000000000000000000..5b86f0c2fa6cbf347591f4aba2526e68ac63e14e GIT binary patch literal 248002 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�-Hdt;Ts?c~qq={WqJB%d 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℞dISo=QlVsCiom8$OIQH$(E*V}ipT!}(ji4us0P zkh+FA<%zjSc=uy{+R!2Na7_%^NMrhao)DG2l>F_Lv4Aou``v~3!0_+(3Qjy0e7s6< zl4?@RU=L%mHQIRM)U|ur8mG&T*criB>PQ>`-m41tqY{ZIxAe>FiC;>vZij<w7#WFX zI+SbH$3VC{#GeNGZf}kJ=HTl4W$mZ_`nwwUpEa|66I6#p+Tm`)D(C3?kwy!rRJ{Kh zIOgqW>4;hEpNLVC{iaXq<=ELQ6p@@i1i}1VtVq0k_Kzd@NLgrG)4N@ef)JZiw|#5! z4<$omuN_cdNXR#-pL>`C`XFS)L5tzO;@z>krXF!<>hbe^xw4wGDBSxr6L(kqpw>pl zT~8|Q67uS?aCa$D9Z6q;Z&-4%v;ElY>7dVRw%?nNYAMQb%Pr`Q*Wx<&nv}Q)ZO$Pt z)})EKO7snGyFM04DRYpOMZiPq#nRV2tL3&kyxP@`s#ks~GyP|U(JIzh78Uu4vN;RP z{w`h=Oe>~-_PxuH)^13M4}LQoU8rB_3amaGz}dLRfe%YdP7kMeczNfy`sSZ=iXw}x z<Q1QnDlNaBSoye6?`DwLG#x#G6BVxL$gAy=%h^zUA{5vH8h*C2SX2(xLsD19Hs<@W z%PIeHN&a5BU7g#?@_;3YH`roWM=M5V#hvK(8b32T+w96k8J3!S``O1OMo3ve#_{#P z%AS6?d{PBR5s^m#o!GO|L1V#%W-InYqyO<+xN74VhfpW+tkG8bsRw}L)=hn_;v3el F{tw#^G@}3j literal 0 HcmV?d00001 diff --git a/doc/intro/tutorials/history_panel.rst b/doc/intro/tutorials/history_panel.rst index 73cf98e55..24a644042 100644 --- a/doc/intro/tutorials/history_panel.rst +++ b/doc/intro/tutorials/history_panel.rst @@ -165,9 +165,51 @@ level, while the original **Processing** session remains unchanged. The selected noise action in **Processing Copy** uses ``sigma = 0.05``. The original chain and the modified copy remain available side by side. -This can be useful to compare the effect of the noise level on the fitting result, or -to explore other processing variants. In this example, selecting both the original and -copied fitting signals in the Signal Panel we can see that there is a difference between -them, but is quite slight. +This can be useful to compare the effect of the noise level on the fitting +result, or to explore other processing variants. In this example, selecting both +the original and copied fitting signals in the Signal Panel shows a difference +between them, but it is quite slight. +Recording an image-to-signal workflow +------------------------------------- +The History Panel records workflows across both data panels in the same session. +Unlike the Signal Panel and Image Panel, it is not divided by data type: its +chronological tree shows image operations and any signals that they produce +together. + +To illustrate this behavior, we will start from a clean workspace. Alternatively, +click **New session** in the History Panel to record it in a new session of your +current workspace. + +In both cases, activate the history recording and switch to the **Image Panel**. + +Create or open a test image and apply a first noise-reduction operation, for +example **Processing > Noise reduction > Moving Average**. As you can see, for +images the history is recorded at the same way that it is for signals. + +.. figure:: ../../images/tutorials/history_panel/10.png + + The new image and its moving-average result are recorded in the same + History Panel session. + +Select the filtered image and choose **Processing > Intensity profiles > Line +profile...**. Set the horizontal line in the profile dialog, then +confirm it. DataLab adds the extracted profile to the Signal Panel, while the +History Panel appends the **Line profile** action to the same session after the +image-processing actions. + +.. figure:: ../../images/tutorials/history_panel/11.png + + Choose the horizontal line used to extract the profile from the filtered + image. + +This single history session therefore captures the full workflow: image +creation, noise reduction, and conversion of image data into a signal. Selecting +the image actions in the History Panel activates the Image Panel; selecting the +profile action activates the Signal Panel and selects the resulting signal. + +.. figure:: ../../images/tutorials/history_panel/12.png + + The History Panel records the image operations and the resulting signal in + one chronological session. From 7d05a7740c0de0e589fbcabdfc0207ef9616166d Mon Sep 17 00:00:00 2001 From: Stefano Pierini <s.pierini@codra.fr> Date: Fri, 14 Aug 2026 15:02:43 +0200 Subject: [PATCH 099/108] Doc: History panel: improve formatting of tutorial content --- doc/intro/tutorials/history_panel.rst | 70 ++++++++++++++++----------- 1 file changed, 41 insertions(+), 29 deletions(-) diff --git a/doc/intro/tutorials/history_panel.rst b/doc/intro/tutorials/history_panel.rst index 24a644042..1a29adb86 100644 --- a/doc/intro/tutorials/history_panel.rst +++ b/doc/intro/tutorials/history_panel.rst @@ -4,8 +4,11 @@ ========================================================================== .. meta:: - :description: Tutorial on how to record, replay and share a processing chain with the History Panel of DataLab, the open-source scientific data analysis and visualization platform - :keywords: DataLab, tutorial, history, record, replay, session, reproducibility, processing chain, dlhist, HDF5 + :description: Tutorial on how to record, replay and share a processing + chain with the History Panel of DataLab, the open-source scientific + data analysis and visualization platform + :keywords: DataLab, tutorial, history, record, replay, session, + reproducibility, processing chain, dlhist, HDF5 This tutorial shows how to use the **History Panel** to make a processing workflow reproducible: @@ -24,8 +27,9 @@ workflow reproducible: Showing the History Panel ------------------------- -The History Panel is visible by default, but could be hidden in your configuration. - In this case, to display it, check the "History Panel" entry in the "View" menu. +The History Panel is visible by default, but could be hidden in your +configuration. In this case, to display it, check the "History Panel" entry in +the "View" menu. .. figure:: ../../images/tutorials/history_panel/01.png @@ -45,8 +49,9 @@ workspace state tables at the bottom ("Signal" / "Shape" on the left, Like the other panels of DataLab, the History Panel is dockable: it can be moved to any side of the main window, or detached as a floating window. Here, it is docked on the left side, next to the Signal Panel, so that the recorded -actions remain visible while working on the data. We use this configuration in the rest - of the tutorial, but you can choose any layout that suits your workflow. +actions remain visible while working on the data. We use this configuration in +the rest of the tutorial, but you can choose any layout that suits your +workflow. .. figure:: ../../images/tutorials/history_panel/03.png @@ -88,9 +93,9 @@ Signal Panel shows both the original and resulting signals, while the Processing Parameters panel displays the seed, mean and standard deviation used for the selected action. -To create a longer chain, we can apply a few more processing steps, for example a -fitting. Once done, the action is recorded in the History Panel, and the resulting -signal is displayed in the Signal Panel. +To create a longer chain, we can apply a few more processing steps, for example +a fitting. Once done, the action is recorded in the History Panel, and the +resulting signal is displayed in the Signal Panel. .. figure:: ../../images/tutorials/history_panel/05.png @@ -99,30 +104,34 @@ signal is displayed in the Signal Panel. Familiarizing with the history panel commands --------------------------------------------- -Now we have a very simple processing chain, which is enough to illustrate the main -features of the History Panel. +Now we have a very simple processing chain, which is enough to illustrate the +main features of the History Panel. The toolbar provides the following commands: - **Record mode** toggles the recording of subsequent actions. - **New session** starts a separate history session. - **Open history file** and **Save history file** load or save a standalone ``.dlhist`` history file. -- **Previous step** and **Next step** select the adjacent action in the current - session. +- **Previous step** and **Next step** select the adjacent action in the + current session. - **Replay** applies the selected session or action without showing parameter dialogs, whereas **Step-by-step** replays it while allowing parameters to be edited at each step. - **Duplicate** copies the selected session, or the complete session containing the selected action, to compare a processing variant. -- **Remove incompatible** removes actions that cannot be directly applied in the - current workspace (i.e. because a signal has been deleted), and **Delete** removes - the selected history entry. +- **Remove incompatible** removes actions that cannot be directly applied in + the current workspace (i.e. because a signal has been deleted), and + **Delete** removes the selected history entry. -When an action is selected in the tree, the corresponding resulting signal is displayed -in the Signal Panel. +When an action is selected in the tree, the corresponding resulting signal is +displayed in the Signal Panel. -Now select the fitting signal in the signal panel, and delete it using the "Delete" -button in the toolbar or pressing the "Delete" key. The fitting action is still available in the History Panel, as it can be replayed using the **Replay** button. In addition the delete action has been recorded in the history, but it is grayed: the reason it that the fitting signal has been deleted, so the action cannot be directly applied in the current workspace. +Now select the fitting signal in the Signal Panel, and delete it using the +"Delete" button in the toolbar or pressing the "Delete" key. The fitting action +is still available in the History Panel, as it can be replayed using the +**Replay** button. In addition, the delete action has been recorded in the +history, but it is grayed: the reason is that the fitting signal has been +deleted, so the action cannot be directly applied in the current workspace. .. figure:: ../../images/tutorials/history_panel/06.png @@ -130,7 +139,9 @@ button in the toolbar or pressing the "Delete" key. The fitting action is still action and the recorded deletion are grayed in the History Panel because they cannot be replayed in the current workspace. -We can now replay the fitting action: the resulting signal is recreated in the signal panel and the "delete" action is no longer grayed, as it can now be applied to the newly created signal. +We can now replay the fitting action: the resulting signal is recreated in the +Signal Panel and the "delete" action is no longer grayed, as it can now be +applied to the newly created signal. .. figure:: ../../images/tutorials/history_panel/07.png @@ -142,11 +153,12 @@ We can now replay the fitting action: the resulting signal is recreated in the s Duplicating the chain to compare variants ----------------------------------------- -We can now duplicate the chain to compare two processing variants. First of all, delete the "Remove selected objects" history record using the delete key. Then Select the -**Processing** session in the History Panel and click **Duplicate**. DataLab -creates a new **Processing Copy** session and a ``Copy - Processing`` group in -the Signal Panel. This group contains independent copies of the signals used -and produced by the original chain. +We can now duplicate the chain to compare two processing variants. First of all, +delete the "Remove selected objects" history record using the Delete key. Then +select the **Processing** session in the History Panel and click **Duplicate**. +DataLab creates a new **Processing Copy** session and a ``Copy - Processing`` +group in the Signal Panel. This group contains independent copies of the signals +used and produced by the original chain. .. figure:: ../../images/tutorials/history_panel/08.png @@ -178,9 +190,9 @@ Unlike the Signal Panel and Image Panel, it is not divided by data type: its chronological tree shows image operations and any signals that they produce together. -To illustrate this behavior, we will start from a clean workspace. Alternatively, -click **New session** in the History Panel to record it in a new session of your -current workspace. +To illustrate this behavior, we will start from a clean workspace. +Alternatively, click **New session** in the History Panel to record it in a new +session of your current workspace. In both cases, activate the history recording and switch to the **Image Panel**. From d7e94421bb6363809f19b23922e36a6dfa87a7ff Mon Sep 17 00:00:00 2001 From: Stefano Pierini <s.pierini@codra.fr> Date: Fri, 14 Aug 2026 15:36:42 +0200 Subject: [PATCH 100/108] Doc: History panel: update menu path for intensity profiles in tutorial --- doc/intro/tutorials/history_panel.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/intro/tutorials/history_panel.rst b/doc/intro/tutorials/history_panel.rst index 1a29adb86..895f161da 100644 --- a/doc/intro/tutorials/history_panel.rst +++ b/doc/intro/tutorials/history_panel.rst @@ -205,7 +205,7 @@ images the history is recorded at the same way that it is for signals. The new image and its moving-average result are recorded in the same History Panel session. -Select the filtered image and choose **Processing > Intensity profiles > Line +Select the filtered image and choose **Analysis > Intensity profiles > Line profile...**. Set the horizontal line in the profile dialog, then confirm it. DataLab adds the extracted profile to the Signal Panel, while the History Panel appends the **Line profile** action to the same session after the From ea0b3bd3a2ea723823ea8e72382391d245d63b47 Mon Sep 17 00:00:00 2001 From: Stefano Pierini <s.pierini@codra.fr> Date: Fri, 14 Aug 2026 15:37:52 +0200 Subject: [PATCH 101/108] Doc: Tutorial History panel: update obsolete text --- doc/intro/tutorials/laser_beam.rst | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/doc/intro/tutorials/laser_beam.rst b/doc/intro/tutorials/laser_beam.rst index ecc6f3a1d..da6b02875 100644 --- a/doc/intro/tutorials/laser_beam.rst +++ b/doc/intro/tutorials/laser_beam.rst @@ -93,8 +93,7 @@ To pan the image, use the middle mouse button while dragging. Both the "Distribute on a grid" and "Reset image positions" options modify the images in place, without creating new images. For this - reason, they are not registered in the History Panel, which only - lists newly created objects. + reason, these operations are not recorded in the History Panel. .. |distribute_on_grid| image:: ../../../datalab/data/icons/processing/distribute_on_grid.svg :width: 24px @@ -174,15 +173,9 @@ selected both signals for comparison. .. note:: - If history recording is enabled, creating a new signal starts a new history - session, separate from the session containing the image operations. Since - extracting the intensity profile is an operation performed on an image, the - new session starts with the Gaussian fit applied to the resulting signal. - - .. figure:: ../../images/tutorials/laser_beam/07.png - - The image-processing actions are recorded in the first session, while - the Gaussian fit starts a separate session for the resulting signal. + If history recording is enabled, the image-processing actions, extracted + profile, and Gaussian fit are recorded in the same active history session. + See :ref:`tutorial_history_panel` for a cross-panel workflow example. From cce09f4190d091607a9a45907c440885790f9148 Mon Sep 17 00:00:00 2001 From: Stefano Pierini <s.pierini@codra.fr> Date: Fri, 14 Aug 2026 15:39:20 +0200 Subject: [PATCH 102/108] Doc: history panel - update obsolete documentation --- doc/features/common/overview.rst | 7 +++---- doc/features/common/settings.rst | 5 ++--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/doc/features/common/overview.rst b/doc/features/common/overview.rst index db73472ad..5263560c6 100644 --- a/doc/features/common/overview.rst +++ b/doc/features/common/overview.rst @@ -31,10 +31,9 @@ History Panel ^^^^^^^^^^^^^ The :ref:`historypanel` is an additional dockable panel that records signal -and image actions into separate active sessions for each data panel. It -supports replay, step-by-step replay, duplication, and compatibility -diagnostics. Sessions may be saved in standalone ``.dlhist`` files or with -the workspace in HDF5 format. +and image actions in a shared active session. It supports replay, step-by-step +replay, duplication, and compatibility diagnostics. Sessions may be saved in +standalone ``.dlhist`` files or with the workspace in HDF5 format. Internal data model and workspace --------------------------------- diff --git a/doc/features/common/settings.rst b/doc/features/common/settings.rst index fd353ad53..d4dc9485b 100644 --- a/doc/features/common/settings.rst +++ b/doc/features/common/settings.rst @@ -144,9 +144,8 @@ History sessions ^^^^^^^^^^^^^^^^ These settings control how new inputs are assigned to history sessions. They -are evaluated only when **Record mode** is enabled and the target Signals or -Images panel has a populated active session. No policy decision is needed when -the active session is empty. The two data panels keep separate active sessions; +are evaluated only when **Record mode** is enabled and the shared active session +contains actions. No policy decision is needed when the active session is empty; see :ref:`historypanel` for the complete workflow. **New object or file** From 6aef4bea353fecd63b38c92cd9fc31797c1f6bd3 Mon Sep 17 00:00:00 2001 From: Duy Anh Philippe PHAM <d.pham@codra.fr> Date: Fri, 14 Aug 2026 16:12:09 +0200 Subject: [PATCH 103/108] Tests: History panel: provide busy-state stubs required by the re-entrance guards --- datalab/locale/fr/LC_MESSAGES/datalab.po | 1 - datalab/tests/features/common/history_panel_test.py | 8 +++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/datalab/locale/fr/LC_MESSAGES/datalab.po b/datalab/locale/fr/LC_MESSAGES/datalab.po index b2c02981f..5681f2dc5 100644 --- a/datalab/locale/fr/LC_MESSAGES/datalab.po +++ b/datalab/locale/fr/LC_MESSAGES/datalab.po @@ -4527,4 +4527,3 @@ msgstr "Image" msgid "Dimensions" msgstr "Dimensions" - diff --git a/datalab/tests/features/common/history_panel_test.py b/datalab/tests/features/common/history_panel_test.py index e57b34dee..4e1b7f5e1 100644 --- a/datalab/tests/features/common/history_panel_test.py +++ b/datalab/tests/features/common/history_panel_test.py @@ -61,7 +61,13 @@ def test_history_tree_double_click_replays_current_selection_without_restoring( refresh_compatibility_items=Mock(), replaying=nullcontext, output_suppressed=nullcontext, - runtime=SimpleNamespace(execution=SimpleNamespace(edit_mode=False)), + runtime=SimpleNamespace( + execution=SimpleNamespace( + edit_mode=False, + is_busy=lambda: False, + is_engine_busy=lambda: False, + ) + ), navigation=SimpleNamespace( sync_panel_selection=Mock(), update_state_widget=Mock(), From 4520b04587138f36423d7135acc8cb27736899a3 Mon Sep 17 00:00:00 2001 From: Stefano Pierini <s.pierini@codra.fr> Date: Fri, 14 Aug 2026 16:26:09 +0200 Subject: [PATCH 104/108] Update French translations for tutorials and release notes - Enhanced the French translation for the laser beam tutorial, improving clarity and accuracy in descriptions of measuring techniques and tools used in DataLab. - Revised the release notes for version 1.03, adding details about new features such as history panel sessions, special values processing, and improved user feedback mechanisms. - Included updates on bug fixes related to history panel functionality, ensuring a smoother user experience and better handling of edge cases. --- .../features/common/historypanel.po | 135 +++- .../LC_MESSAGES/features/common/overview.po | 311 ++++++-- .../LC_MESSAGES/features/common/settings.po | 714 ++++++++++++++---- .../fr/LC_MESSAGES/intro/tutorials/blobs.po | 353 ++++++--- .../LC_MESSAGES/intro/tutorials/laser_beam.po | 309 +++++--- .../LC_MESSAGES/release_notes/release_1.03.po | 260 +++++-- 6 files changed, 1614 insertions(+), 468 deletions(-) diff --git a/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po b/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po index d0198e70b..4d680b3c5 100644 --- a/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po +++ b/doc/locale/fr/LC_MESSAGES/features/common/historypanel.po @@ -5,9 +5,6 @@ # msgid "" msgstr "" -"POT-Creation-Date: 2026-08-06 09:11+0200\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -184,15 +181,13 @@ msgstr "" "n'ajoute aucune nouvelle entrée." msgid "" -"The Signals and Images panels each have their own active session. New " -"actions are added to the active session of the data panel they concern, " -"so switching between signals and images does not mix their recording " -"contexts." +"There is a single active recording session, shared by the Signals and " +"Images panels. New actions from both panels are chained into that session" +" (one is created on first use), so mixed signal/image pipelines are " +"recorded together and recording resumes in the user-selected session. " +"Each session remains associated with the Signals or Images panel for " +"display purposes, through the actions it contains." msgstr "" -"Les panneaux Signaux et Images disposent chacun de leur propre session " -"active. Les nouvelles actions sont ajoutées à la session active du " -"panneau de données concerné ; ainsi, le passage des signaux aux images ne" -" mélange pas leurs contextes d'enregistrement." msgid "" "When a new object is created or a file is loaded into a populated active " @@ -239,9 +234,10 @@ msgstr "" msgid "record" msgstr "record" +#, fuzzy msgid "" -"|new_session| **New session**: start a new active history session for the" -" current data panel." +"|new_session| **New session**: start a new history session and make it " +"the active recording session." msgstr "" "|new_session| **Nouvelle session** : démarre une nouvelle session " "d'historique active pour le panneau de données actuel." @@ -289,6 +285,7 @@ msgstr "" msgid "step_next" msgstr "step_next" +#, fuzzy msgid "" "|replay| **Replay**: recompute the selection in place, silently (no " "parameter dialogs). Selecting an action replays that action; selecting a " @@ -311,8 +308,14 @@ msgid "" "restored. Analyses recorded with earlier versions of DataLab replay using" " their saved state. UI actions are replayed by invoking their recorded " "method and may reproduce side effects, including creating, importing, or " -"duplicating objects; destructive actions are skipped when their captured " -"targets no longer resolve." +"duplicating objects; load actions reload their objects even if these were" +" deleted after being recorded. Recorded destructive actions (e.g. object " +"removals) are skipped with a warning whenever replaying them would be " +"unsafe: when their captured state no longer matches the current " +"workspace, when their targets were re-created earlier in the same replay," +" or when their targets belong to another session. As a consequence, a " +"replayed session may intentionally not reproduce a recorded end state " +"that included such deletions." msgstr "" "|replay| **Rejouer** : recalcule la sélection en place, silencieusement " "(sans boîtes de dialogue de paramètres). Sélectionner une action rejoue " @@ -338,10 +341,9 @@ msgstr "" "restaurés. Les analyses enregistrées avec des versions antérieures de " "DataLab sont rejouées à partir de leur état sauvegardé. Les actions de " "l'interface sont rejouées en invoquant leur méthode enregistrée et " -"peuvent reproduire des " -"effets, notamment créer, importer ou dupliquer des objets ; les actions " -"destructives sont ignorées lorsque leurs cibles capturées ne peuvent plus" -" être résolues." +"peuvent reproduire des effets, notamment créer, importer ou dupliquer des" +" objets ; les actions destructives sont ignorées lorsque leurs cibles " +"capturées ne peuvent plus être résolues." msgid "replay" msgstr "replay" @@ -367,11 +369,15 @@ msgstr "" msgid "step_by_step" msgstr "step_by_step" +#, fuzzy msgid "" "|duplicate| **Duplicate**: duplicate the processing chain containing each" " selected action, or the processing chains in each selected session. " "DataLab clones the required objects and creates independent history " -"sessions." +"sessions. The duplicate is a standalone deep copy of the chain — as if " +"the recorded operations had been redone by hand on the cloned objects — " +"so replaying either the original or the duplicated session only affects " +"its own objects." msgstr "" "|duplicate| **Dupliquer** : duplique la chaîne de traitement contenant " "chaque action sélectionnée, ou les chaînes de traitement de chaque " @@ -394,10 +400,13 @@ msgstr "" msgid "remove_incompatible" msgstr "remove_incompatible" +#, fuzzy msgid "" "|delete| **Delete**: remove the selected actions or sessions from the " -"history. Removing an intermediate action splices it out and preserves its" -" downstream steps as an independent chain." +"history (keyboard shortcut: :kbd:`Del`, active only while the history " +"tree has focus, so it never deletes signal or image objects instead). " +"Removing an intermediate action splices it out and preserves its " +"downstream steps as an independent chain." msgstr "" "|delete| **Supprimer** : retire de l'historique les actions ou sessions " "sélectionnées. La suppression d'une action intermédiaire la retire de la " @@ -414,6 +423,13 @@ msgstr "" "pour la sélection courante, avec la même sémantique de recalcul en place " "que celle documentée ci-dessus." +msgid "" +"While a replay or recompute is in progress, History Panel commands are " +"unavailable: the toolbar actions are disabled, and tree interactions " +"(context menu, double-click, :kbd:`Del` key) are ignored until the run " +"completes." +msgstr "" + msgid "Tree view" msgstr "Arborescence" @@ -422,10 +438,12 @@ msgstr "" "L'arborescence organise les actions enregistrées dans des sessions " "dépliables :" +#, fuzzy msgid "" -"Each top-level row is a **session** associated with the Signals or Images" -" panel. Sessions may be started when recording is enabled, with **New " -"session**, or according to the configured session policy." +"Each top-level row is a **session**; the panel(s) it relates to are " +"determined by the actions it contains. Sessions may be started when " +"recording is enabled, with **New session**, or according to the " +"configured session policy." msgstr "" "Chaque ligne de premier niveau est une **session** associée au panneau " "Signaux ou Images. Les sessions peuvent être démarrées lorsque " @@ -461,19 +479,21 @@ msgstr "" "; sinon, ses objets d'entrée existants sont sélectionnés. DataLab bascule" " ensuite vers ce panneau de données." +#, fuzzy msgid "" -"While Record mode is enabled, selecting a session row makes that session " -"active for its data panel." +"While Record mode is enabled, selecting a session row (or one of its " +"actions) makes that session the active recording session." msgstr "" "Lorsque le mode d'enregistrement est activé, sélectionner une ligne de " "session rend cette session active pour son panneau de données." +#, fuzzy msgid "" "Actions that are not compatible with the current workspace state (for " "example because a referenced object identifier no longer exists, or " "because its data array shape changed) are shown with a disabled " -"foreground and an explanatory tooltip. They cannot be replayed until the " -"workspace matches the recorded state again." +"foreground and an explanatory tooltip. Attempting to replay them opens " +"the broken chain resolution dialog described below." msgstr "" "Les actions qui ne sont pas compatibles avec l'état courant de l'espace " "de travail (par exemple parce qu'un identifiant d'objet référencé " @@ -482,6 +502,35 @@ msgstr "" "peuvent pas être rejouées tant que l'espace de travail ne correspond pas " "de nouveau à l'état enregistré." +msgid "" +"Actions left **outdated** by a failed or interrupted recompute, or by " +"parameter edits whose propagation to downstream steps is still pending, " +"are highlighted with an amber background and carry an explanatory " +"tooltip. Replaying them refreshes their result and clears the marker." +msgstr "" + +msgid "Broken chain resolution" +msgstr "" + +msgid "" +"Starting **Replay** or **Step-by-step** (or double-clicking a tree item) " +"on a selection containing actions that are incompatible with the current " +"workspace — typically because the objects they rely on were deleted — " +"opens a resolution dialog. Two choices are offered:" +msgstr "" + +msgid "" +"**Repair and continue**: the broken actions and all their downstream " +"descendants are removed from the history, then the remaining valid " +"actions of the selection are replayed." +msgstr "" + +msgid "" +"**Cancel**: nothing is modified, neither the history nor the workspace. " +"The dialog is shown again on the next replay attempt until the chain is " +"repaired." +msgstr "" + msgid "Workspace state display" msgstr "Affichage de l'état de l'espace de travail" @@ -566,6 +615,15 @@ msgstr "" " les collisions et ajoute les sessions d'historique importées qui " "référencent ces nouveaux identifiants." +msgid "" +"A history entry whose saved parameters can no longer be decoded (for " +"example a ROI payload written by an incompatible version of DataLab) does" +" not prevent the rest of the file from loading: the affected action is " +"loaded as incompatible — shown as a disabled row with an explanatory " +"tooltip, and never replayed — while all other sessions and actions load " +"normally. Such entries can be cleaned up with **Remove incompatible**." +msgstr "" + msgid "" "Replaying a session that depends on external files (e.g. opening a " "dataset from disk) will only succeed if those files are still available " @@ -755,3 +813,22 @@ msgstr "" #~ "gaussien, ...) dont l'exécution est " #~ "confiée à Sigima par les processeurs " #~ "de DataLab." + +#~ msgid "" +#~ "The Signals and Images panels each " +#~ "have their own active session. New " +#~ "actions are added to the active " +#~ "session of the data panel they " +#~ "concern, so switching between signals " +#~ "and images does not mix their " +#~ "recording contexts." +#~ msgstr "" +#~ "Les panneaux Signaux et Images disposent" +#~ " chacun de leur propre session " +#~ "active. Les nouvelles actions sont " +#~ "ajoutées à la session active du " +#~ "panneau de données concerné ; ainsi, " +#~ "le passage des signaux aux images " +#~ "ne mélange pas leurs contextes " +#~ "d'enregistrement." + diff --git a/doc/locale/fr/LC_MESSAGES/features/common/overview.po b/doc/locale/fr/LC_MESSAGES/features/common/overview.po index dd8d27008..abf463ead 100644 --- a/doc/locale/fr/LC_MESSAGES/features/common/overview.po +++ b/doc/locale/fr/LC_MESSAGES/features/common/overview.po @@ -3,21 +3,30 @@ # This file is distributed under the same license as the DataLab package. # FIRST AUTHOR <EMAIL@ADDRESS>, 2022. # -#, fuzzy msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" -"POT-Creation-Date: 2026-08-05 14:24+0200\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2026-08-14 15:47+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.18.0\n" -msgid "Overview and basic concepts of DataLab, the open-source scientific data analysis and visualization platform" -msgstr "Vue d'ensemble et concepts de base de DataLab, la plateforme open-source d'analyse et de visualisation de données scientifiques" +msgid "" +"Overview and basic concepts of DataLab, the open-source scientific data " +"analysis and visualization platform" +msgstr "" +"Vue d'ensemble et concepts de base de DataLab, la plateforme open-source " +"d'analyse et de visualisation de données scientifiques" msgid "DataLab, workspace, scientific, data, analysis, visualization, platform" -msgstr "DataLab, espace de travail, scientifique, données, analyse, visualisation, plateforme" +msgstr "" +"DataLab, espace de travail, scientifique, données, analyse, " +"visualisation, plateforme" msgid "Overview" msgstr "Vue d'ensemble" @@ -25,14 +34,38 @@ msgstr "Vue d'ensemble" msgid "Basic concepts" msgstr "Concepts de base" -msgid "Working with DataLab is very easy. The user interface is intuitive and self-explanatory. The main window is divided into two main areas:" -msgstr "Travailler avec DataLab est très simple. L'interface est intuitive et appréhendable facilement. La fenêtre principale est divisée en deux zones principales :" +msgid "" +"Working with DataLab is very easy. The user interface is intuitive and " +"self-explanatory. The main window is divided into two main areas:" +msgstr "" +"Travailler avec DataLab est très simple. L'interface est intuitive et " +"appréhendable facilement. La fenêtre principale est divisée en deux zones" +" principales :" -msgid "The left area contains the **Signals** and **Images** data tabs, which list the data sets currently loaded in each panel. Clicking a tab switches the main window to the corresponding panel, as well as the menu and toolbar contents. Below the list of data sets, a **Properties** view shows information about the currently selected data set." -msgstr "La zone de gauche contient les onglets de données **Signaux** et **Images**, qui répertorient les jeux de données actuellement chargés dans chaque panneau. Cliquer sur un onglet fait basculer la fenêtre principale vers le panneau correspondant, ainsi que le contenu du menu et de la barre d'outils. Sous la liste des jeux de données, une vue **Propriétés** affiche des informations sur le jeu de données actuellement sélectionné." +msgid "" +"The left area contains the **Signals** and **Images** data tabs, which " +"list the data sets currently loaded in each panel. Clicking a tab " +"switches the main window to the corresponding panel, as well as the menu " +"and toolbar contents. Below the list of data sets, a **Properties** view " +"shows information about the currently selected data set." +msgstr "" +"La zone de gauche contient les onglets de données **Signaux** et " +"**Images**, qui répertorient les jeux de données actuellement chargés " +"dans chaque panneau. Cliquer sur un onglet fait basculer la fenêtre " +"principale vers le panneau correspondant, ainsi que le contenu du menu et" +" de la barre d'outils. Sous la liste des jeux de données, une vue " +"**Propriétés** affiche des informations sur le jeu de données " +"actuellement sélectionné." -msgid "The right area shows the visualization of the currently selected data set. The visualization is updated automatically when the user selects a new data set in the list of data sets." -msgstr "La zone de droite affiche la visualisation du jeu de données actuellement sélectionné. La visualisation est mise à jour automatiquement lorsque l'utilisateur sélectionne un nouveau jeu de données dans la liste des jeux de données." +msgid "" +"The right area shows the visualization of the currently selected data " +"set. The visualization is updated automatically when the user selects a " +"new data set in the list of data sets." +msgstr "" +"La zone de droite affiche la visualisation du jeu de données actuellement" +" sélectionné. La visualisation est mise à jour automatiquement lorsque " +"l'utilisateur sélectionne un nouveau jeu de données dans la liste des " +"jeux de données." msgid "DataLab main window, at startup." msgstr "Fenêtre principale de DataLab, au démarrage." @@ -40,50 +73,130 @@ msgstr "Fenêtre principale de DataLab, au démarrage." msgid "History Panel" msgstr "Panneau d'historique" -msgid "The :ref:`historypanel` is an additional dockable panel that records signal and image actions into separate active sessions for each data panel. It supports replay, step-by-step replay, duplication, and compatibility diagnostics. Sessions may be saved in standalone ``.dlhist`` files or with the workspace in HDF5 format." -msgstr "Le :ref:`historypanel` est un panneau ancrable supplémentaire qui enregistre les actions sur les signaux et les images dans des sessions actives distinctes pour chaque panneau de données. Il permet de rejouer les actions, de les rejouer pas à pas, de les dupliquer et de diagnostiquer les incompatibilités. Les sessions peuvent être enregistrées dans des fichiers autonomes ``.dlhist`` ou avec l'espace de travail au format HDF5." +msgid "" +"The :ref:`historypanel` is an additional dockable panel that records " +"signal and image actions in a shared active session. It supports replay, " +"step-by-step replay, duplication, and compatibility diagnostics. Sessions" +" may be saved in standalone ``.dlhist`` files or with the workspace in " +"HDF5 format." +msgstr "" +"Le :ref:`historypanel` est un panneau ancrable supplémentaire qui " +"enregistre les actions sur les signaux et les images dans une session active " +"partagée. Il permet de rejouer les actions, de les rejouer pas à pas, de les " +"dupliquer et de diagnostiquer les incompatibilités. Les sessions peuvent être " +"enregistrées dans des fichiers autonomes ``.dlhist`` ou avec l'espace de " +"travail au format HDF5." msgid "Internal data model and workspace" msgstr "Modèle de données interne et espace de travail" -msgid "DataLab has its own internal data model, in which data sets are organized around a tree structure. Each panel in the main window corresponds to a branch of the tree. Each data set shown in the panels corresponds to a leaf of the tree. Inside the data set, the data is organized in an object-oriented way, with a set of attributes and methods. The data model is described in more detail in the API section (see :mod:`sigima.objects`)." -msgstr "DataLab a son propre modèle de données interne, dans lequel les jeux de données sont organisés autour d'une structure arborescente. Chaque panneau de la fenêtre principale correspond à une branche de l'arbre. Chaque jeu de données affiché dans les panneaux correspond à une feuille de l'arbre. À l'intérieur du jeu de données, les données sont organisées de manière orientée objet, avec un ensemble d'attributs et de méthodes. Le modèle de données est décrit plus en détail dans la section API (voir :mod:`sigima.objects`)." +msgid "" +"DataLab has its own internal data model, in which data sets are organized" +" around a tree structure. Each panel in the main window corresponds to a " +"branch of the tree. Each data set shown in the panels corresponds to a " +"leaf of the tree. Inside the data set, the data is organized in an " +"object-oriented way, with a set of attributes and methods. The data model" +" is described in more detail in the API section (see " +":mod:`sigima.objects`)." +msgstr "" +"DataLab a son propre modèle de données interne, dans lequel les jeux de " +"données sont organisés autour d'une structure arborescente. Chaque " +"panneau de la fenêtre principale correspond à une branche de l'arbre. " +"Chaque jeu de données affiché dans les panneaux correspond à une feuille " +"de l'arbre. À l'intérieur du jeu de données, les données sont organisées " +"de manière orientée objet, avec un ensemble d'attributs et de méthodes. " +"Le modèle de données est décrit plus en détail dans la section API (voir " +":mod:`sigima.objects`)." -msgid "For each signal or image object, DataLab stores not only the data itself but also a set of metadata describing the data and how it should be displayed. The metadata is stored in a dictionary accessible through the object's ``metadata`` attribute (and may also be browsed in the **Properties** view, with the **Metadata** button)." -msgstr "Pour chaque objet signal ou image, DataLab stocke non seulement les données elles-mêmes, mais aussi un ensemble de métadonnées décrivant les données et la manière dont elles doivent être affichées. Ces métadonnées sont stockées dans un dictionnaire accessible par l'attribut ``metadata`` de l'objet (et peuvent également être consultées dans la vue **Propriétés**, à l'aide du bouton **Métadonnées**)." +msgid "" +"For each signal or image object, DataLab stores not only the data itself " +"but also a set of metadata describing the data and how it should be " +"displayed. The metadata is stored in a dictionary accessible through the " +"object's ``metadata`` attribute (and may also be browsed in the " +"**Properties** view, with the **Metadata** button)." +msgstr "" +"Pour chaque objet signal ou image, DataLab stocke non seulement les " +"données elles-mêmes, mais aussi un ensemble de métadonnées décrivant les " +"données et la manière dont elles doivent être affichées. Ces métadonnées " +"sont stockées dans un dictionnaire accessible par l'attribut ``metadata``" +" de l'objet (et peuvent également être consultées dans la vue " +"**Propriétés**, à l'aide du bouton **Métadonnées**)." -msgid "The DataLab **Workspace** is defined as the collection of all data sets which are currently loaded in DataLab, in both the **Signals** and **Images** panels." -msgstr "L'**Espace de travail** de DataLab est défini comme l'ensemble de tous les jeux de données actuellement chargés dans DataLab, dans les panneaux **Signaux** et **Images**." +msgid "" +"The DataLab **Workspace** is defined as the collection of all data sets " +"which are currently loaded in DataLab, in both the **Signals** and " +"**Images** panels." +msgstr "" +"L'**Espace de travail** de DataLab est défini comme l'ensemble de tous " +"les jeux de données actuellement chargés dans DataLab, dans les panneaux " +"**Signaux** et **Images**." msgid "Loading and saving the workspace" msgstr "Chargement et enregistrement de l'espace de travail" -msgid "The following actions are available to manage the workspace from the **File** menu:" -msgstr "Les actions suivantes sont disponibles pour gérer l'espace de travail depuis le menu **Fichier** :" +msgid "" +"The following actions are available to manage the workspace from the " +"**File** menu:" +msgstr "" +"Les actions suivantes sont disponibles pour gérer l'espace de travail " +"depuis le menu **Fichier** :" msgid "**Open HDF5 file**: load a workspace from an HDF5 file." -msgstr "**Ouvrir un fichier HDF5** : charger un espace de travail à partir d'un fichier HDF5." +msgstr "" +"**Ouvrir un fichier HDF5** : charger un espace de travail à partir d'un " +"fichier HDF5." msgid "**Save to HDF5 file**: save the current workspace to an HDF5 file." -msgstr "**Enregistrer dans un fichier HDF5** : enregistrer l'espace de travail actuel dans un fichier HDF5." +msgstr "" +"**Enregistrer dans un fichier HDF5** : enregistrer l'espace de travail " +"actuel dans un fichier HDF5." -msgid "**Browse HDF5 file**: open the :ref:`h5browser` to explore the content of an HDF5 file and import data sets into the workspace." -msgstr "**Parcourir un fichier HDF5** : ouvrir le :ref:`h5browser` pour explorer le contenu d'un fichier HDF5 et importer des jeux de données dans l'espace de travail." +msgid "" +"**Browse HDF5 file**: open the :ref:`h5browser` to explore the content of" +" an HDF5 file and import data sets into the workspace." +msgstr "" +"**Parcourir un fichier HDF5** : ouvrir le :ref:`h5browser` pour explorer " +"le contenu d'un fichier HDF5 et importer des jeux de données dans " +"l'espace de travail." -msgid "Data sets may also be saved or loaded individually, using data formats such as `.txt` or `.npy` for 1D signals (see :ref:`open_signal` for the list of supported formats), or `.tiff` or `.dcm` for 2D images (see :ref:`open_image` for the list of supported formats)." -msgstr "Les jeux de données peuvent également être enregistrés ou chargés individuellement, en utilisant des formats de données tels que `.txt` ou `.npy` pour les signaux 1D (voir :ref:`open_signal` pour la liste des formats pris en charge), ou `.tiff` ou `.dcm` pour les images 2D (voir :ref:`open_image` pour la liste des formats pris en charge)." +msgid "" +"Data sets may also be saved or loaded individually, using data formats " +"such as `.txt` or `.npy` for 1D signals (see :ref:`open_signal` for the " +"list of supported formats), or `.tiff` or `.dcm` for 2D images (see " +":ref:`open_image` for the list of supported formats)." +msgstr "" +"Les jeux de données peuvent également être enregistrés ou chargés " +"individuellement, en utilisant des formats de données tels que `.txt` ou " +"`.npy` pour les signaux 1D (voir :ref:`open_signal` pour la liste des " +"formats pris en charge), ou `.tiff` ou `.dcm` pour les images 2D (voir " +":ref:`open_image` pour la liste des formats pris en charge)." msgid "Interactive object creation and processing" msgstr "Création et traitement interactifs d'objets" -msgid "DataLab provides an interactive workflow for creating objects and adjusting processing parameters, allowing you to fine-tune results without creating multiple objects." -msgstr "DataLab fournit un flux de travail interactif pour créer des objets et ajuster les paramètres de traitement, vous permettant d'affiner les résultats sans créer plusieurs objets." +msgid "" +"DataLab provides an interactive workflow for creating objects and " +"adjusting processing parameters, allowing you to fine-tune results " +"without creating multiple objects." +msgstr "" +"DataLab fournit un flux de travail interactif pour créer des objets et " +"ajuster les paramètres de traitement, vous permettant d'affiner les " +"résultats sans créer plusieurs objets." msgid "Interactive object creation" msgstr "Création interactive d'objets" -msgid "When creating a new signal or image object using the creation functions (e.g., Gaussian signal, 2D peak image, etc.), DataLab stores the creation parameters in the object's metadata. This enables interactive parameter adjustment after creation:" -msgstr "Lors de la création d'un nouveau signal ou d'une nouvelle image à l'aide des fonctions de création (par exemple, signal gaussien, image de pic 2D, etc.), DataLab stocke les paramètres de création dans les métadonnées de l'objet. Cela permet d'ajuster les paramètres de manière interactive après la création :" +msgid "" +"When creating a new signal or image object using the creation functions " +"(e.g., Gaussian signal, 2D peak image, etc.), DataLab stores the creation" +" parameters in the object's metadata. This enables interactive parameter " +"adjustment after creation:" +msgstr "" +"Lors de la création d'un nouveau signal ou d'une nouvelle image à l'aide " +"des fonctions de création (par exemple, signal gaussien, image de pic 2D," +" etc.), DataLab stocke les paramètres de création dans les métadonnées de" +" l'objet. Cela permet d'ajuster les paramètres de manière interactive " +"après la création :" msgid "Create a signal or image object from the **Create** menu" msgstr "Créer un objet signal ou image depuis le menu **Création**" @@ -92,19 +205,32 @@ msgid "Select the created object in the list" msgstr "Sélectionner l'objet créé dans la liste" msgid "A **Creation** tab appears in the Properties panel (bottom-left)" -msgstr "Un onglet **Création** apparaît dans le panneau des propriétés (en bas à gauche)" +msgstr "" +"Un onglet **Création** apparaît dans le panneau des propriétés (en bas à " +"gauche)" msgid "Modify any creation parameter (amplitude, frequency, size, etc.)" -msgstr "Modifier n'importe quel paramètre de création (amplitude, fréquence, taille, etc.)" +msgstr "" +"Modifier n'importe quel paramètre de création (amplitude, fréquence, " +"taille, etc.)" msgid "Click **Apply** to regenerate the object with new parameters" -msgstr "Cliquer sur **Appliquer** pour régénérer l'objet avec les nouveaux paramètres" +msgstr "" +"Cliquer sur **Appliquer** pour régénérer l'objet avec les nouveaux " +"paramètres" -msgid "The object is updated in place, preserving any subsequent processing or analysis results. This is particularly useful for:" -msgstr "L'objet est mis à jour sur place, préservant tous les résultats de traitement ou d'analyse ultérieurs. Cela est particulièrement utile pour :" +msgid "" +"The object is updated in place, preserving any subsequent processing or " +"analysis results. This is particularly useful for:" +msgstr "" +"L'objet est mis à jour sur place, préservant tous les résultats de " +"traitement ou d'analyse ultérieurs. Cela est particulièrement utile pour " +":" msgid "Exploring different parameter values without cluttering the workspace" -msgstr "Explorer différentes valeurs de paramètres sans encombrer l'espace de travail" +msgstr "" +"Explorer différentes valeurs de paramètres sans encombrer l'espace de " +"travail" msgid "Fine-tuning object characteristics while observing the results" msgstr "Affiner les caractéristiques de l'objet tout en observant les résultats" @@ -112,20 +238,41 @@ msgstr "Affiner les caractéristiques de l'objet tout en observant les résultat msgid "Educational purposes to demonstrate parameter effects" msgstr "Objectifs pédagogiques pour démontrer les effets des paramètres" -msgid "Interactive creation is only available for objects created with parameter classes (not for imported data from files)." -msgstr "La création interactive n'est disponible que pour les objets créés avec des classes de paramètres (pas pour les données importées à partir de fichiers)." +msgid "" +"Interactive creation is only available for objects created with parameter" +" classes (not for imported data from files)." +msgstr "" +"La création interactive n'est disponible que pour les objets créés avec " +"des classes de paramètres (pas pour les données importées à partir de " +"fichiers)." msgid "Interactive 1-to-1 processing" msgstr "Traitement interactif 1-vers-1" -msgid "When applying a 1-to-1 processing operation that has configurable parameters (e.g., Gaussian filter, threshold, morphological operations), DataLab stores the processing metadata, enabling parameter adjustment and re-processing:" -msgstr "Lors de l'application d'une opération de traitement 1-vers-1 qui a des paramètres configurables (par exemple, filtre gaussien, seuil, opérations morphologiques), DataLab stocke les métadonnées de traitement, permettant l'ajustement des paramètres et le retraitement :" +msgid "" +"When applying a 1-to-1 processing operation that has configurable " +"parameters (e.g., Gaussian filter, threshold, morphological operations), " +"DataLab stores the processing metadata, enabling parameter adjustment and" +" re-processing:" +msgstr "" +"Lors de l'application d'une opération de traitement 1-vers-1 qui a des " +"paramètres configurables (par exemple, filtre gaussien, seuil, opérations" +" morphologiques), DataLab stocke les métadonnées de traitement, " +"permettant l'ajustement des paramètres et le retraitement :" -msgid "Apply a processing operation with parameters (e.g., **Processing** > **Noise reduction** > **Gaussian filter**)" -msgstr "Appliquer une opération de traitement avec des paramètres (par exemple, **Traitement** > **Réduction de bruit** > **Filtre gaussien**)" +msgid "" +"Apply a processing operation with parameters (e.g., **Processing** > " +"**Noise reduction** > **Gaussian filter**)" +msgstr "" +"Appliquer une opération de traitement avec des paramètres (par exemple, " +"**Traitement** > **Réduction de bruit** > **Filtre gaussien**)" -msgid "The result object contains processing metadata (parameters, source object, function name)" -msgstr "L'objet résultant contient des métadonnées de traitement (paramètres, objet source, nom de la fonction)" +msgid "" +"The result object contains processing metadata (parameters, source " +"object, function name)" +msgstr "" +"L'objet résultant contient des métadonnées de traitement (paramètres, " +"objet source, nom de la fonction)" msgid "Select the processed object in the list" msgstr "Sélectionner l'objet traité dans la liste" @@ -134,16 +281,24 @@ msgid "A **Processing** tab appears in the Properties panel" msgstr "Un onglet **Traitement** apparaît dans le panneau des propriétés" msgid "Modify processing parameters (e.g., filter sigma value)" -msgstr "Modifier les paramètres de traitement (par exemple, valeur du sigma du filtre)" +msgstr "" +"Modifier les paramètres de traitement (par exemple, valeur du sigma du " +"filtre)" msgid "Click **Apply** to re-process with updated parameters" msgstr "Cliquer sur **Appliquer** pour retraiter avec les paramètres mis à jour" -msgid "The processed object is updated in place with the new results. This workflow is ideal for:" -msgstr "L'objet traité est mis à jour sur place avec les nouveaux résultats. Ce flux de travail est idéal pour :" +msgid "" +"The processed object is updated in place with the new results. This " +"workflow is ideal for:" +msgstr "" +"L'objet traité est mis à jour sur place avec les nouveaux résultats. Ce " +"flux de travail est idéal pour :" msgid "Iteratively tuning filter parameters while observing results in real time" -msgstr "Ajuster de manière itérative les paramètres du filtre tout en observant les résultats en temps réel" +msgstr "" +"Ajuster de manière itérative les paramètres du filtre tout en observant " +"les résultats en temps réel" msgid "Adjusting threshold values without creating multiple intermediate objects" msgstr "Ajustement des valeurs de seuil sans créer plusieurs objets intermédiaires" @@ -152,19 +307,29 @@ msgid "Experimenting with different morphological structuring element sizes" msgstr "Tester différentes tailles d'éléments structurants morphologiques" msgid "Educational demonstrations of parameter effects on processing results" -msgstr "Démonstrations éducatives des effets des paramètres sur les résultats du traitement" +msgstr "" +"Démonstrations éducatives des effets des paramètres sur les résultats du " +"traitement" msgid "**Processing metadata requirements:**" msgstr "**Exigences en matière de métadonnées de traitement :**" msgid "Only works for 1-to-1 processing functions with parameter classes" -msgstr "Ne fonctionne que pour les fonctions de traitement 1-vers-1 avec des classes de paramètres" +msgstr "" +"Ne fonctionne que pour les fonctions de traitement 1-vers-1 avec des " +"classes de paramètres" -msgid "Processing functions without parameters (e.g., absolute value, inverse) work as before" -msgstr "Les fonctions de traitement sans paramètres (par exemple, valeur absolue, inverse) fonctionnent comme auparavant" +msgid "" +"Processing functions without parameters (e.g., absolute value, inverse) " +"work as before" +msgstr "" +"Les fonctions de traitement sans paramètres (par exemple, valeur absolue," +" inverse) fonctionnent comme auparavant" msgid "Source object must still exist for re-processing (error shown if deleted)" -msgstr "L'objet source doit toujours exister pour le retraitement (erreur affichée s'il est supprimé)" +msgstr "" +"L'objet source doit toujours exister pour le retraitement (erreur " +"affichée s'il est supprimé)" msgid "**Not supported for:**" msgstr "**Non pris en charge pour :**" @@ -175,8 +340,12 @@ msgstr "Traitement 2-vers-1 (opérations combinant deux objets)" msgid "n-to-1 processing (operations aggregating multiple objects)" msgstr "Traitement n-vers-1 (opérations agrégeant plusieurs objets)" -msgid "These patterns don't benefit significantly from interactive parameter adjustment" -msgstr "Ces modèles ne bénéficient pas de manière significative de l'ajustement interactif des paramètres" +msgid "" +"These patterns don't benefit significantly from interactive parameter " +"adjustment" +msgstr "" +"Ces modèles ne bénéficient pas de manière significative de l'ajustement " +"interactif des paramètres" msgid "Example workflow" msgstr "Exemple de flux de travail" @@ -190,20 +359,30 @@ msgstr "**Créer un signal de test** : Création > Signal gaussien" msgid "Initial parameters: amplitude=1.0, mu=50, sigma=10" msgstr "Paramètres initiaux : amplitude=1.0, mu=50, sigma=10" -msgid "**Adjust creation parameters**: In the Creation tab, change sigma to 20, click Apply" -msgstr "**Ajuster les paramètres de création** : Dans l'onglet Création, faire passer sigma à 20, cliquer sur Appliquer" +msgid "" +"**Adjust creation parameters**: In the Creation tab, change sigma to 20, " +"click Apply" +msgstr "" +"**Ajuster les paramètres de création** : Dans l'onglet Création, faire " +"passer sigma à 20, cliquer sur Appliquer" msgid "Signal is regenerated with new width" msgstr "Le signal est régénéré avec une nouvelle largeur" msgid "**Apply Gaussian filter**: Processing > Noise reduction > Gaussian filter" -msgstr "**Appliquer le filtre gaussien** : Traitement > Réduction de bruit > Filtre gaussien" +msgstr "" +"**Appliquer le filtre gaussien** : Traitement > Réduction de bruit > " +"Filtre gaussien" msgid "Initial sigma=2.0" msgstr "Sigma initial=2.0" -msgid "**Fine-tune filtering**: In the Processing tab, try sigma=1.0, then sigma=5.0" -msgstr "**Ajuster le filtrage** : Dans l'onglet Traitement, essayer sigma=1.0, puis sigma=5.0" +msgid "" +"**Fine-tune filtering**: In the Processing tab, try sigma=1.0, then " +"sigma=5.0" +msgstr "" +"**Ajuster le filtrage** : Dans l'onglet Traitement, essayer sigma=1.0, " +"puis sigma=5.0" msgid "Each Apply updates the filtered result" msgstr "Chaque clic sur **Appliquer** met à jour le résultat filtré" @@ -211,5 +390,11 @@ msgstr "Chaque clic sur **Appliquer** met à jour le résultat filtré" msgid "Compare different smoothing levels without creating multiple objects" msgstr "Comparer différents niveaux de lissage sans créer plusieurs objets" -msgid "This interactive approach provides immediate visual feedback and keeps your workspace organized by avoiding proliferation of test objects with slightly different parameters." -msgstr "Cette approche interactive fournit un retour visuel immédiat et garde votre espace de travail organisé en évitant la prolifération d'objets de test avec des paramètres légèrement différents." +msgid "" +"This interactive approach provides immediate visual feedback and keeps " +"your workspace organized by avoiding proliferation of test objects with " +"slightly different parameters." +msgstr "" +"Cette approche interactive fournit un retour visuel immédiat et garde " +"votre espace de travail organisé en évitant la prolifération d'objets de " +"test avec des paramètres légèrement différents." diff --git a/doc/locale/fr/LC_MESSAGES/features/common/settings.po b/doc/locale/fr/LC_MESSAGES/features/common/settings.po index d230b6e42..f637cec96 100644 --- a/doc/locale/fr/LC_MESSAGES/features/common/settings.po +++ b/doc/locale/fr/LC_MESSAGES/features/common/settings.po @@ -5,31 +5,46 @@ # msgid "" msgstr "" -"Project-Id-Version: PROJECT VERSION\n" -"POT-Creation-Date: 2026-08-05 14:24+0200\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -msgid "Settings of DataLab, the open-source scientific data analysis and visualization platform" -msgstr "Préférences de DataLab, la plateforme open-source d'analyse et de visualisation de données scientifiques" +msgid "" +"Settings of DataLab, the open-source scientific data analysis and " +"visualization platform" +msgstr "" +"Préférences de DataLab, la plateforme open-source d'analyse et de " +"visualisation de données scientifiques" msgid "DataLab, settings, scientific, data, analysis, visualization, platform" -msgstr "DataLab, préférences, scientifique, données, analyse, visualisation, plateforme" +msgstr "" +"DataLab, préférences, scientifique, données, analyse, visualisation, " +"plateforme" msgid "Settings" msgstr "Préférences" -msgid "DataLab provides a comprehensive settings dialog to customize the application behavior, visualization defaults, and I/O operations. The settings are organized into six tabs: General, Processing, Visualization, I/O, AI Assistant, and Console." -msgstr "DataLab propose une boîte de dialogue de préférences complète pour personnaliser le comportement de l'application, les paramètres de visualisation par défaut et les opérations d'entrée/sortie. Les préférences sont organisées en six onglets : Général, Traitement, Visualisation, Entrée/sortie, Assistant IA et Console." +msgid "" +"DataLab provides a comprehensive settings dialog to customize the " +"application behavior, visualization defaults, and I/O operations. The " +"settings are organized into six tabs: General, Processing, Visualization," +" I/O, AI Assistant, and Console." +msgstr "" +"DataLab propose une boîte de dialogue de préférences complète pour " +"personnaliser le comportement de l'application, les paramètres de " +"visualisation par défaut et les opérations d'entrée/sortie. Les " +"préférences sont organisées en six onglets : Général, Traitement, " +"Visualisation, Entrée/sortie, Assistant IA et Console." msgid "General" msgstr "Général" -msgid "The General settings tab contains main window and general feature settings:" -msgstr "L'onglet des préférences générales contient les paramètres de la fenêtre principale et les paramètres généraux :" +msgid "" +"The General settings tab contains main window and general feature " +"settings:" +msgstr "" +"L'onglet des préférences générales contient les paramètres de la fenêtre " +"principale et les paramètres généraux :" msgid "General settings tab" msgstr "Onglet des préférences générales" @@ -37,53 +52,112 @@ msgstr "Onglet des préférences générales" msgid "**Color mode**" msgstr "**Mode couleur**" -msgid "Choose the color mode for the application interface (e.g., light, dark, or auto)." -msgstr "Choisir le mode couleur de l'interface de l'application (par exemple, clair, sombre ou automatique)." +msgid "" +"Choose the color mode for the application interface (e.g., light, dark, " +"or auto)." +msgstr "" +"Choisir le mode couleur de l'interface de l'application (par exemple, " +"clair, sombre ou automatique)." msgid "**Process isolation**" msgstr "**Isolation des processus**" -msgid "When enabled, each computation runs in a separate process, preventing the application from freezing during long computations. This is the recommended setting for better responsiveness." -msgstr "Si le réglage est activé, chaque calcul s'exécute dans un processus séparé, empêchant l'application de geler pendant les longs calculs. Il s'agit du paramètre recommandé pour une meilleure réactivité." +msgid "" +"When enabled, each computation runs in a separate process, preventing the" +" application from freezing during long computations. This is the " +"recommended setting for better responsiveness." +msgstr "" +"Si le réglage est activé, chaque calcul s'exécute dans un processus " +"séparé, empêchant l'application de geler pendant les longs calculs. Il " +"s'agit du paramètre recommandé pour une meilleure réactivité." msgid "**RPC server**" msgstr "**Serveur RPC**" -msgid "Enable the RPC (Remote Procedure Call) server to communicate with external applications, such as your own scripts running in Spyder, Jupyter, or other software. This allows programmatic control of DataLab." -msgstr "Activer le serveur RPC (Remote Procedure Call) pour communiquer avec des applications externes, telles que vos propres scripts s'exécutant dans Spyder, Jupyter ou d'autres logiciels. Cela permet un contrôle programmatique de DataLab." +msgid "" +"Enable the RPC (Remote Procedure Call) server to communicate with " +"external applications, such as your own scripts running in Spyder, " +"Jupyter, or other software. This allows programmatic control of DataLab." +msgstr "" +"Activer le serveur RPC (Remote Procedure Call) pour communiquer avec des " +"applications externes, telles que vos propres scripts s'exécutant dans " +"Spyder, Jupyter ou d'autres logiciels. Cela permet un contrôle " +"programmatique de DataLab." msgid "**Web API localhost bypass**" msgstr "**Contournement localhost de l'API Web**" -msgid "When enabled (default), connections from localhost (127.0.0.1) to the Web API do not require authentication. This simplifies notebook integration when DataLab-Kernel runs on the same machine. Disable for stricter security if needed." -msgstr "Lorsque cette option est activée (par défaut), les connexions depuis localhost (127.0.0.1) vers l'API Web ne nécessitent pas d'authentification. Cela simplifie l'intégration des notebooks lorsque DataLab-Kernel s'exécute sur la même machine. Désactiver pour une sécurité plus stricte si nécessaire." +msgid "" +"When enabled (default), connections from localhost (127.0.0.1) to the Web" +" API do not require authentication. This simplifies notebook integration " +"when DataLab-Kernel runs on the same machine. Disable for stricter " +"security if needed." +msgstr "" +"Lorsque cette option est activée (par défaut), les connexions depuis " +"localhost (127.0.0.1) vers l'API Web ne nécessitent pas " +"d'authentification. Cela simplifie l'intégration des notebooks lorsque " +"DataLab-Kernel s'exécute sur la même machine. Désactiver pour une " +"sécurité plus stricte si nécessaire." -msgid "When this option is enabled, any application running on your local machine can access the DataLab Web API without a token. Disable this option if you need stricter security." -msgstr "Lorsque cette option est activée, toute application s'exécutant sur votre machine locale peut accéder à l'API Web DataLab sans jeton. Désactivez cette option si vous avez besoin d'une sécurité plus stricte." +msgid "" +"When this option is enabled, any application running on your local " +"machine can access the DataLab Web API without a token. Disable this " +"option if you need stricter security." +msgstr "" +"Lorsque cette option est activée, toute application s'exécutant sur votre" +" machine locale peut accéder à l'API Web DataLab sans jeton. Désactivez " +"cette option si vous avez besoin d'une sécurité plus stricte." msgid "**Memory threshold**" msgstr "**Seuil de mémoire**" -msgid "Set a threshold (in MB) below which a warning is displayed before loading new data. This helps prevent out-of-memory errors when working with large datasets. Set to 0 to disable the warning." -msgstr "Définir un seuil (en Mo) en dessous duquel un avertissement est affiché avant de charger de nouvelles données. Cela permet d'éviter les erreurs de mémoire insuffisante lors du travail avec de grands ensembles de données. Mettre à 0 pour désactiver l'avertissement." +msgid "" +"Set a threshold (in MB) below which a warning is displayed before loading" +" new data. This helps prevent out-of-memory errors when working with " +"large datasets. Set to 0 to disable the warning." +msgstr "" +"Définir un seuil (en Mo) en dessous duquel un avertissement est affiché " +"avant de charger de nouvelles données. Cela permet d'éviter les erreurs " +"de mémoire insuffisante lors du travail avec de grands ensembles de " +"données. Mettre à 0 pour désactiver l'avertissement." msgid "**Third-party plugins**" msgstr "**Plugins tiers**" -msgid "Enable or disable third-party plugins immediately. Changes are applied without restarting DataLab. When disabled, third-party plugins are not discovered or loaded." -msgstr "Activer ou désactiver immédiatement les plugins tiers. Les modifications sont appliquées sans redémarrer DataLab. Lorsqu'ils sont désactivés, les plugins tiers ne sont ni détectés ni chargés." +msgid "" +"Enable or disable third-party plugins immediately. Changes are applied " +"without restarting DataLab. When disabled, third-party plugins are not " +"discovered or loaded." +msgstr "" +"Activer ou désactiver immédiatement les plugins tiers. Les modifications " +"sont appliquées sans redémarrer DataLab. Lorsqu'ils sont désactivés, les " +"plugins tiers ne sont ni détectés ni chargés." msgid "**Plugins path**" msgstr "**Chemin des plugins**" -msgid "Specify the directory path where DataLab should look for third-party plugins. DataLab will also discover plugins in your PYTHONPATH. To enable or disable individual plugins, use the ``Plugins > Configure plugins...`` menu action. DataLab then proposes reloading plugins automatically." -msgstr "Indiquer le répertoire dans lequel DataLab doit rechercher les plugins tiers. DataLab détectera également les plugins présents dans votre PYTHONPATH. Pour activer ou désactiver des plugins individuellement, utilisez l'action de menu ``Plugins > Configurer les plugins...``. DataLab proposera ensuite de recharger automatiquement les plugins." +msgid "" +"Specify the directory path where DataLab should look for third-party " +"plugins. DataLab will also discover plugins in your PYTHONPATH. To enable" +" or disable individual plugins, use the ``Plugins > Configure " +"plugins...`` menu action. DataLab then proposes reloading plugins " +"automatically." +msgstr "" +"Indiquer le répertoire dans lequel DataLab doit rechercher les plugins " +"tiers. DataLab détectera également les plugins présents dans votre " +"PYTHONPATH. Pour activer ou désactiver des plugins individuellement, " +"utilisez l'action de menu ``Plugins > Configurer les plugins...``. " +"DataLab proposera ensuite de recharger automatiquement les plugins." msgid "Processing" msgstr "Traitement" -msgid "The Processing settings tab controls computation behavior and default parameters:" -msgstr "L'onglet des préférences de traitement contrôle le comportement des calculs et les paramètres par défaut :" +msgid "" +"The Processing settings tab controls computation behavior and default " +"parameters:" +msgstr "" +"L'onglet des préférences de traitement contrôle le comportement des " +"calculs et les paramètres par défaut :" msgid "Processing settings tab" msgstr "Onglet des préférences de traitement" @@ -100,28 +174,56 @@ msgstr "**Single** : mode d'opération avec un seul opérande" msgid "**Pairwise**: pairwise operation mode" msgstr "**Pairwise** : mode d'opération par paire" -msgid "These operation modes determine how DataLab handles computations involving multiple objects. They apply to two types of operations:" -msgstr "Ces modes d'opération déterminent comment DataLab gère les calculs impliquant plusieurs objets. Ils s'appliquent à deux types d'opérations :" +msgid "" +"These operation modes determine how DataLab handles computations " +"involving multiple objects. They apply to two types of operations:" +msgstr "" +"Ces modes d'opération déterminent comment DataLab gère les calculs " +"impliquant plusieurs objets. Ils s'appliquent à deux types d'opérations :" -msgid "**N→1 operations**: Combine N (≥2) objects into 1 output (e.g. sum, average)" -msgstr "**Opérations N→1** : Combiner N (≥2) objets en 1 sortie (par exemple somme, moyenne)" +msgid "" +"**N→1 operations**: Combine N (≥2) objects into 1 output (e.g. sum, " +"average)" +msgstr "" +"**Opérations N→1** : Combiner N (≥2) objets en 1 sortie (par exemple " +"somme, moyenne)" -msgid "**N+1→N operations**: Apply an operation between N (≥1) objects and 1 operand to produce N outputs (e.g. difference, division)" -msgstr "**Opérations N+1→N** : Appliquer une opération entre N (≥1) objets et 1 opérande pour produire N sorties (par exemple différence, division)" +msgid "" +"**N+1→N operations**: Apply an operation between N (≥1) objects and 1 " +"operand to produce N outputs (e.g. difference, division)" +msgstr "" +"**Opérations N+1→N** : Appliquer une opération entre N (≥1) objets et 1 " +"opérande pour produire N sorties (par exemple différence, division)" -msgid "**Single operand mode** (default): Operations are applied independently within each group." -msgstr "**Mode d'opération avec un seul opérande** (par défaut) : Les opérations sont appliquées indépendamment dans chaque groupe." +msgid "" +"**Single operand mode** (default): Operations are applied independently " +"within each group." +msgstr "" +"**Mode d'opération avec un seul opérande** (par défaut) : Les opérations " +"sont appliquées indépendamment dans chaque groupe." #, python-brace-format -msgid "For **N→1 operations**: All objects in each group are combined into one result per group. Example with groups G1={A, B} and G2={C, D}, sum operation:" -msgstr "Pour les **opérations N→1** : Tous les objets de chaque groupe sont combinés en un seul résultat par groupe. Exemple avec les groupes G1={A, B} et G2={C, D}, opération de somme :" +msgid "" +"For **N→1 operations**: All objects in each group are combined into one " +"result per group. Example with groups G1={A, B} and G2={C, D}, sum " +"operation:" +msgstr "" +"Pour les **opérations N→1** : Tous les objets de chaque groupe sont " +"combinés en un seul résultat par groupe. Exemple avec les groupes G1={A, " +"B} et G2={C, D}, opération de somme :" msgid "Result: Σ(A,B) and Σ(C,D) (one per group)" msgstr "Résultat : Σ(A,B) et Σ(C,D) (un par groupe)" #, python-brace-format -msgid "For **N+1→N operations**: Each selected object is combined with a single reference operand. Example with groups G1={A, B} and G2={C, D}, difference with reference R:" -msgstr "Pour les **opérations N+1→N** : Chaque objet sélectionné est combiné avec un seul opérande de référence. Exemple avec les groupes G1={A, B} et G2={C, D}, différence avec la référence R :" +msgid "" +"For **N+1→N operations**: Each selected object is combined with a single " +"reference operand. Example with groups G1={A, B} and G2={C, D}, " +"difference with reference R:" +msgstr "" +"Pour les **opérations N+1→N** : Chaque objet sélectionné est combiné avec" +" un seul opérande de référence. Exemple avec les groupes G1={A, B} et " +"G2={C, D}, différence avec la référence R :" msgid "In G1: A-R, B-R" msgstr "Dans G1 : A-R, B-R" @@ -129,19 +231,35 @@ msgstr "Dans G1 : A-R, B-R" msgid "In G2: C-R, D-R" msgstr "Dans G2 : C-R, D-R" -msgid "**Pairwise operation mode**: Objects from different groups are combined at matching positions (all groups must have the same number of objects)." -msgstr "**Mode d'opération par paire** : Les objets de différents groupes sont combinés aux positions correspondantes (tous les groupes doivent avoir le même nombre d'objets)." +msgid "" +"**Pairwise operation mode**: Objects from different groups are combined " +"at matching positions (all groups must have the same number of objects)." +msgstr "" +"**Mode d'opération par paire** : Les objets de différents groupes sont " +"combinés aux positions correspondantes (tous les groupes doivent avoir le" +" même nombre d'objets)." #, python-brace-format -msgid "For **N→1 operations**: Objects at the same position in each group are combined. Example with groups G1={A, B} and G2={C, D}, sum operation:" -msgstr "Pour les **opérations N→1** : Les objets à la même position dans chaque groupe sont combinés. Exemple avec les groupes G1={A, B} et G2={C, D}, opération de somme :" +msgid "" +"For **N→1 operations**: Objects at the same position in each group are " +"combined. Example with groups G1={A, B} and G2={C, D}, sum operation:" +msgstr "" +"Pour les **opérations N→1** : Les objets à la même position dans chaque " +"groupe sont combinés. Exemple avec les groupes G1={A, B} et G2={C, D}, " +"opération de somme :" msgid "Result: A+C and B+D (pairing by position)" msgstr "Résultat : A+C et B+D (appariement par position)" #, python-brace-format -msgid "For **N+1→N operations**: Objects at matching positions are combined pairwise. Example with groups G1={A, B}, G2={C, D}, difference with group G3={E, F}:" -msgstr "Pour les **opérations N+1→N** : Les objets aux positions correspondantes sont combinés par paires. Exemple avec les groupes G1={A, B}, G2={C, D}, différence avec le groupe G3={E, F} :" +msgid "" +"For **N+1→N operations**: Objects at matching positions are combined " +"pairwise. Example with groups G1={A, B}, G2={C, D}, difference with group" +" G3={E, F}:" +msgstr "" +"Pour les **opérations N+1→N** : Les objets aux positions correspondantes " +"sont combinés par paires. Exemple avec les groupes G1={A, B}, G2={C, D}, " +"différence avec le groupe G3={E, F} :" msgid "New group 1: A-E, B-F" msgstr "Nouveau groupe 1 : A-E, B-F" @@ -152,26 +270,48 @@ msgstr "Nouveau groupe 2 : C-E, D-F" msgid "**Use signal bounds for new signals**" msgstr "**Utiliser les bornes du signal pour les nouveaux signaux**" -msgid "When enabled, the xmin and xmax values for new signals are initialized from the current signal's bounds. When disabled, default values are used." -msgstr "Si le réglage est activé, les valeurs xmin et xmax pour les nouveaux signaux sont initialisées à partir des bornes du signal actuel. Lorsque désactivé, les valeurs par défaut sont utilisées." +msgid "" +"When enabled, the xmin and xmax values for new signals are initialized " +"from the current signal's bounds. When disabled, default values are used." +msgstr "" +"Si le réglage est activé, les valeurs xmin et xmax pour les nouveaux " +"signaux sont initialisées à partir des bornes du signal actuel. Lorsque " +"désactivé, les valeurs par défaut sont utilisées." msgid "**Use image dimensions for new images**" msgstr "**Utiliser les dimensions d'image pour les nouvelles images**" -msgid "When enabled, the width and height values for new images are initialized from the current image's dimensions. When disabled, default values are used." -msgstr "Si le réglage est activé, les valeurs de largeur et de hauteur pour les nouvelles images sont initialisées à partir des dimensions de l'image actuelle. Lorsque désactivé, les valeurs par défaut sont utilisées." +msgid "" +"When enabled, the width and height values for new images are initialized " +"from the current image's dimensions. When disabled, default values are " +"used." +msgstr "" +"Si le réglage est activé, les valeurs de largeur et de hauteur pour les " +"nouvelles images sont initialisées à partir des dimensions de l'image " +"actuelle. Lorsque désactivé, les valeurs par défaut sont utilisées." msgid "**FFT shift**" msgstr "**Décalage FFT**" -msgid "Enable FFT shift to center the zero-frequency component in the frequency spectrum for easier visualization and analysis." -msgstr "Activer le décalage FFT pour centrer la composante de fréquence nulle dans le spectre de fréquences pour une visualisation et une analyse plus faciles." +msgid "" +"Enable FFT shift to center the zero-frequency component in the frequency " +"spectrum for easier visualization and analysis." +msgstr "" +"Activer le décalage FFT pour centrer la composante de fréquence nulle " +"dans le spectre de fréquences pour une visualisation et une analyse plus " +"faciles." msgid "**Extract multiple ROIs in a single object**" msgstr "**Extraire plusieurs ROI dans un seul objet**" -msgid "When enabled, multiple regions of interest (ROIs) are extracted into a single object. When disabled, each ROI is extracted into a separate object." -msgstr "Lorsque cette option est activée, plusieurs régions d'intérêt (ROI) sont extraites dans un seul objet. Lorsqu'elle est désactivée, chaque ROI est extraite dans un objet distinct." +msgid "" +"When enabled, multiple regions of interest (ROIs) are extracted into a " +"single object. When disabled, each ROI is extracted into a separate " +"object." +msgstr "" +"Lorsque cette option est activée, plusieurs régions d'intérêt (ROI) sont " +"extraites dans un seul objet. Lorsqu'elle est désactivée, chaque ROI est " +"extraite dans un objet distinct." msgid "**Ignore warnings**" msgstr "**Ignorer les avertissements**" @@ -182,8 +322,12 @@ msgstr "Supprimer les messages d'avertissement pendant les calculs." msgid "**X-array compatibility behavior**" msgstr "**Comportement de compatibilité des tableaux des X**" -msgid "Choose the behavior when X arrays are incompatible in multi-signal computations:" -msgstr "Choisir le comportement lorsque les tableaux des X sont incompatibles dans les calculs multi-signaux :" +msgid "" +"Choose the behavior when X arrays are incompatible in multi-signal " +"computations:" +msgstr "" +"Choisir le comportement lorsque les tableaux des X sont incompatibles " +"dans les calculs multi-signaux :" msgid "**Ask**: display a confirmation dialog (default)" msgstr "**Demander** : afficher une boîte de dialogue de confirmation (par défaut)" @@ -194,23 +338,43 @@ msgstr "**Interpoler** : interpoler automatiquement les signaux" msgid "History sessions" msgstr "Sessions d'historique" -msgid "These settings control how new inputs are assigned to history sessions. They are evaluated only when **Record mode** is enabled and the target Signals or Images panel has a populated active session. No policy decision is needed when the active session is empty. The two data panels keep separate active sessions; see :ref:`historypanel` for the complete workflow." -msgstr "Ces paramètres déterminent comment les nouvelles entrées sont affectées aux sessions d'historique. Ils ne sont évalués que lorsque le **Mode d'enregistrement** est activé et que le panneau Signaux ou Images cible possède une session active non vide. Aucune décision de politique n'est nécessaire lorsque la session active est vide. Les deux panneaux de données conservent des sessions actives distinctes ; voir :ref:`historypanel` pour le flux de travail complet." +msgid "" +"These settings control how new inputs are assigned to history sessions. " +"They are evaluated only when **Record mode** is enabled and the shared " +"active session contains actions. No policy decision is needed when the " +"active session is empty; see :ref:`historypanel` for the complete " +"workflow." +msgstr "" +"Ces paramètres déterminent comment les nouvelles entrées sont affectées " +"aux sessions d'historique. Ils ne sont évalués que lorsque le **Mode " +"d'enregistrement** est activé et que la session active partagée contient des " +"actions. Aucune décision de politique n'est nécessaire lorsque la session " +"active est vide ; voir :ref:`historypanel` pour le flux de travail complet." msgid "**New object or file**" msgstr "**Nouvel objet ou fichier**" msgid "Choose what happens when a new object is created or a file is loaded:" -msgstr "Choisir ce qui se produit lorsqu'un nouvel objet est créé ou qu'un fichier est chargé :" +msgstr "" +"Choisir ce qui se produit lorsqu'un nouvel objet est créé ou qu'un " +"fichier est chargé :" msgid "**Ask** (default): ask whether to start a new session" -msgstr "**Demander** (par défaut) : demander s'il faut démarrer une nouvelle session" +msgstr "" +"**Demander** (par défaut) : demander s'il faut démarrer une nouvelle " +"session" msgid "**Always start a new session**: start a session before recording the input" -msgstr "**Toujours démarrer une nouvelle session** : démarrer une session avant d'enregistrer l'entrée" +msgstr "" +"**Toujours démarrer une nouvelle session** : démarrer une session avant " +"d'enregistrer l'entrée" -msgid "**Continue in the current session**: append the input to the active session" -msgstr "**Continuer dans la session courante** : ajouter l'entrée à la session active" +msgid "" +"**Continue in the current session**: append the input to the active " +"session" +msgstr "" +"**Continuer dans la session courante** : ajouter l'entrée à la session " +"active" msgid "**Plugin-created object**" msgstr "**Objet créé par un plugin**" @@ -221,29 +385,59 @@ msgstr "Choisir ce qui se produit lorsqu'un plugin ajoute un objet :" msgid "**Ask**: ask whether to start a new session" msgstr "**Demander** : demander s'il faut démarrer une nouvelle session" -msgid "**Always start a new session**: start a session before recording the object" -msgstr "**Toujours démarrer une nouvelle session** : démarrer une session avant d'enregistrer l'objet" +msgid "" +"**Always start a new session**: start a session before recording the " +"object" +msgstr "" +"**Toujours démarrer une nouvelle session** : démarrer une session avant " +"d'enregistrer l'objet" -msgid "**Continue in the current session** (default): append the object without a modal prompt, so plugin execution is not blocked" -msgstr "**Continuer dans la session courante** (par défaut) : ajouter l'objet sans afficher de boîte de dialogue modale, afin de ne pas bloquer l'exécution du plugin" +msgid "" +"**Continue in the current session** (default): append the object without " +"a modal prompt, so plugin execution is not blocked" +msgstr "" +"**Continuer dans la session courante** (par défaut) : ajouter l'objet " +"sans afficher de boîte de dialogue modale, afin de ne pas bloquer " +"l'exécution du plugin" msgid "**Plugin multi-load**" msgstr "**Chargement multiple par un plugin**" -msgid "Choose what happens when a plugin explicitly groups several object additions in one multi-load scope:" -msgstr "Choisir ce qui se produit lorsqu'un plugin regroupe explicitement plusieurs ajouts d'objets dans une même portée de chargement multiple :" +msgid "" +"Choose what happens when a plugin explicitly groups several object " +"additions in one multi-load scope:" +msgstr "" +"Choisir ce qui se produit lorsqu'un plugin regroupe explicitement " +"plusieurs ajouts d'objets dans une même portée de chargement multiple :" msgid "**Ask once**: ask once whether the whole batch should start a new session" -msgstr "**Demander une seule fois** : demander une seule fois si l'ensemble du lot doit démarrer une nouvelle session" +msgstr "" +"**Demander une seule fois** : demander une seule fois si l'ensemble du " +"lot doit démarrer une nouvelle session" msgid "**Start a new session**: start one session for the batch" msgstr "**Démarrer une nouvelle session** : démarrer une seule session pour le lot" -msgid "**Continue in the current session** (default): append the whole batch to the active session" -msgstr "**Continuer dans la session courante** (par défaut) : ajouter l'ensemble du lot à la session active" +msgid "" +"**Continue in the current session** (default): append the whole batch to " +"the active session" +msgstr "" +"**Continuer dans la session courante** (par défaut) : ajouter l'ensemble " +"du lot à la session active" -msgid "**Ask once** is the UI label for one durable session decision covering the complete explicit plugin multi-load scope, rather than one prompt per object. With ordinary **Ask** behavior, repeated prompts for synchronous additions to the same panel are debounced during the current Qt event-loop turn." -msgstr "**Demander une seule fois** est le libellé de l'interface correspondant à une décision de session unique et durable qui couvre toute la portée explicite de chargement multiple du plugin, plutôt qu'à une demande par objet. Avec le comportement **Demander** ordinaire, un mécanisme anti-rebond évite les demandes répétées pour les ajouts synchrones au même panneau pendant le tour courant de la boucle d'événements Qt." +msgid "" +"**Ask once** is the UI label for one durable session decision covering " +"the complete explicit plugin multi-load scope, rather than one prompt per" +" object. With ordinary **Ask** behavior, repeated prompts for synchronous" +" additions to the same panel are debounced during the current Qt event-" +"loop turn." +msgstr "" +"**Demander une seule fois** est le libellé de l'interface correspondant à" +" une décision de session unique et durable qui couvre toute la portée " +"explicite de chargement multiple du plugin, plutôt qu'à une demande par " +"objet. Avec le comportement **Demander** ordinaire, un mécanisme anti-" +"rebond évite les demandes répétées pour les ajouts synchrones au même " +"panneau pendant le tour courant de la boucle d'événements Qt." msgid "Result management" msgstr "Gestion des résultats" @@ -251,26 +445,51 @@ msgstr "Gestion des résultats" msgid "**Keep results in metadata after computation**" msgstr "**Conserver les résultats dans les métadonnées après le calcul**" -msgid "When enabled, results from previous analyses are kept in the object's metadata after computation. When disabled, results are removed. This option is disabled by default to avoid confusion from outdated results." -msgstr "Si le réglage est activé, les résultats des analyses précédentes sont conservés dans les métadonnées de l'objet après le calcul. Lorsque désactivé, les résultats sont supprimés. Cette option est désactivée par défaut pour éviter toute confusion due à des résultats obsolètes." +msgid "" +"When enabled, results from previous analyses are kept in the object's " +"metadata after computation. When disabled, results are removed. This " +"option is disabled by default to avoid confusion from outdated results." +msgstr "" +"Si le réglage est activé, les résultats des analyses précédentes sont " +"conservés dans les métadonnées de l'objet après le calcul. Lorsque " +"désactivé, les résultats sont supprimés. Cette option est désactivée par " +"défaut pour éviter toute confusion due à des résultats obsolètes." msgid "**Show results dialog automatically after processing**" -msgstr "**Afficher automatiquement la boîte de dialogue des résultats après le traitement**" +msgstr "" +"**Afficher automatiquement la boîte de dialogue des résultats après le " +"traitement**" -msgid "When enabled, the results dialog is shown automatically after each processing operation producing results. When disabled, the results dialog is not shown automatically but results can still be viewed using the dedicated button or menu option." -msgstr "Si le réglage est activé, la boîte de dialogue des résultats est affichée automatiquement après chaque opération de traitement produisant des résultats. Lorsque désactivé, la boîte de dialogue des résultats n'est pas affichée automatiquement, mais les résultats peuvent toujours être consultés à l'aide du bouton ou de l'option de menu dédiée." +msgid "" +"When enabled, the results dialog is shown automatically after each " +"processing operation producing results. When disabled, the results dialog" +" is not shown automatically but results can still be viewed using the " +"dedicated button or menu option." +msgstr "" +"Si le réglage est activé, la boîte de dialogue des résultats est affichée" +" automatiquement après chaque opération de traitement produisant des " +"résultats. Lorsque désactivé, la boîte de dialogue des résultats n'est " +"pas affichée automatiquement, mais les résultats peuvent toujours être " +"consultés à l'aide du bouton ou de l'option de menu dédiée." msgid "Visualization" msgstr "Visualisation" -msgid "The Visualization settings tab controls how data is displayed. This tab is organized into four sub-tabs: Common, Signals, Images, and Results." -msgstr "L'onglet des préférences de visualisation contrôle comment les données sont affichées. Cet onglet est organisé en quatre sous-onglets : Commun, Signaux, Images et Résultats." +msgid "" +"The Visualization settings tab controls how data is displayed. This tab " +"is organized into four sub-tabs: Common, Signals, Images, and Results." +msgstr "" +"L'onglet des préférences de visualisation contrôle comment les données " +"sont affichées. Cet onglet est organisé en quatre sous-onglets : Commun, " +"Signaux, Images et Résultats." msgid "Common settings" msgstr "Paramètres communs" msgid "The Common sub-tab contains settings that apply to all visualizations:" -msgstr "Le sous-onglet Commun contient des paramètres qui s'appliquent à toutes les visualisations :" +msgstr "" +"Le sous-onglet Commun contient des paramètres qui s'appliquent à toutes " +"les visualisations :" msgid "Visualization settings - Common sub-tab" msgstr "Préférences de visualisation - Sous-onglet Commun" @@ -278,20 +497,30 @@ msgstr "Préférences de visualisation - Sous-onglet Commun" msgid "**Plot toolbar position**" msgstr "**Position de la barre d'outils de tracé**" -msgid "Choose where to position the plot toolbar (top, bottom, left, or right of the plot)." -msgstr "Choisir où positionner la barre d'outils de tracé (en haut, en bas, à gauche ou à droite du tracé)." +msgid "" +"Choose where to position the plot toolbar (top, bottom, left, or right of" +" the plot)." +msgstr "" +"Choisir où positionner la barre d'outils de tracé (en haut, en bas, à " +"gauche ou à droite du tracé)." msgid "**Ignore title insertion message**" msgstr "**Ignorer le message d'insertion de titre**" -msgid "Suppress the information message when inserting an object title as an annotation label." -msgstr "Supprimer le message d'information lors de l'insertion d'un titre d'objet comme étiquette d'annotation." +msgid "" +"Suppress the information message when inserting an object title as an " +"annotation label." +msgstr "" +"Supprimer le message d'information lors de l'insertion d'un titre d'objet" +" comme étiquette d'annotation." msgid "Signals" msgstr "Signaux" msgid "The Signals sub-tab contains settings specific to signal visualizations:" -msgstr "Le sous-onglet Signaux contient des paramètres spécifiques aux visualisations de signaux :" +msgstr "" +"Le sous-onglet Signaux contient des paramètres spécifiques aux " +"visualisations de signaux :" msgid "Visualization settings - Signals sub-tab" msgstr "Préférences de visualisation - Sous-onglet Signaux" @@ -299,52 +528,112 @@ msgstr "Préférences de visualisation - Sous-onglet Signaux" msgid "**Default line width**" msgstr "**Épaisseur par défaut**" -msgid "Default line width for curves representing signals. This setting affects all signal visualizations unless overridden individually. Note: for signals exceeding the line width performance threshold (see below), the line width is automatically clamped to 1.0 for optimal rendering performance." -msgstr "Épaisseur de trait par défaut pour les courbes représentant les signaux. Ce paramètre affecte toutes les visualisations de signaux, sauf si elles sont remplacées individuellement. Remarque : pour les signaux dépassant le seuil de performance de l'épaisseur de trait (voir ci-dessous), l'épaisseur de trait est automatiquement plafonnée à 1,0 pour des performances de rendu optimales." +msgid "" +"Default line width for curves representing signals. This setting affects " +"all signal visualizations unless overridden individually. Note: for " +"signals exceeding the line width performance threshold (see below), the " +"line width is automatically clamped to 1.0 for optimal rendering " +"performance." +msgstr "" +"Épaisseur de trait par défaut pour les courbes représentant les signaux. " +"Ce paramètre affecte toutes les visualisations de signaux, sauf si elles " +"sont remplacées individuellement. Remarque : pour les signaux dépassant " +"le seuil de performance de l'épaisseur de trait (voir ci-dessous), " +"l'épaisseur de trait est automatiquement plafonnée à 1,0 pour des " +"performances de rendu optimales." msgid "**Line width performance threshold**" msgstr "**Seuil de performance de l'épaisseur de trait**" -msgid "For signals with more than this number of points (default: 1,000), line width is automatically limited to 1.0 for performance reasons. This prevents the ~10x rendering slowdown caused by Qt's raster engine when drawing thick lines (width > 1.0) on large datasets. For smaller signals, the configured default line width applies normally. This optimization is transparent and requires no user intervention." -msgstr "Pour les signaux comportant plus de ce nombre de points (par défaut : 1 000), l'épaisseur de trait est automatiquement limitée à 1,0 pour des raisons de performance. Cela évite le ralentissement du rendu d'environ 10x causé par le moteur raster de Qt lors du dessin de lignes épaisses (largeur > 1,0) sur de grands ensembles de données. Pour les signaux plus petits, l'épaisseur de trait par défaut configurée s'applique normalement. Cette optimisation est transparente et ne nécessite aucune intervention de l'utilisateur." +msgid "" +"For signals with more than this number of points (default: 1,000), line " +"width is automatically limited to 1.0 for performance reasons. This " +"prevents the ~10x rendering slowdown caused by Qt's raster engine when " +"drawing thick lines (width > 1.0) on large datasets. For smaller signals," +" the configured default line width applies normally. This optimization is" +" transparent and requires no user intervention." +msgstr "" +"Pour les signaux comportant plus de ce nombre de points (par défaut : 1 " +"000), l'épaisseur de trait est automatiquement limitée à 1,0 pour des " +"raisons de performance. Cela évite le ralentissement du rendu d'environ " +"10x causé par le moteur raster de Qt lors du dessin de lignes épaisses " +"(largeur > 1,0) sur de grands ensembles de données. Pour les signaux plus" +" petits, l'épaisseur de trait par défaut configurée s'applique " +"normalement. Cette optimisation est transparente et ne nécessite aucune " +"intervention de l'utilisateur." msgid "**Use auto downsampling**" msgstr "**Utiliser le sous-échantillonnage automatique**" -msgid "Enable automatic downsampling for large signals to improve performance and visualization clarity." -msgstr "Activer le sous-échantillonnage automatique pour les grands signaux afin d'améliorer les performances et la clarté de la visualisation." +msgid "" +"Enable automatic downsampling for large signals to improve performance " +"and visualization clarity." +msgstr "" +"Activer le sous-échantillonnage automatique pour les grands signaux afin " +"d'améliorer les performances et la clarté de la visualisation." msgid "**Downsampling max points**" msgstr "**Nombre maximum de points de sous-échantillonnage**" -msgid "Maximum number of points to display when downsampling is enabled (default: 10,000)." -msgstr "Nombre maximum de points à afficher lorsque le sous-échantillonnage est activé (par défaut : 10 000)." +msgid "" +"Maximum number of points to display when downsampling is enabled " +"(default: 10,000)." +msgstr "" +"Nombre maximum de points à afficher lorsque le sous-échantillonnage est " +"activé (par défaut : 10 000)." msgid "**Autoscale margin**" msgstr "**Marge d'échelle automatique**" #, python-format -msgid "Percentage of margin to add around data when auto-scaling signal plots. A value of 0.2% adds a small margin for better visualization. Set to 0% for no margin (exact data bounds)." -msgstr "Pourcentage de marge à ajouter autour des données lors de la mise à l'échelle automatique des tracés de signaux. Une valeur de 0,2 % ajoute une petite marge pour une meilleure visualisation. Mettre à 0 % pour aucune marge (bornes de données exactes)." +msgid "" +"Percentage of margin to add around data when auto-scaling signal plots. A" +" value of 0.2% adds a small margin for better visualization. Set to 0% " +"for no margin (exact data bounds)." +msgstr "" +"Pourcentage de marge à ajouter autour des données lors de la mise à " +"l'échelle automatique des tracés de signaux. Une valeur de 0,2 % ajoute " +"une petite marge pour une meilleure visualisation. Mettre à 0 % pour " +"aucune marge (bornes de données exactes)." msgid "**DateTime format (s/min/h)**" msgstr "**Format DateTime (s/min/h)**" -msgid "Format string for datetime X-axis labels when using standard time units (s, min, h). Uses Python's strftime format codes (e.g., %H:%M:%S for hours:minutes:seconds)." -msgstr "Chaîne de format pour les étiquettes de l'axe X datetime lors de l'utilisation d'unités de temps standard (s, min, h). Utilise les codes de format strftime de Python (par exemple, %H:%M:%S pour heures:minutes:secondes)." +msgid "" +"Format string for datetime X-axis labels when using standard time units " +"(s, min, h). Uses Python's strftime format codes (e.g., %H:%M:%S for " +"hours:minutes:seconds)." +msgstr "" +"Chaîne de format pour les étiquettes de l'axe X datetime lors de " +"l'utilisation d'unités de temps standard (s, min, h). Utilise les codes " +"de format strftime de Python (par exemple, %H:%M:%S pour " +"heures:minutes:secondes)." msgid "**DateTime format (ms/μs/ns)**" msgstr "**Format DateTime (ms/μs/ns)**" #, python-format -msgid "Format string for datetime X-axis labels when using sub-second time units (ms, μs, ns). Uses Python's strftime format codes (e.g., %H:%M:%S.%f for hours:minutes:seconds.microseconds)." -msgstr "Chaîne de format pour les étiquettes de l'axe X datetime lors de l'utilisation d'unités de temps infra-secondes (ms, μs, ns). Utilise les codes de format strftime de Python (par exemple, %H:%M:%S.%f pour heures:minutes:secondes.microsecondes)." +msgid "" +"Format string for datetime X-axis labels when using sub-second time units" +" (ms, μs, ns). Uses Python's strftime format codes (e.g., %H:%M:%S.%f for" +" hours:minutes:seconds.microseconds)." +msgstr "" +"Chaîne de format pour les étiquettes de l'axe X datetime lors de " +"l'utilisation d'unités de temps infra-secondes (ms, μs, ns). Utilise les " +"codes de format strftime de Python (par exemple, %H:%M:%S.%f pour " +"heures:minutes:secondes.microsecondes)." msgid "**Results: edit shape styles**" msgstr "**Résultats : modifier les styles de forme**" -msgid "Click this button to configure the visual style for annotation shapes (rectangles, circles, segments, etc.) displayed on signal plots. This includes:" -msgstr "Cliquer sur ce bouton pour configurer le style visuel des formes d'annotation (rectangles, cercles, segments, etc.) affichées sur les tracés de signaux. Cela inclut :" +msgid "" +"Click this button to configure the visual style for annotation shapes " +"(rectangles, circles, segments, etc.) displayed on signal plots. This " +"includes:" +msgstr "" +"Cliquer sur ce bouton pour configurer le style visuel des formes " +"d'annotation (rectangles, cercles, segments, etc.) affichées sur les " +"tracés de signaux. Cela inclut :" msgid "Line style, color, and width" msgstr "Style de ligne, couleur et largeur" @@ -355,14 +644,23 @@ msgstr "Motif de remplissage, couleur et transparence" msgid "Symbol shape, size, and colors" msgstr "Forme du symbole, taille et couleurs" -msgid "These settings apply to all result shapes drawn on signal plots (e.g., peak markers, FWHM indicators, feature detection results)." -msgstr "Ces paramètres s'appliquent à toutes les formes de résultats dessinées sur les tracés de signaux (par exemple, les marqueurs de pics, les indicateurs FWHM, les résultats de détection de caractéristiques)." +msgid "" +"These settings apply to all result shapes drawn on signal plots (e.g., " +"peak markers, FWHM indicators, feature detection results)." +msgstr "" +"Ces paramètres s'appliquent à toutes les formes de résultats dessinées " +"sur les tracés de signaux (par exemple, les marqueurs de pics, les " +"indicateurs FWHM, les résultats de détection de caractéristiques)." msgid "**Results: edit marker styles**" msgstr "**Résultats : modifier les styles de marqueur**" -msgid "Click this button to configure the visual style for cursor markers on signal plots. This includes:" -msgstr "Cliquer sur ce bouton pour configurer le style visuel des marqueurs de curseur sur les tracés de signaux. Cela inclut :" +msgid "" +"Click this button to configure the visual style for cursor markers on " +"signal plots. This includes:" +msgstr "" +"Cliquer sur ce bouton pour configurer le style visuel des marqueurs de " +"curseur sur les tracés de signaux. Cela inclut :" msgid "Symbol appearance" msgstr "Apparence du symbole" @@ -373,14 +671,20 @@ msgstr "Formatage et positionnement des étiquettes de texte" msgid "Background transparency" msgstr "Transparence de l'arrière-plan" -msgid "These settings apply to cursor-type markers used in signal analysis results." -msgstr "Ces paramètres s'appliquent aux marqueurs de type curseur utilisés dans les résultats d'analyse de signaux." +msgid "" +"These settings apply to cursor-type markers used in signal analysis " +"results." +msgstr "" +"Ces paramètres s'appliquent aux marqueurs de type curseur utilisés dans " +"les résultats d'analyse de signaux." msgid "Images" msgstr "Images" msgid "The Images sub-tab contains settings specific to image visualizations:" -msgstr "Le sous-onglet Images contient des paramètres spécifiques aux visualisations d'images :" +msgstr "" +"Le sous-onglet Images contient des paramètres spécifiques aux " +"visualisations d'images :" msgid "Visualization settings - Images sub-tab" msgstr "Préférences de visualisation - Sous-onglet Images" @@ -388,75 +692,154 @@ msgstr "Préférences de visualisation - Sous-onglet Images" msgid "**Lock aspect ratio to 1:1**" msgstr "**Verrouiller le rapport d'aspect à 1:1**" -msgid "When enabled, the aspect ratio of images is locked to 1:1. When disabled, the aspect ratio is determined by the physical pixel size (default and recommended setting)." -msgstr "Si le réglage est activé, le rapport d'aspect des images est verrouillé à 1:1. Lorsque désactivé, le rapport d'aspect est déterminé par la taille physique du pixel (paramètre par défaut et recommandé)." +msgid "" +"When enabled, the aspect ratio of images is locked to 1:1. When disabled," +" the aspect ratio is determined by the physical pixel size (default and " +"recommended setting)." +msgstr "" +"Si le réglage est activé, le rapport d'aspect des images est verrouillé à" +" 1:1. Lorsque désactivé, le rapport d'aspect est déterminé par la taille " +"physique du pixel (paramètre par défaut et recommandé)." msgid "**Eliminate outliers**" msgstr "**Éliminer les valeurs aberrantes**" -msgid "Percentage of the highest and lowest values to eliminate from the image histogram. Recommended values are below 1%." -msgstr "Pourcentage des valeurs les plus élevées et les plus basses à éliminer de l'histogramme de l'image. Les valeurs recommandées sont inférieures à 1 %." +msgid "" +"Percentage of the highest and lowest values to eliminate from the image " +"histogram. Recommended values are below 1%." +msgstr "" +"Pourcentage des valeurs les plus élevées et les plus basses à éliminer de" +" l'histogramme de l'image. Les valeurs recommandées sont inférieures à 1 " +"%." #, python-format -msgid "Percentage of margin to add around data when auto-scaling image plots. A value of 0.2% adds a small margin for better visualization. Set to 0% for no margin (exact data bounds)." -msgstr "Pourcentage de marge à ajouter autour des données lors de la mise à l'échelle automatique des tracés d'images. Une valeur de 0,2 % ajoute une petite marge pour une meilleure visualisation. Mettre à 0 % pour aucune marge (bornes de données exactes)." +msgid "" +"Percentage of margin to add around data when auto-scaling image plots. A " +"value of 0.2% adds a small margin for better visualization. Set to 0% for" +" no margin (exact data bounds)." +msgstr "" +"Pourcentage de marge à ajouter autour des données lors de la mise à " +"l'échelle automatique des tracés d'images. Une valeur de 0,2 % ajoute une" +" petite marge pour une meilleure visualisation. Mettre à 0 % pour aucune " +"marge (bornes de données exactes)." msgid "**Default image visualization settings**" msgstr "**Paramètres de visualisation d'image par défaut**" -msgid "Click this button to configure default visualization settings for images (colormap, interpolation, contrast, etc.)." -msgstr "Cliquer sur ce bouton pour configurer les paramètres de visualisation par défaut pour les images (carte de couleurs, interpolation, contraste, etc.)." +msgid "" +"Click this button to configure default visualization settings for images " +"(colormap, interpolation, contrast, etc.)." +msgstr "" +"Cliquer sur ce bouton pour configurer les paramètres de visualisation par" +" défaut pour les images (carte de couleurs, interpolation, contraste, " +"etc.)." -msgid "Click this button to configure the visual style for annotation shapes displayed on image plots. Parameters are similar to signal shapes but optimized for image visualization (e.g., different colors for better visibility on images)." -msgstr "Cliquer sur ce bouton pour configurer le style visuel des formes d'annotation affichées sur les tracés d'images. Les paramètres sont similaires à ceux des formes de signaux mais optimisés pour la visualisation d'images (par exemple, différentes couleurs pour une meilleure visibilité sur les images)." +msgid "" +"Click this button to configure the visual style for annotation shapes " +"displayed on image plots. Parameters are similar to signal shapes but " +"optimized for image visualization (e.g., different colors for better " +"visibility on images)." +msgstr "" +"Cliquer sur ce bouton pour configurer le style visuel des formes " +"d'annotation affichées sur les tracés d'images. Les paramètres sont " +"similaires à ceux des formes de signaux mais optimisés pour la " +"visualisation d'images (par exemple, différentes couleurs pour une " +"meilleure visibilité sur les images)." -msgid "Click this button to configure the visual style for cursor markers on image plots." -msgstr "Cliquer sur ce bouton pour configurer le style visuel des marqueurs de curseur sur les tracés d'images." +msgid "" +"Click this button to configure the visual style for cursor markers on " +"image plots." +msgstr "" +"Cliquer sur ce bouton pour configurer le style visuel des marqueurs de " +"curseur sur les tracés d'images." msgid "Results" msgstr "Résultats" -msgid "The Results sub-tab contains settings for displaying analysis results on plots:" -msgstr "L'onglet des préférences de résultats contient des paramètres pour l'affichage des résultats d'analyse sur les graphiques :" +msgid "" +"The Results sub-tab contains settings for displaying analysis results on " +"plots:" +msgstr "" +"L'onglet des préférences de résultats contient des paramètres pour " +"l'affichage des résultats d'analyse sur les graphiques :" msgid "Visualization settings - Results sub-tab" msgstr "Préférences de visualisation - Sous-onglet Résultats" -msgid "These settings control how analysis results are displayed on plots to prevent performance issues with large datasets:" -msgstr "Ces paramètres contrôlent la façon dont les résultats d'analyse sont affichés sur les graphiques afin de limiter les problèmes de performance avec de grands ensembles de données :" +msgid "" +"These settings control how analysis results are displayed on plots to " +"prevent performance issues with large datasets:" +msgstr "" +"Ces paramètres contrôlent la façon dont les résultats d'analyse sont " +"affichés sur les graphiques afin de limiter les problèmes de performance " +"avec de grands ensembles de données :" msgid "**Maximum shapes to draw**" msgstr "**Nombre maximum de formes à dessiner**" -msgid "Maximum number of geometry shapes to draw on the plot (default: 1,000). When the number of shapes exceeds this limit, only the first N shapes are drawn and a warning label is displayed." -msgstr "Nombre maximum de formes géométriques à dessiner sur le graphique (par défaut : 1 000). Lorsque le nombre de formes dépasse cette limite, seules les N premières formes sont dessinées et une étiquette d'avertissement est affichée." +msgid "" +"Maximum number of geometry shapes to draw on the plot (default: 1,000). " +"When the number of shapes exceeds this limit, only the first N shapes are" +" drawn and a warning label is displayed." +msgstr "" +"Nombre maximum de formes géométriques à dessiner sur le graphique (par " +"défaut : 1 000). Lorsque le nombre de formes dépasse cette limite, seules" +" les N premières formes sont dessinées et une étiquette d'avertissement " +"est affichée." msgid "**Maximum cells in label**" msgstr "**Nombre maximum de cellules dans l'étiquette**" -msgid "Maximum number of table cells (rows × columns) to display in merged result labels on plots (default: 100). When the number of cells exceeds this limit, the table is truncated." -msgstr "Nombre maximum de cellules de tableau (lignes × colonnes) à afficher dans les étiquettes de résultats fusionnés sur les graphiques (par défaut : 100). Lorsque le nombre de cellules dépasse cette limite, le tableau est tronqué." +msgid "" +"Maximum number of table cells (rows × columns) to display in merged " +"result labels on plots (default: 100). When the number of cells exceeds " +"this limit, the table is truncated." +msgstr "" +"Nombre maximum de cellules de tableau (lignes × colonnes) à afficher dans" +" les étiquettes de résultats fusionnés sur les graphiques (par défaut : " +"100). Lorsque le nombre de cellules dépasse cette limite, le tableau est " +"tronqué." msgid "**Maximum columns in label**" msgstr "**Nombre maximum de colonnes dans l'étiquette**" -msgid "Maximum number of columns to display in merged result labels (default: 15). When the number of columns exceeds this limit, only the first N columns are displayed." -msgstr "Nombre maximum de colonnes à afficher dans les étiquettes de résultats fusionnés (par défaut : 15). Lorsque le nombre de colonnes dépasse cette limite, seules les N premières colonnes sont affichées." +msgid "" +"Maximum number of columns to display in merged result labels (default: " +"15). When the number of columns exceeds this limit, only the first N " +"columns are displayed." +msgstr "" +"Nombre maximum de colonnes à afficher dans les étiquettes de résultats " +"fusionnés (par défaut : 15). Lorsque le nombre de colonnes dépasse cette " +"limite, seules les N premières colonnes sont affichées." msgid "**Show the merged result label by default**" msgstr "**Afficher l'étiquette de résultat fusionné par défaut**" -msgid "When enabled, the merged result label is shown on the plot by default for new objects. This setting can be toggled per-object using the checkbox in the Properties panel." -msgstr "Si le réglage est activé, l'étiquette de résultat fusionné est affichée sur le graphique par défaut pour les nouveaux objets. Ce paramètre peut être basculé par objet à l'aide de la case à cocher dans le panneau Propriétés." +msgid "" +"When enabled, the merged result label is shown on the plot by default for" +" new objects. This setting can be toggled per-object using the checkbox " +"in the Properties panel." +msgstr "" +"Si le réglage est activé, l'étiquette de résultat fusionné est affichée " +"sur le graphique par défaut pour les nouveaux objets. Ce paramètre peut " +"être basculé par objet à l'aide de la case à cocher dans le panneau " +"Propriétés." -msgid "These settings affect only the visualization of results on plots. They do not affect the actual computation or storage of results in metadata." -msgstr "Ces paramètres n'affectent que la visualisation des résultats sur les graphiques. Ils n'affectent pas le calcul réel ou le stockage des résultats dans les métadonnées." +msgid "" +"These settings affect only the visualization of results on plots. They do" +" not affect the actual computation or storage of results in metadata." +msgstr "" +"Ces paramètres n'affectent que la visualisation des résultats sur les " +"graphiques. Ils n'affectent pas le calcul réel ou le stockage des " +"résultats dans les métadonnées." msgid "I/O" msgstr "Entrée/sortie" msgid "The I/O settings tab controls input/output operations:" -msgstr "L'onglet des préférences d'entrée/sortie contrôle les opérations d'entrée/sortie :" +msgstr "" +"L'onglet des préférences d'entrée/sortie contrôle les opérations " +"d'entrée/sortie :" msgid "I/O settings tab" msgstr "Onglet des préférences d'entrée/sortie" @@ -465,31 +848,50 @@ msgid "**Clear workspace before loading HDF5 file**" msgstr "**Effacer l'espace de travail avant de charger le fichier HDF5**" msgid "When enabled, the workspace is cleared before loading an HDF5 file." -msgstr "Si le réglage est activé, l'espace de travail est effacé avant de charger un fichier HDF5." +msgstr "" +"Si le réglage est activé, l'espace de travail est effacé avant de charger" +" un fichier HDF5." msgid "**Ask before clearing workspace**" msgstr "**Demander avant d'effacer l'espace de travail**" -msgid "When enabled, a confirmation dialog is displayed before clearing the workspace." -msgstr "Si le réglage est activé, une boîte de dialogue de confirmation est affichée avant d'effacer l'espace de travail." +msgid "" +"When enabled, a confirmation dialog is displayed before clearing the " +"workspace." +msgstr "" +"Si le réglage est activé, une boîte de dialogue de confirmation est " +"affichée avant d'effacer l'espace de travail." msgid "**HDF5 full path in title**" msgstr "**Chemin complet HDF5 dans le titre**" -msgid "When enabled, the full path of the HDF5 dataset is used as the title for the signal/image object. When disabled, only the dataset name is used." -msgstr "Si le réglage est activé, le chemin complet du jeu de données HDF5 est utilisé comme titre pour l'objet signal/image. Lorsque désactivé, seul le nom du jeu de données est utilisé." +msgid "" +"When enabled, the full path of the HDF5 dataset is used as the title for " +"the signal/image object. When disabled, only the dataset name is used." +msgstr "" +"Si le réglage est activé, le chemin complet du jeu de données HDF5 est " +"utilisé comme titre pour l'objet signal/image. Lorsque désactivé, seul le" +" nom du jeu de données est utilisé." msgid "**HDF5 file name in title**" msgstr "**Nom de fichier HDF5 dans le titre**" -msgid "When enabled, the HDF5 file name is appended as a suffix to the title of the signal/image object." -msgstr "Si le réglage est activé, le nom du fichier HDF5 est ajouté comme suffixe au titre de l'objet signal/image." +msgid "" +"When enabled, the HDF5 file name is appended as a suffix to the title of " +"the signal/image object." +msgstr "" +"Si le réglage est activé, le nom du fichier HDF5 est ajouté comme suffixe" +" au titre de l'objet signal/image." msgid "Console" msgstr "Console" -msgid "The Console settings tab configures the internal console for debugging and advanced users:" -msgstr "L'onglet des préférences de console configure la console interne pour le débogage et les utilisateurs avancés :" +msgid "" +"The Console settings tab configures the internal console for debugging " +"and advanced users:" +msgstr "" +"L'onglet des préférences de console configure la console interne pour le " +"débogage et les utilisateurs avancés :" msgid "Console settings tab" msgstr "Onglet des préférences de console" @@ -503,14 +905,24 @@ msgstr "Activer la console Python interne pour le débogage et les scripts avanc msgid "**Show console on error**" msgstr "**Afficher la console en cas d'erreur**" -msgid "When enabled, the console is automatically shown when an error occurs in the application. This is useful for debugging as it allows you to see the error traceback." -msgstr "Si le réglage est activé, la console est automatiquement affichée lorsqu'une erreur se produit dans l'application. Ceci est utile pour le débogage car cela permet de voir la trace d'erreur." +msgid "" +"When enabled, the console is automatically shown when an error occurs in " +"the application. This is useful for debugging as it allows you to see the" +" error traceback." +msgstr "" +"Si le réglage est activé, la console est automatiquement affichée " +"lorsqu'une erreur se produit dans l'application. Ceci est utile pour le " +"débogage car cela permet de voir la trace d'erreur." msgid "**External editor path**" msgstr "**Chemin de l'éditeur externe**" -msgid "Path to an external text editor to use for editing Python code from the console." -msgstr "Chemin vers un éditeur de texte externe à utiliser pour éditer du code Python depuis la console." +msgid "" +"Path to an external text editor to use for editing Python code from the " +"console." +msgstr "" +"Chemin vers un éditeur de texte externe à utiliser pour éditer du code " +"Python depuis la console." msgid "**External editor arguments**" msgstr "**Arguments de l'éditeur externe**" diff --git a/doc/locale/fr/LC_MESSAGES/intro/tutorials/blobs.po b/doc/locale/fr/LC_MESSAGES/intro/tutorials/blobs.po index 4e9fe69b1..6a620e563 100644 --- a/doc/locale/fr/LC_MESSAGES/intro/tutorials/blobs.po +++ b/doc/locale/fr/LC_MESSAGES/intro/tutorials/blobs.po @@ -5,16 +5,47 @@ # msgid "" msgstr "" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -msgid ":octicon:`book;1em;sd-text-info` Detecting blobs on an image" -msgstr ":octicon:`book;1em;sd-text-info` Détection de taches sur une image" +msgid "" +"Automatically detect defects, particles or spots on images (blob " +"detection) with DataLab, the open-source signal and image analysis " +"platform: image denoising, automated blob detection, and workspace " +"saving. Also introduces the plugin system." +msgstr "" +"Détectez automatiquement défauts, particules ou taches sur des images " +"(détection de blobs) avec DataLab, la plateforme open-source d'analyse de" +" signaux et d'images : débruitage d'image, détection automatique de " +"taches et enregistrement de l'espace de travail. Présente également le " +"système de plugins." -msgid "This example shows how to detect blobs on an image with DataLab, and also covers other features such as the plugin system:" -msgstr "Cet exemple montre comment détecter des taches sur une image avec DataLab, et couvre également d'autres fonctionnalités telles que le système de plugins :" +msgid "" +"defect detection, particle detection, blob detection, non-destructive " +"testing, automated inspection, image denoising, image analysis software, " +"plugin, DataLab, tutorial" +msgstr "" +"détection de défauts, détection de particules, détection de blobs, " +"contrôle non destructif, inspection automatisée, débruitage d'image, " +"logiciel d'analyse d'images, plugin, DataLab, tutoriel" + +msgid "" +":octicon:`book;1em;sd-text-info` Automated detection of defects and " +"particles on images" +msgstr "" +":octicon:`book;1em;sd-text-info` Détection automatisée de défauts et de " +"particules sur des images" + +msgid "" +"This example shows how to automatically detect blob-like features -- " +"defects, particles, spots -- on an image with DataLab, and also covers " +"other features such as the plugin system:" +msgstr "" +"Cet exemple montre comment détecter automatiquement des éléments de type " +"tache -- défauts, particules, points -- sur une image avec DataLab, et " +"couvre également d'autres fonctionnalités telles que le système de " +"plugins :" msgid "Add a new plugin to DataLab" msgstr "Ajouter un nouveau plugin à DataLab" @@ -28,138 +59,286 @@ msgstr "Détecter des taches sur une image" msgid "Save the workspace to a file" msgstr "Enregistrer l'espace de travail dans un fichier" -msgid "First, we open DataLab, and open the settings dialog (using \"File > Settings...\", or the |libre-gui-settings| icon in the toolbar)." -msgstr "Tout d'abord, nous ouvrons DataLab, et ouvrons la boîte de dialogue des paramètres (en utilisant \"Fichier > Paramètres...\", ou l'icône |libre-gui-settings| dans la barre d'outils)." +msgid "" +"First, we open DataLab, and open the settings dialog (using \"File > " +"Settings...\", or the |libre-gui-settings| icon in the toolbar)." +msgstr "" +"Tout d'abord, nous ouvrons DataLab, et ouvrons la boîte de dialogue des " +"paramètres (en utilisant \"Fichier > Paramètres...\", ou l'icône |libre-" +"gui-settings| dans la barre d'outils)." msgid "libre-gui-settings" msgstr "" -msgid "In the \"General\" tab, we can see the \"Plugins path\" field. This is the path where DataLab will look for plugins. We can add a new plugin by copying/pasting the plugin file in this directory." -msgstr "Dans l'onglet \"Général\", nous pouvons voir le champ \"Chemin des plugins\". C'est le chemin où DataLab recherchera les plugins. Nous pouvons ajouter un nouveau plugin en copiant/collant le fichier du plugin dans ce répertoire." +msgid "" +"In the \"General\" tab, we can see the \"Plugins path\" field. This is " +"the path where DataLab will look for plugins. We can add a new plugin by " +"copying/pasting the plugin file in this directory." +msgstr "" +"Dans l'onglet \"Général\", nous pouvons voir le champ \"Chemin des " +"plugins\". C'est le chemin où DataLab recherchera les plugins. Nous " +"pouvons ajouter un nouveau plugin en copiant/collant le fichier du plugin" +" dans ce répertoire." msgid "The plugin system is described in the :ref:`about_plugins` section." msgstr "Le système de plugins est décrit dans la section :ref:`about_plugins`." -msgid "Let's add the `datalab_example_imageproc.py` plugin to DataLab (this is an example plugin that is shipped with DataLab source package, or may be downloaded from `here <https://github.com/DataLab-Platform/DataLab/tree/main/plugins/examples>`_)." -msgstr "Ajoutons le plugin `datalab_example_imageproc.py` à DataLab (c'est un plugin d'exemple qui est fourni avec le package source de DataLab, ou peut être téléchargé `ici <https://github.com/DataLab-Platform/DataLab/tree/main/plugins/examples>`_)." +msgid "" +"Let's add the `datalab_example_imageproc.py` plugin to DataLab (this is " +"an example plugin that is shipped with DataLab source package, or may be " +"downloaded from `here <https://github.com/DataLab-" +"Platform/DataLab/tree/main/plugins/examples>`_)." +msgstr "" +"Ajoutons le plugin `datalab_example_imageproc.py` à DataLab (c'est un " +"plugin d'exemple qui est fourni avec le package source de DataLab, ou " +"peut être téléchargé `ici <https://github.com/DataLab-" +"Platform/DataLab/tree/main/plugins/examples>`_)." -msgid "If we close and reopen DataLab, we can see that the plugin is now available in the \"Plugins\" menu: there is a new \"Extract blobs (example)\" entry." -msgstr "Si nous fermons et rouvrons DataLab, nous pouvons voir que le plugin est maintenant disponible dans le menu \"Plugins\" : il y a une nouvelle entrée \"Extract blobs (example)\"." +msgid "" +"If we close and reopen DataLab, we can see that the plugin is now " +"available in the \"Plugins\" menu: there is a new \"Extract blobs " +"(example)\" entry." +msgstr "" +"Si nous fermons et rouvrons DataLab, nous pouvons voir que le plugin est " +"maintenant disponible dans le menu \"Plugins\" : il y a une nouvelle " +"entrée \"Extract blobs (example)\"." msgid "The \"About DataLab\" dialog shows the list of available plugins." -msgstr "La boîte de dialogue \"À propos de DataLab\" affiche la liste des plugins disponibles." +msgstr "" +"La boîte de dialogue \"À propos de DataLab\" affiche la liste des plugins" +" disponibles." msgid "Let's click on \"Extract blobs (example) > Generate test image\"" msgstr "Cliquons sur \"Extract blobs (example) > Generate test image\"" -msgid "DataLab menus change between images and signals. To be able to see the \"Extract blobs (example)\" menu, make sure that the \"Images\" panel is selected (click on the \"Images\" tab on the left)." -msgstr "Les menus de DataLab changent entre les images et les signaux. Pour pouvoir voir le menu \"Extract blobs (example)\", assurez-vous que le panneau \"Images\" est sélectionné (cliquez sur l'onglet \"Images\" à gauche)." +msgid "" +"DataLab menus change between images and signals. To be able to see the " +"\"Extract blobs (example)\" menu, make sure that the \"Images\" panel is " +"selected (click on the \"Images\" tab on the left)." +msgstr "" +"Les menus de DataLab changent entre les images et les signaux. Pour " +"pouvoir voir le menu \"Extract blobs (example)\", assurez-vous que le " +"panneau \"Images\" est sélectionné (cliquez sur l'onglet \"Images\" à " +"gauche)." -msgid "A pop-up dialog appears, asking for the parameters of the test image to generate (the size of the image and its title). We can just keep the default parameters and click on \"OK\"." -msgstr "Une boîte de dialogue contextuelle apparaît, demandant les paramètres de l'image de test à générer (la taille de l'image et son titre). Nous pouvons simplement conserver les paramètres par défaut et cliquer sur \"OK\"." +msgid "" +"A pop-up dialog appears, asking for the parameters of the test image to " +"generate (the size of the image and its title). We can just keep the " +"default parameters and click on \"OK\"." +msgstr "" +"Une boîte de dialogue contextuelle apparaît, demandant les paramètres de " +"l'image de test à générer (la taille de l'image et son titre). Nous " +"pouvons simplement conserver les paramètres par défaut et cliquer sur " +"\"OK\"." -msgid "For information, the image is generated by the plugin using the following code::" -msgstr "Pour information, l'image est générée par le plugin en utilisant le code suivant::" +msgid "" +"For information, the image is generated by the plugin using the following" +" code::" +msgstr "" +"Pour information, l'image est générée par le plugin en utilisant le code " +"suivant::" -msgid "The plugin has generated a test image, and added it to the \"Images\" panel. The image shows a few blobs, with a central bigger disk, and a noisy background." -msgstr "Le plugin a généré une image de test, et l'a ajoutée au panneau \"Images\". L'image montre quelques taches, avec un disque central plus grand, et un fond bruité." +msgid "" +"The plugin has generated a test image, and added it to the \"Images\" " +"panel. The image shows a few blobs, with a central bigger disk, and a " +"noisy background." +msgstr "" +"Le plugin a généré une image de test, et l'a ajoutée au panneau " +"\"Images\". L'image montre quelques taches, avec un disque central plus " +"grand, et un fond bruité." -msgid "The plugin has other features, such as denoising the image, and detecting blobs on the image, but we won't cover them here: we will instead use the DataLab native features to achieve, manually, the same operations as the plugin." -msgstr "Le plugin a d'autres fonctionnalités, telles que le débruitage de l'image, et la détection de taches sur l'image, mais nous ne les aborderons pas ici : nous utiliserons plutôt les fonctionnalités natives de DataLab pour réaliser, manuellement, les mêmes opérations que le plugin." +msgid "" +"The plugin has other features, such as denoising the image, and detecting" +" blobs on the image, but we won't cover them here: we will instead use " +"the DataLab native features to achieve, manually, the same operations as " +"the plugin." +msgstr "" +"Le plugin a d'autres fonctionnalités, telles que le débruitage de " +"l'image, et la détection de taches sur l'image, mais nous ne les " +"aborderons pas ici : nous utiliserons plutôt les fonctionnalités natives " +"de DataLab pour réaliser, manuellement, les mêmes opérations que le " +"plugin." -msgid "The image is a bit noisy, and also quite large. In addition, the blobs are large with respect to the pixel size." -msgstr "L'image est un peu bruitée, et aussi assez grande. De plus, les taches sont grandes par rapport à la taille des pixels." +msgid "" +"The image is a bit noisy, and also quite large. In addition, the blobs " +"are large with respect to the pixel size." +msgstr "" +"L'image est un peu bruitée, et aussi assez grande. De plus, les taches " +"sont grandes par rapport à la taille des pixels." -msgid "To reduce the noise there are several functions available in DataLab. Due to the considerations we just made, we can consider that a binning would reduce the noise without losing the information we look for. Let's apply a binning to the image by a factor of 2 on both axes. This will reduce the image size by a factor of 4, and the noise standard deviation by a factor of 2. Choosing to change the pixel size accordingly will keep the blob size constant in the previous unit (in this case, pixels, but in a real application we can calibrate them to respect a real physical size)." -msgstr "Pour réduire le bruit, il existe plusieurs fonctions disponibles dans DataLab. En raison des considérations que nous venons de faire, nous pouvons considérer qu'un binning réduirait le bruit sans perdre l'information que nous recherchons. Appliquons un binning à l'image par un facteur de 2 sur les deux axes. Cela réduira la taille de l'image d'un facteur de 4, et l'écart type du bruit d'un facteur de 2. Choisir de modifier la taille des pixels en conséquence maintiendra la taille des taches constante dans l'unité précédente (dans ce cas, les pixels, mais dans une application réelle, nous pouvons les calibrer pour respecter une taille physique réelle)." +msgid "" +"To reduce the noise there are several functions available in DataLab. Due" +" to the considerations we just made, we can consider that a binning would" +" reduce the noise without losing the information we look for. Let's apply" +" a binning to the image by a factor of 2 on both axes. This will reduce " +"the image size by a factor of 4, and the noise standard deviation by a " +"factor of 2. Choosing to change the pixel size accordingly will keep the " +"blob size constant in the previous unit (in this case, pixels, but in a " +"real application we can calibrate them to respect a real physical size)." +msgstr "" +"Pour réduire le bruit, il existe plusieurs fonctions disponibles dans " +"DataLab. En raison des considérations que nous venons de faire, nous " +"pouvons considérer qu'un binning réduirait le bruit sans perdre " +"l'information que nous recherchons. Appliquons un binning à l'image par " +"un facteur de 2 sur les deux axes. Cela réduira la taille de l'image d'un" +" facteur de 4, et l'écart type du bruit d'un facteur de 2. Choisir de " +"modifier la taille des pixels en conséquence maintiendra la taille des " +"taches constante dans l'unité précédente (dans ce cas, les pixels, mais " +"dans une application réelle, nous pouvons les calibrer pour respecter une" +" taille physique réelle)." msgid "Click on \"Operations > Pixel binning\"." msgstr "Cliquons sur \"Opérations > Pixel binning\"." -msgid "The \"Binning\" dialog opens, with several options. Set the binning factor to 2 for both axes, select the \"change pixel size\" case and click on \"OK\"." -msgstr "La boîte de dialogue \"Binning\" s'ouvre, avec plusieurs options. Réglez le facteur de binning à 2 pour les deux axes, sélectionnez la case \"changer la taille des pixels\" et cliquez sur \"OK\"." +msgid "" +"The \"Binning\" dialog opens, with several options. Set the binning " +"factor to 2 for both axes, select the \"change pixel size\" case and " +"click on \"OK\"." +msgstr "" +"La boîte de dialogue \"Binning\" s'ouvre, avec plusieurs options. Réglez " +"le facteur de binning à 2 pour les deux axes, sélectionnez la case " +"\"changer la taille des pixels\" et cliquez sur \"OK\"." -msgid "The binned image is added to the \"Images\" panel. It is now easier to see the blobs (even if they were already quite visible on the original image: this is just an example), and the image will be faster to process." -msgstr "L'image binnée est ajoutée au panneau \"Images\". Il est maintenant plus facile de voir les taches (même si elles étaient déjà assez visibles sur l'image d'origine : c'est juste un exemple), et l'image sera plus rapide à traiter." +msgid "" +"The binned image is added to the \"Images\" panel. It is now easier to " +"see the blobs (even if they were already quite visible on the original " +"image: this is just an example), and the image will be faster to process." +msgstr "" +"L'image binnée est ajoutée au panneau \"Images\". Il est maintenant plus " +"facile de voir les taches (même si elles étaient déjà assez visibles sur " +"l'image d'origine : c'est juste un exemple), et l'image sera plus rapide " +"à traiter." -msgid "A different approach we can take is to apply a moving median filter, to reduce the importance of the spikes. We do it with a window of 5; of course in practice different window sizes can be tested to find a good compromise between noise reduction and resolution. Let's see how to do that." -msgstr "Une autre approche que nous pouvons adopter est d'appliquer un filtre médian mobile, pour réduire l'importance des pics. Nous le faisons avec une fenêtre de 5 ; bien sûr, en pratique, différentes tailles de fenêtre peuvent être testées pour trouver un bon compromis entre la réduction du bruit et la résolution. Voyons comment faire cela." +msgid "" +"A different approach we can take is to apply a moving median filter, to " +"reduce the importance of the spikes. We do it with a window of 5; of " +"course in practice different window sizes can be tested to find a good " +"compromise between noise reduction and resolution. Let's see how to do " +"that." +msgstr "" +"Une autre approche que nous pouvons adopter est d'appliquer un filtre " +"médian mobile, pour réduire l'importance des pics. Nous le faisons avec " +"une fenêtre de 5 ; bien sûr, en pratique, différentes tailles de fenêtre " +"peuvent être testées pour trouver un bon compromis entre la réduction du " +"bruit et la résolution. Voyons comment faire cela." -msgid "Click on \"Processing > Noise reduction > Moving median\" entry, and set the window size to ``5``." -msgstr "Cliquez sur l'entrée \"Traitement > Réduction du bruit > Médiane mobile\", et réglez la taille de la fenêtre sur ``5``." +msgid "" +"Click on \"Processing > Noise reduction > Moving median\" entry, and set " +"the window size to ``5``." +msgstr "" +"Cliquez sur l'entrée \"Traitement > Réduction du bruit > Médiane " +"mobile\", et réglez la taille de la fenêtre sur ``5``." -msgid "The filtered image is added to the \"Images\" panel. Denoising is quite efficient." -msgstr "L'image filtrée est ajoutée au panneau \"Images\". Le débruitage est assez efficace." +msgid "" +"The filtered image is added to the \"Images\" panel. Denoising is quite " +"efficient." +msgstr "" +"L'image filtrée est ajoutée au panneau \"Images\". Le débruitage est " +"assez efficace." -msgid "Now, we can be satisfied with our denoising: it is visible that the noise is smaller. We can thus move to the following step: detect the blobs on the image. To do that, we can use the \"Blob detection\" function available in the \"Analysis\" menu. Different :ref:`algorithms <ima-blob-detection>` are available, here we will use the OpenCV one." -msgstr "A présent, le débruitage paraît satisfaisant : le niveau de bruit est sensiblement réduit. Nous pouvons donc passer à l'étape suivante : détecter les taches sur l'image. Pour ce faire, nous pouvons utiliser la fonction \"Détection de taches\" disponible dans le menu \"Analyse\". Différents :ref:`algorithmes <ima-blob-detection>` sont disponibles, ici nous utiliserons celui d'OpenCV." +msgid "" +"Now, we can be satisfied with our denoising: it is visible that the noise" +" is smaller. We can thus move to the following step: detect the blobs on " +"the image. To do that, we can use the \"Blob detection\" function " +"available in the \"Analysis\" menu. Different :ref:`algorithms <ima-blob-" +"detection>` are available, here we will use the OpenCV one." +msgstr "" +"A présent, le débruitage paraît satisfaisant : le niveau de bruit est " +"sensiblement réduit. Nous pouvons donc passer à l'étape suivante : " +"détecter les taches sur l'image. Pour ce faire, nous pouvons utiliser la " +"fonction \"Détection de taches\" disponible dans le menu \"Analyse\". " +"Différents :ref:`algorithmes <ima-blob-detection>` sont disponibles, ici " +"nous utiliserons celui d'OpenCV." msgid "Click on \"Analysis > Blob detection > Blob detection (OpenCV)\"." msgstr "Cliquons sur \"Analysis > Blob detection > Blob detection (OpenCV)\"." -msgid "The \"Blob detection (OpenCV)\" dialog opens. Set the parameters as shown on the screenshot, and click on \"OK\"." -msgstr "La boîte de dialogue \"Blob detection (OpenCV)\" s'ouvre. Réglez les paramètres comme indiqué sur la capture d'écran, et cliquez sur \"OK\"." +msgid "" +"The \"Blob detection (OpenCV)\" dialog opens. Set the parameters as shown" +" on the screenshot, and click on \"OK\"." +msgstr "" +"La boîte de dialogue \"Blob detection (OpenCV)\" s'ouvre. Réglez les " +"paramètres comme indiqué sur la capture d'écran, et cliquez sur \"OK\"." -msgid "The \"Results\" dialog opens, showing the detected blobs: one line per blob, with the blob coordinates and radius." -msgstr "La boîte de dialogue \"Résultats\" s'ouvre, montrant les taches détectées : une ligne par tache, avec les coordonnées et le rayon de la tache." +msgid "" +"The \"Results\" dialog opens, showing the detected blobs: one line per " +"blob, with the blob coordinates and radius." +msgstr "" +"La boîte de dialogue \"Résultats\" s'ouvre, montrant les taches détectées" +" : une ligne par tache, avec les coordonnées et le rayon de la tache." -msgid "If you want to show the analysis results again, you can select the \"Show results\" |show_results| entry in the \"Analysis\" menu, or the \"Results\" |show_results| button, in the property panel below the image list:" -msgstr "Si vous souhaitez afficher à nouveau les résultats d'analyse, vous pouvez sélectionner l'entrée \"Afficher les résultats\" |show_results| dans le menu \"Analyse\", ou le bouton \"Résultats\" |show_results|, dans le panneau de propriétés en dessous de la liste des images :" +msgid "" +"If you want to show the analysis results again, you can select the \"Show" +" results\" |show_results| entry in the \"Analysis\" menu, or the " +"\"Results\" |show_results| button, in the property panel below the image " +"list:" +msgstr "" +"Si vous souhaitez afficher à nouveau les résultats d'analyse, vous pouvez" +" sélectionner l'entrée \"Afficher les résultats\" |show_results| dans le " +"menu \"Analyse\", ou le bouton \"Résultats\" |show_results|, dans le " +"panneau de propriétés en dessous de la liste des images :" msgid "show_results" msgstr "" -msgid "The detected blobs are also added to the image metadata, and can be seen in the visualization panel on the right." -msgstr "Les taches détectées sont également ajoutées aux métadonnées de l'image, et peuvent être visualisées dans le panneau de visualisation à droite." - -msgid "Finally, we can save the workspace to a file. The workspace contains all the images that were loaded in DataLab, as well as the processing results. It also contains the visualization settings (colormaps, contrast, etc.), the metadata, and the annotations. To save the workspace, click on \"File > Save to HDF5 file...\", or the |filesave_h5| button in the toolbar." -msgstr "Enfin, nous pouvons enregistrer l'espace de travail dans un fichier. L'espace de travail contient toutes les images qui ont été chargées dans DataLab, ainsi que les résultats de traitement. Il contient également les paramètres de visualisation (palettes de couleurs, contraste, etc.), les métadonnées et les annotations. Pour enregistrer l'espace de travail, cliquez sur \"Fichier > Enregistrer dans un fichier HDF5...\", ou sur le bouton |filesave_h5| dans la barre d'outils." - -msgid "filesave_h5" +msgid "" +"The detected blobs are also added to the image metadata, and can be seen " +"in the visualization panel on the right." msgstr "" +"Les taches détectées sont également ajoutées aux métadonnées de l'image, " +"et peuvent être visualisées dans le panneau de visualisation à droite." -msgid "If you want to load the workspace again, you can use the \"File > Open HDF5 file...\" (or the |fileopen_h5| button in the toolbar) to load the whole workspace, or the \"File > Browse HDF5 file...\" (or the |h5browser| button in the toolbar) to load only a selection of data sets from the workspace." -msgstr "Si vous souhaitez charger à nouveau l'espace de travail, vous pouvez utiliser \"Fichier > Ouvrir un fichier HDF5...\" (ou le bouton |fileopen_h5| dans la barre d'outils) pour charger l'ensemble de l'espace de travail, ou \"Fichier > Parcourir un fichier HDF5...\" (ou le bouton |h5browser| dans la barre d'outils) pour charger uniquement une sélection d'ensembles de données de l'espace de travail." - -msgid "fileopen_h5" +msgid "" +"Finally, we can save the workspace to a file. The workspace contains all " +"the images that were loaded in DataLab, as well as the processing " +"results. It also contains the visualization settings (colormaps, " +"contrast, etc.), the metadata, and the annotations. To save the " +"workspace, click on \"File > Save to HDF5 file...\", or the |filesave_h5|" +" button in the toolbar." msgstr "" +"Enfin, nous pouvons enregistrer l'espace de travail dans un fichier. " +"L'espace de travail contient toutes les images qui ont été chargées dans " +"DataLab, ainsi que les résultats de traitement. Il contient également les" +" paramètres de visualisation (palettes de couleurs, contraste, etc.), les" +" métadonnées et les annotations. Pour enregistrer l'espace de travail, " +"cliquez sur \"Fichier > Enregistrer dans un fichier HDF5...\", ou sur le " +"bouton |filesave_h5| dans la barre d'outils." -msgid "h5browser" +msgid "filesave_h5" msgstr "" msgid "" -"Automatically detect defects, particles or spots on images (blob detection) " -"with DataLab, the open-source signal and image analysis platform: image " -"denoising, automated blob detection, and workspace saving. Also introduces " -"the plugin system." +"If you want to load the workspace again, you can use the \"File > Open " +"HDF5 file...\" (or the |fileopen_h5| button in the toolbar) to load the " +"whole workspace, or the \"File > Browse HDF5 file...\" (or the " +"|h5browser| button in the toolbar) to load only a selection of data sets " +"from the workspace." msgstr "" -"Détectez automatiquement défauts, particules ou taches sur des images " -"(détection de blobs) avec DataLab, la plateforme open-source d'analyse de " -"signaux et d'images : débruitage d'image, détection automatique de taches et" -" enregistrement de l'espace de travail. Présente également le système de " -"plugins." +"Si vous souhaitez charger à nouveau l'espace de travail, vous pouvez " +"utiliser \"Fichier > Ouvrir un fichier HDF5...\" (ou le bouton " +"|fileopen_h5| dans la barre d'outils) pour charger l'ensemble de l'espace" +" de travail, ou \"Fichier > Parcourir un fichier HDF5...\" (ou le bouton " +"|h5browser| dans la barre d'outils) pour charger uniquement une sélection" +" d'ensembles de données de l'espace de travail." -msgid "" -"defect detection, particle detection, blob detection, non-destructive " -"testing, automated inspection, image denoising, image analysis software, " -"plugin, DataLab, tutorial" +msgid "fileopen_h5" msgstr "" -"détection de défauts, détection de particules, détection de blobs, contrôle " -"non destructif, inspection automatisée, débruitage d'image, logiciel " -"d'analyse d'images, plugin, DataLab, tutoriel" -msgid "" -":octicon:`book;1em;sd-text-info` Automated detection of defects and " -"particles on images" +msgid "h5browser" msgstr "" -":octicon:`book;1em;sd-text-info` Détection automatisée de défauts et de " -"particules sur des images" -msgid "" -"This example shows how to automatically detect blob-like features -- " -"defects, particles, spots -- on an image with DataLab, and also covers other" -" features such as the plugin system:" -msgstr "" -"Cet exemple montre comment détecter automatiquement des éléments de type " -"tache -- défauts, particules, points -- sur une image avec DataLab, et " -"couvre également d'autres fonctionnalités telles que le système de plugins :" +#~ msgid ":octicon:`book;1em;sd-text-info` Detecting blobs on an image" +#~ msgstr ":octicon:`book;1em;sd-text-info` Détection de taches sur une image" + +#~ msgid "" +#~ "This example shows how to detect " +#~ "blobs on an image with DataLab, " +#~ "and also covers other features such " +#~ "as the plugin system:" +#~ msgstr "" +#~ "Cet exemple montre comment détecter des" +#~ " taches sur une image avec DataLab," +#~ " et couvre également d'autres " +#~ "fonctionnalités telles que le système de" +#~ " plugins :" + diff --git a/doc/locale/fr/LC_MESSAGES/intro/tutorials/laser_beam.po b/doc/locale/fr/LC_MESSAGES/intro/tutorials/laser_beam.po index dc0fe535b..3b7c185ee 100644 --- a/doc/locale/fr/LC_MESSAGES/intro/tutorials/laser_beam.po +++ b/doc/locale/fr/LC_MESSAGES/intro/tutorials/laser_beam.po @@ -3,34 +3,39 @@ # This file is distributed under the same license as the DataLab package. # FIRST AUTHOR <EMAIL@ADDRESS>, 2024. # -#, fuzzy msgid "" msgstr "" -"POT-Creation-Date: 2026-08-05 14:07+0200\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" msgid "" -"Tutorial on how to measure the size of a laser beam using DataLab, the " -"open-source scientific analysis and visualization platform" +"Measure laser beam size (FWHM) from camera images with DataLab, the open-" +"source signal and image analysis platform: thresholding, line and radial " +"intensity profiles, Gaussian fit, and batch analysis of a whole image " +"stack to plot beam size along the propagation axis." msgstr "" -"Tutoriel: mesurer la taille d'un faisceau laser avec DataLab, la " -"plateforme d'analyse et de visualisation scientifique open-source" +"Mesurez la taille d'un faisceau laser (FWHM) à partir d'images caméra " +"avec DataLab, la plateforme open-source d'analyse de signaux et d'images " +": seuillage, profils d'intensité rectilignes et radiaux, ajustement " +"gaussien, et analyse par lots d'une pile d'images pour tracer la taille " +"du faisceau le long de l'axe de propagation." msgid "" -"DataLab, tutorial, laser beam, size, FWHM, Gaussian fit, radial profile, " -"line profile, thresholding, centroid, image statistics, linear " -"calibration, HDF5, workspace" +"laser beam profiling, beam size measurement, FWHM, beam waist, Gaussian " +"fit, radial profile, camera image analysis, image stack, batch " +"processing, photonics, DataLab, tutorial" msgstr "" -"DataLab, tutoriel, faisceau laser, taille, FWHM, ajustement gaussien, " -"profil radial, profil de ligne, seuillage, centre de gravité, " -"statistiques de l'image, étalonnage linéaire, HDF5, espace de travail" +"profilométrie de faisceau laser, mesure de taille de faisceau, FWHM, " +"waist, ajustement gaussien, profil radial, analyse d'images caméra, pile " +"d'images, traitement par lots, photonique, DataLab, tutoriel" -msgid ":octicon:`book;1em;sd-text-info` Measuring Laser Beam Size" -msgstr ":octicon:`book;1em;sd-text-info` Mesurer la taille d'un faisceau laser" +msgid "" +":octicon:`book;1em;sd-text-info` Laser beam profiling: measuring beam " +"size along the propagation axis" +msgstr "" +":octicon:`book;1em;sd-text-info` Profilométrie de faisceau laser : " +"mesurer la taille du faisceau le long de l'axe de propagation" msgid "" "This example shows how to measure the size of a laser beam along the " @@ -188,8 +193,15 @@ msgstr "" msgid "reset_positions" msgstr "reset_positions" -msgid "Both the \"Distribute on a grid\" and \"Reset image positions\" options modify the images in place, without creating new images. For this reason, they are not registered in the History Panel, which only lists newly created objects." -msgstr "Les options \"Distribuer sur une grille\" et \"Réinitialiser les positions des images\" modifient les images sur place, sans créer de nouvelles images. Pour cette raison, elles ne sont pas enregistrées dans le panneau Historique, qui ne répertorie que les objets nouvellement créés." +msgid "" +"Both the \"Distribute on a grid\" and \"Reset image positions\" options " +"modify the images in place, without creating new images. For this reason," +" these operations are not recorded in the History Panel." +msgstr "" +"Les options \"Distribuer sur une grille\" et \"Réinitialiser les " +"positions des images\" modifient les images sur place, sans créer de " +"nouvelles images. Pour cette raison, ces opérations ne sont pas " +"enregistrées dans le panneau d'historique." msgid "Remove background noise" msgstr "Supprimer le bruit de fond" @@ -204,8 +216,23 @@ msgstr "" "images. Plusieurs méthodes sont disponibles pour estimer le niveau de " "bruit de fond." -msgid "One approach utilizes the \"Cross section\" tool, which is provided by the `PlotPy <https://github.com/PlotPyStack/plotpy>`__ library that DataLab uses for signal and image visualization. Select an image from the \"Image panel\", choose the corresponding image in the visualization panel, and activate the \"Cross section\" tool |cross_section| from the vertical toolbar on the left side of the visualization panel. This reveals that the background noise level is approximately 30 lsb." -msgstr "Une approche utilise l'outil \"Profil rectiligne\", qui est fourni par la bibliothèque `PlotPy <https://github.com/PlotPyStack/plotpy>`__ que DataLab utilise pour la visualisation de signaux et d'images. Sélectionnez une image dans le panneau \"Images\", choisissez l'image correspondante dans le panneau de visualisation, et activez l'outil \"Profil rectiligne\" |cross_section| depuis la barre d'outils verticale sur le côté gauche du panneau de visualisation. Cela révèle que le niveau de bruit de fond est d'environ 30 lsb." +msgid "" +"One approach utilizes the \"Cross section\" tool, which is provided by " +"the `PlotPy <https://github.com/PlotPyStack/plotpy>`__ library that " +"DataLab uses for signal and image visualization. Select an image from the" +" \"Image panel\", choose the corresponding image in the visualization " +"panel, and activate the \"Cross section\" tool |cross_section| from the " +"vertical toolbar on the left side of the visualization panel. This " +"reveals that the background noise level is approximately 30 lsb." +msgstr "" +"Une approche utilise l'outil \"Profil rectiligne\", qui est fourni par la" +" bibliothèque `PlotPy <https://github.com/PlotPyStack/plotpy>`__ que " +"DataLab utilise pour la visualisation de signaux et d'images. " +"Sélectionnez une image dans le panneau \"Images\", choisissez l'image " +"correspondante dans le panneau de visualisation, et activez l'outil " +"\"Profil rectiligne\" |cross_section| depuis la barre d'outils verticale " +"sur le côté gauche du panneau de visualisation. Cela révèle que le niveau" +" de bruit de fond est d'environ 30 lsb." msgid "cross_section" msgstr "cross_section" @@ -220,8 +247,22 @@ msgstr "" "ouvrir le menu contextuel, puis choisissez \"Marqueurs > Lié à l'élément " "actif\"." -msgid "Another method for measuring background noise, also provided by `PlotPy <https://github.com/PlotPyStack/plotpy>`__, involves using the \"Image statistics\" tool |imagestats| from the vertical toolbar on the left side of the visualization panel. This tool displays statistical information for a rectangular region that you define by dragging the mouse across the image. This analysis confirms that the background noise level is approximately 30 lsb." -msgstr "Une autre méthode pour mesurer le bruit de fond, également fournie par `PlotPy <https://github.com/PlotPyStack/plotpy>`__, consiste à utiliser l'outil \"Statistiques de l'image\" |imagestats| de la barre d'outils verticale sur le côté gauche du panneau de visualisation. Cet outil affiche des informations statistiques pour une région rectangulaire que vous définissez en faisant glisser la souris sur l'image. Cette analyse confirme que le niveau de bruit de fond est d'environ 30 lsb." +msgid "" +"Another method for measuring background noise, also provided by `PlotPy " +"<https://github.com/PlotPyStack/plotpy>`__, involves using the \"Image " +"statistics\" tool |imagestats| from the vertical toolbar on the left side" +" of the visualization panel. This tool displays statistical information " +"for a rectangular region that you define by dragging the mouse across the" +" image. This analysis confirms that the background noise level is " +"approximately 30 lsb." +msgstr "" +"Une autre méthode pour mesurer le bruit de fond, également fournie par " +"`PlotPy <https://github.com/PlotPyStack/plotpy>`__, consiste à utiliser " +"l'outil \"Statistiques de l'image\" |imagestats| de la barre d'outils " +"verticale sur le côté gauche du panneau de visualisation. Cet outil " +"affiche des informations statistiques pour une région rectangulaire que " +"vous définissez en faisant glisser la souris sur l'image. Cette analyse " +"confirme que le niveau de bruit de fond est d'environ 30 lsb." msgid "imagestats" msgstr "imagestats" @@ -279,20 +320,32 @@ msgid "" "intensity profile extraction." msgstr "" "Ensuite, nous pouvons extraire un profil de ligne le long de l'axe " -"horizontal en utilisant \"Opérations > Profils d'intensité > Profil " +"horizontal en utilisant \"Analyse > Profils d'intensité > Profil " "rectiligne\". Définissez la position de la ligne sur la position du " "centroïde calculée précédemment (c'est-à-dire 668) en utilisant le bouton" " \"Définir les paramètres\". Voir :ref:`tutorial_fabry_perot` pour plus " "de détails sur l'extraction de profil d'intensité." -msgid "The intensity profile will be displayed in the \"Signal panel\". We can then fit the profile to a Gaussian function using \"Processing > Fitting > Gaussian fit\". Here we have selected both signals for comparison." -msgstr "Le profil d'intensité sera affiché dans le panneau \"Signaux\". Nous pouvons ensuite ajuster le profil à une fonction gaussienne en utilisant \"Traitement > Ajustement > Ajustement gaussien\". Ici, nous avons sélectionné les deux signaux pour comparaison." - -msgid "If history recording is enabled, creating a new signal starts a new history session, separate from the session containing the image operations. Since extracting the intensity profile is an operation performed on an image, the new session starts with the Gaussian fit applied to the resulting signal." -msgstr "Si l'enregistrement de l'historique est activé, la création d'un nouveau signal démarre une nouvelle session d'historique, distincte de celle contenant les opérations sur les images. Comme l'extraction du profil d'intensité est une opération effectuée sur une image, la nouvelle session commence avec l'ajustement gaussien appliqué au signal obtenu." +msgid "" +"The intensity profile will be displayed in the \"Signal panel\". We can " +"then fit the profile to a Gaussian function using \"Processing > Fitting " +"> Gaussian fit\". Here we have selected both signals for comparison." +msgstr "" +"Le profil d'intensité sera affiché dans le panneau \"Signaux\". Nous " +"pouvons ensuite ajuster le profil à une fonction gaussienne en utilisant " +"\"Traitement > Ajustement > Ajustement gaussien\". Ici, nous avons " +"sélectionné les deux signaux pour comparaison." -msgid "The image-processing actions are recorded in the first session, while the Gaussian fit starts a separate session for the resulting signal." -msgstr "Les actions de traitement d'image sont enregistrées dans la première session, tandis que l'ajustement gaussien démarre une session distincte pour le signal obtenu." +msgid "" +"If history recording is enabled, the image-processing actions, extracted " +"profile, and Gaussian fit are recorded in the same active history " +"session. See :ref:`tutorial_history_panel` for a cross-panel workflow " +"example." +msgstr "" +"Si l'enregistrement de l'historique est activé, les actions de traitement " +"d'image, le profil extrait et l'ajustement gaussien sont enregistrés dans la " +"même session d'historique active. Consultez :ref:`tutorial_history_panel` " +"pour un exemple de flux entre les panneaux." msgid "" "The intensity profile fitted to a Gaussian function. Here both signals " @@ -479,8 +532,18 @@ msgstr "" "propagation (la position est en unités arbitraires—l'index de l'image)." #, python-brace-format -msgid "We can also calibrate the X and Y axes using \"Processing > Linear calibration\". Here we set the X axis to the position in mm (entering the title and unit in the \"Properties\" group box) using the formula: :math:`X[\\textrm{mm}] = 0.5 \\cdot i + 10` where :math:`i` is the image index." -msgstr "Nous pouvons également étalonner les axes X et Y en utilisant \"Traitement > Étalonnage linéaire\". Ici, nous définissons l'axe X sur la position en mm (en entrant le titre et l'unité dans le groupe \"Propriétés\") en utilisant la formule : :math:`X[\\textrm{mm}] = 0.5 \\cdot i + 10` où :math:`i` est l'index de l'image." +msgid "" +"We can also calibrate the X and Y axes using \"Processing > Linear " +"calibration\". Here we set the X axis to the position in mm (entering the" +" title and unit in the \"Properties\" group box) using the formula: " +":math:`X[\\textrm{mm}] = 0.5 \\cdot i + 10` where :math:`i` is the image " +"index." +msgstr "" +"Nous pouvons également étalonner les axes X et Y en utilisant " +"\"Traitement > Étalonnage linéaire\". Ici, nous définissons l'axe X sur " +"la position en mm (en entrant le titre et l'unité dans le groupe " +"\"Propriétés\") en utilisant la formule : :math:`X[\\textrm{mm}] = 0.5 " +"\\cdot i + 10` où :math:`i` est l'index de l'image." msgid "" "The calibrated beam size as a function of the position along the " @@ -524,65 +587,123 @@ msgstr "fileopen_h5" msgid "h5browser" msgstr "h5browser" -msgid "" -"Measure laser beam size (FWHM) from camera images with DataLab, the open-" -"source signal and image analysis platform: thresholding, line and radial " -"intensity profiles, Gaussian fit, and batch analysis of a whole image stack " -"to plot beam size along the propagation axis." -msgstr "" -"Mesurez la taille d'un faisceau laser (FWHM) à partir d'images caméra avec " -"DataLab, la plateforme open-source d'analyse de signaux et d'images : " -"seuillage, profils d'intensité rectilignes et radiaux, ajustement gaussien, " -"et analyse par lots d'une pile d'images pour tracer la taille du faisceau le" -" long de l'axe de propagation." - -msgid "" -"laser beam profiling, beam size measurement, FWHM, beam waist, Gaussian fit," -" radial profile, camera image analysis, image stack, batch processing, " -"photonics, DataLab, tutorial" -msgstr "" -"profilométrie de faisceau laser, mesure de taille de faisceau, FWHM, waist, " -"ajustement gaussien, profil radial, analyse d'images caméra, pile d'images, " -"traitement par lots, photonique, DataLab, tutoriel" - -msgid "" -":octicon:`book;1em;sd-text-info` Laser beam profiling: measuring beam size " -"along the propagation axis" -msgstr "" -":octicon:`book;1em;sd-text-info` Profilométrie de faisceau laser : mesurer " -"la taille du faisceau le long de l'axe de propagation" - -msgid "" -"One approach utilizes the \"Cross section\" tool, which is provided by the " -"`PlotPy <https://github.com/PlotPyStack/plotpy>` library that DataLab uses " -"for signal and image visualization. Select an image from the \"Image " -"panel\", choose the corresponding image in the visualization panel, and " -"activate the \"Cross section\" tool |cross_section| from the vertical " -"toolbar on the left side of the visualization panel. This reveals that the " -"background noise level is approximately 30 lsb." -msgstr "" -"Une approche utilise l'outil \"Profil rectiligne\", qui est fourni par la " -"bibliothèque `PlotPy <https://github.com/PlotPyStack/plotpy>` que DataLab " -"utilise pour la visualisation de signaux et d'images. Sélectionnez une image" -" dans le panneau \"Images\", choisissez l'image correspondante dans le " -"panneau de visualisation, et activez l'outil \"Profil rectiligne\" " -"|cross_section| depuis la barre d'outils verticale sur le côté gauche du " -"panneau de visualisation. Cela révèle que le niveau de bruit de fond est " -"d'environ 30 lsb." - -msgid "" -"Another method for measuring background noise, also provided by `PlotPy " -"<https://github.com/PlotPyStack/plotpy>`, involves using the \"Image " -"statistics\" tool |imagestats| from the vertical toolbar on the left side of" -" the visualization panel. This tool displays statistical information for a " -"rectangular region that you define by dragging the mouse across the image. " -"This analysis confirms that the background noise level is approximately 30 " -"lsb." -msgstr "" -"Une autre méthode pour mesurer le bruit de fond, également fournie par " -"`PlotPy <https://github.com/PlotPyStack/plotpy>`, consiste à utiliser " -"l'outil \"Statistiques de l'image\" |imagestats| de la barre d'outils " -"verticale sur le côté gauche du panneau de visualisation. Cet outil affiche " -"des informations statistiques pour une région rectangulaire que vous " -"définissez en faisant glisser la souris sur l'image. Cette analyse confirme " -"que le niveau de bruit de fond est d'environ 30 lsb." +#~ msgid "" +#~ "Tutorial on how to measure the " +#~ "size of a laser beam using " +#~ "DataLab, the open-source scientific " +#~ "analysis and visualization platform" +#~ msgstr "" +#~ "Tutoriel: mesurer la taille d'un " +#~ "faisceau laser avec DataLab, la " +#~ "plateforme d'analyse et de visualisation " +#~ "scientifique open-source" + +#~ msgid "" +#~ "DataLab, tutorial, laser beam, size, " +#~ "FWHM, Gaussian fit, radial profile, line" +#~ " profile, thresholding, centroid, image " +#~ "statistics, linear calibration, HDF5, " +#~ "workspace" +#~ msgstr "" +#~ "DataLab, tutoriel, faisceau laser, taille, " +#~ "FWHM, ajustement gaussien, profil radial, " +#~ "profil de ligne, seuillage, centre de" +#~ " gravité, statistiques de l'image, " +#~ "étalonnage linéaire, HDF5, espace de " +#~ "travail" + +#~ msgid ":octicon:`book;1em;sd-text-info` Measuring Laser Beam Size" +#~ msgstr ":octicon:`book;1em;sd-text-info` Mesurer la taille d'un faisceau laser" + +#~ msgid "" +#~ "If history recording is enabled, " +#~ "creating a new signal starts a new" +#~ " history session, separate from the " +#~ "session containing the image operations. " +#~ "Since extracting the intensity profile " +#~ "is an operation performed on an " +#~ "image, the new session starts with " +#~ "the Gaussian fit applied to the " +#~ "resulting signal." +#~ msgstr "" +#~ "Si l'enregistrement de l'historique est " +#~ "activé, la création d'un nouveau signal" +#~ " démarre une nouvelle session d'historique," +#~ " distincte de celle contenant les " +#~ "opérations sur les images. Comme " +#~ "l'extraction du profil d'intensité est " +#~ "une opération effectuée sur une image," +#~ " la nouvelle session commence avec " +#~ "l'ajustement gaussien appliqué au signal " +#~ "obtenu." + +#~ msgid "" +#~ "The image-processing actions are " +#~ "recorded in the first session, while " +#~ "the Gaussian fit starts a separate " +#~ "session for the resulting signal." +#~ msgstr "" +#~ "Les actions de traitement d'image sont" +#~ " enregistrées dans la première session, " +#~ "tandis que l'ajustement gaussien démarre " +#~ "une session distincte pour le signal " +#~ "obtenu." + +#~ msgid "" +#~ "One approach utilizes the \"Cross " +#~ "section\" tool, which is provided by " +#~ "the `PlotPy <https://github.com/PlotPyStack/plotpy>` " +#~ "library that DataLab uses for signal " +#~ "and image visualization. Select an image" +#~ " from the \"Image panel\", choose the" +#~ " corresponding image in the visualization" +#~ " panel, and activate the \"Cross " +#~ "section\" tool |cross_section| from the " +#~ "vertical toolbar on the left side " +#~ "of the visualization panel. This reveals" +#~ " that the background noise level is" +#~ " approximately 30 lsb." +#~ msgstr "" +#~ "Une approche utilise l'outil \"Profil " +#~ "rectiligne\", qui est fourni par la " +#~ "bibliothèque `PlotPy " +#~ "<https://github.com/PlotPyStack/plotpy>` que DataLab " +#~ "utilise pour la visualisation de signaux" +#~ " et d'images. Sélectionnez une image " +#~ "dans le panneau \"Images\", choisissez " +#~ "l'image correspondante dans le panneau " +#~ "de visualisation, et activez l'outil " +#~ "\"Profil rectiligne\" |cross_section| depuis " +#~ "la barre d'outils verticale sur le " +#~ "côté gauche du panneau de visualisation." +#~ " Cela révèle que le niveau de " +#~ "bruit de fond est d'environ 30 " +#~ "lsb." + +#~ msgid "" +#~ "Another method for measuring background " +#~ "noise, also provided by `PlotPy " +#~ "<https://github.com/PlotPyStack/plotpy>`, involves using" +#~ " the \"Image statistics\" tool |imagestats|" +#~ " from the vertical toolbar on the " +#~ "left side of the visualization panel." +#~ " This tool displays statistical information" +#~ " for a rectangular region that you" +#~ " define by dragging the mouse across" +#~ " the image. This analysis confirms " +#~ "that the background noise level is " +#~ "approximately 30 lsb." +#~ msgstr "" +#~ "Une autre méthode pour mesurer le " +#~ "bruit de fond, également fournie par " +#~ "`PlotPy <https://github.com/PlotPyStack/plotpy>`, consiste" +#~ " à utiliser l'outil \"Statistiques de " +#~ "l'image\" |imagestats| de la barre " +#~ "d'outils verticale sur le côté gauche" +#~ " du panneau de visualisation. Cet " +#~ "outil affiche des informations statistiques" +#~ " pour une région rectangulaire que " +#~ "vous définissez en faisant glisser la" +#~ " souris sur l'image. Cette analyse " +#~ "confirme que le niveau de bruit de" +#~ " fond est d'environ 30 lsb." diff --git a/doc/locale/fr/LC_MESSAGES/release_notes/release_1.03.po b/doc/locale/fr/LC_MESSAGES/release_notes/release_1.03.po index 31222a321..fc5480658 100644 --- a/doc/locale/fr/LC_MESSAGES/release_notes/release_1.03.po +++ b/doc/locale/fr/LC_MESSAGES/release_notes/release_1.03.po @@ -5,7 +5,6 @@ # msgid "" msgstr "" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -57,75 +56,248 @@ msgstr "" "d'environnement obsolète sur une autre machine n'empêchera pas le " "démarrage de DataLab" -msgid "**Replace special values processing (signal and image):**" -msgstr "**Traitement de remplacement des valeurs spéciales (signal et image) :**" +msgid "**History Panel sessions:**" +msgstr "**Sessions du panneau d'historique :**" -msgid "DataLab now provides a dedicated **\"Replace special values\"** processing function that detects and replaces `NaN`, `+Inf` and `-Inf` values in both signals and images. The feature is available under **Processing → Level adjustment → Replace special values** in both the Signal and Image panels." -msgstr "DataLab fournit désormais une fonction de traitement dédiée **\"Remplacer les valeurs spéciales\"** qui détecte et remplace les valeurs `NaN`, `+Inf` et `-Inf` dans les signaux et les images. La fonctionnalité est disponible sous **Traitement → Ajustement des niveaux → Remplacer les valeurs spéciales** dans les panneaux Signal et Image." +msgid "" +"Added serialized and replayable history sessions with workspace-state " +"validation" +msgstr "" +"Ajout de sessions d'historique sérialisées et rejouables, avec validation" +" de l'état de l'espace de travail" -msgid "Each target (`NaN`, `+Inf`, `-Inf`) can be processed independently with its own strategy" -msgstr "Chaque cible (`NaN`, `+Inf`, `-Inf`) peut être traitée indépendamment avec sa propre stratégie" +msgid "" +"Added `.dlhist` import/export support and separated reset sessions from " +"regular history sessions" +msgstr "" +"Ajout de la prise en charge de l'import/export `.dlhist` et séparation " +"des sessions de réinitialisation des sessions d'historique ordinaires" + +msgid "Improved replay compatibility reporting for clearer user feedback" +msgstr "" +"Amélioration du rapport de compatibilité de relecture pour fournir un " +"retour utilisateur plus clair" + +msgid "" +"The Delete key now removes the selected entries in the History panel " +"(same behavior as in the Signal and Image panels), and only applies while" +" the history tree has focus" +msgstr "" -msgid "Signal strategies: do nothing, replace with zero / constant / minimum / maximum / mean / median, delete affected points, forward fill, backward fill, interpolation (linear, spline, quadratic, cubic, PCHIP), N-neighbor minimum / maximum / mean / median" -msgstr "Stratégies pour les signaux : ne rien faire, remplacer par zéro / constante / minimum / maximum / moyenne / médiane, supprimer les points affectés, remplissage avant, remplissage arrière, interpolation (linéaire, spline, quadratique, cubique, PCHIP), minimum / maximum / moyenne / médiane des N voisins" +msgid "" +"Added a resolution dialog when replaying a processing chain broken by " +"deleted objects: choose \"Repair and continue\" to prune the broken steps" +" and replay the remaining valid ones, or cancel without modifying " +"anything" +msgstr "" -msgid "Image strategies: do nothing, replace with zero / constant / minimum / maximum / mean / median, N-neighbor minimum / maximum / mean / median" -msgstr "Stratégies pour les images : ne rien faire, remplacer par zéro / constante / minimum / maximum / moyenne / médiane, minimum / maximum / moyenne / médiane des N voisins" +msgid "**Replace special values processing (signal and image):**" +msgstr "**Traitement de remplacement des valeurs spéciales (signal et image) :**" -msgid "The parameter dialog displays **colored badges** showing the number (and percentage) of `NaN`, `+Inf` and `-Inf` samples found in the source object, giving immediate visibility on what will be modified" -msgstr "La boîte de dialogue des paramètres affiche des **badges colorés** indiquant le nombre (et le pourcentage) d'échantillons `NaN`, `+Inf` et `-Inf` trouvés dans l'objet source, offrant une visibilité immédiate sur ce qui sera modifié" +msgid "" +"DataLab now provides a dedicated **\"Replace special values\"** " +"processing function that detects and replaces `NaN`, `+Inf` and `-Inf` " +"values in both signals and images. The feature is available under " +"**Processing → Level adjustment → Replace special values** in both the " +"Signal and Image panels." +msgstr "" +"DataLab fournit désormais une fonction de traitement dédiée **\"Remplacer" +" les valeurs spéciales\"** qui détecte et remplace les valeurs `NaN`, " +"`+Inf` et `-Inf` dans les signaux et les images. La fonctionnalité est " +"disponible sous **Traitement → Ajustement des niveaux → Remplacer les " +"valeurs spéciales** dans les panneaux Signal et Image." -msgid "When a neighbor strategy is selected, a **live kernel preview** shows the shape of the neighborhood that will be used for the replacement" -msgstr "Lorsqu'une stratégie de voisinage est sélectionnée, un **aperçu en direct du noyau** montre la forme du voisinage qui sera utilisé pour le remplacement" +msgid "" +"Each target (`NaN`, `+Inf`, `-Inf`) can be processed independently with " +"its own strategy" +msgstr "" +"Chaque cible (`NaN`, `+Inf`, `-Inf`) peut être traitée indépendamment " +"avec sa propre stratégie" -msgid "Integer images are handled explicitly: because `NaN` and infinite values cannot exist in integer data, the dialog explains that the operation is not applicable and prevents accidental processing, while preserving the original image data type without unnecessary float conversion" -msgstr "Les images entières sont traitées explicitement : comme les valeurs `NaN` et infinies ne peuvent pas exister dans les données entières, la boîte de dialogue explique que l'opération n'est pas applicable et empêche un traitement accidentel, tout en préservant le type de données d'image d'origine sans conversion inutile en flottant" +msgid "" +"Signal strategies: do nothing, replace with zero / constant / minimum / " +"maximum / mean / median, delete affected points, forward fill, backward " +"fill, interpolation (linear, spline, quadratic, cubic, PCHIP), N-neighbor" +" minimum / maximum / mean / median" +msgstr "" +"Stratégies pour les signaux : ne rien faire, remplacer par zéro / " +"constante / minimum / maximum / moyenne / médiane, supprimer les points " +"affectés, remplissage avant, remplissage arrière, interpolation " +"(linéaire, spline, quadratique, cubique, PCHIP), minimum / maximum / " +"moyenne / médiane des N voisins" -msgid "**History Panel sessions:**" -msgstr "**Sessions du panneau d'historique :**" +msgid "" +"Image strategies: do nothing, replace with zero / constant / minimum / " +"maximum / mean / median, N-neighbor minimum / maximum / mean / median" +msgstr "" +"Stratégies pour les images : ne rien faire, remplacer par zéro / " +"constante / minimum / maximum / moyenne / médiane, minimum / maximum / " +"moyenne / médiane des N voisins" msgid "" -"Added serialized and replayable history sessions with workspace-state " -"validation" +"The parameter dialog displays **colored badges** showing the number (and " +"percentage) of `NaN`, `+Inf` and `-Inf` samples found in the source " +"object, giving immediate visibility on what will be modified" msgstr "" -"Ajout de sessions d'historique sérialisées et rejouables, avec validation " -"de l'état de l'espace de travail" +"La boîte de dialogue des paramètres affiche des **badges colorés** " +"indiquant le nombre (et le pourcentage) d'échantillons `NaN`, `+Inf` et " +"`-Inf` trouvés dans l'objet source, offrant une visibilité immédiate sur " +"ce qui sera modifié" msgid "" -"Added `.dlhist` import/export support and separated reset sessions from " -"regular history sessions" +"When a neighbor strategy is selected, a **live kernel preview** shows the" +" shape of the neighborhood that will be used for the replacement" msgstr "" -"Ajout de la prise en charge de l'import/export `.dlhist` et séparation des " -"sessions de réinitialisation des sessions d'historique ordinaires" +"Lorsqu'une stratégie de voisinage est sélectionnée, un **aperçu en direct" +" du noyau** montre la forme du voisinage qui sera utilisé pour le " +"remplacement" -msgid "Improved replay compatibility reporting for clearer user feedback" +msgid "" +"Integer images are handled explicitly: because `NaN` and infinite values " +"cannot exist in integer data, the dialog explains that the operation is " +"not applicable and prevents accidental processing, while preserving the " +"original image data type without unnecessary float conversion" msgstr "" -"Amélioration du rapport de compatibilité de relecture pour fournir un retour " -"utilisateur plus clair" +"Les images entières sont traitées explicitement : comme les valeurs `NaN`" +" et infinies ne peuvent pas exister dans les données entières, la boîte " +"de dialogue explique que l'opération n'est pas applicable et empêche un " +"traitement accidentel, tout en préservant le type de données d'image " +"d'origine sans conversion inutile en flottant" msgid "🔄 Changes" msgstr "🔄 Modifications" msgid "**Detection tools now preserve existing regions of interest:**" -msgstr "**Les outils de détection préservent désormais les régions d'intérêt existantes :**" +msgstr "" +"**Les outils de détection préservent désormais les régions d'intérêt " +"existantes :**" -msgid "Regions of interest created by peak, blob, Hough circle, and contour detection are now added to existing ROIs instead of replacing them, without displaying a destructive confirmation dialog" -msgstr "Les régions d'intérêt créées par la détection de pics, de blobs, de cercles de Hough et de contours sont désormais ajoutées aux ROI existantes au lieu de les remplacer, sans afficher de boîte de dialogue de confirmation destructive" +msgid "" +"Regions of interest created by peak, blob, Hough circle, and contour " +"detection are now added to existing ROIs instead of replacing them, " +"without displaying a destructive confirmation dialog" +msgstr "" +"Les régions d'intérêt créées par la détection de pics, de blobs, de " +"cercles de Hough et de contours sont désormais ajoutées aux ROI " +"existantes au lieu de les remplacer, sans afficher de boîte de dialogue " +"de confirmation destructive" msgid "**Analysis results are now refreshed on demand instead of automatically:**" -msgstr "**Les résultats d'analyse sont désormais actualisés à la demande plutôt qu'automatiquement :**" +msgstr "" +"**Les résultats d'analyse sont désormais actualisés à la demande plutôt " +"qu'automatiquement :**" -msgid "Analysis results (statistics, FWHM, centroid, peak/contour/blob detection, etc.) are no longer recomputed automatically when you modify a region of interest, transform the data, or edit object properties" -msgstr "Les résultats d'analyse (statistiques, FWHM, centroïde, détection de pics/contours/blobs, etc.) ne sont plus recalculés automatiquement lorsque vous modifiez une région d'intérêt, transformez les données ou modifiez les propriétés de l'objet" +msgid "" +"Analysis results (statistics, FWHM, centroid, peak/contour/blob " +"detection, etc.) are no longer recomputed automatically when you modify a" +" region of interest, transform the data, or edit object properties" +msgstr "" +"Les résultats d'analyse (statistiques, FWHM, centroïde, détection de " +"pics/contours/blobs, etc.) ne sont plus recalculés automatiquement " +"lorsque vous modifiez une région d'intérêt, transformez les données ou " +"modifiez les propriétés de l'objet" + +msgid "" +"Existing analysis results are now left untouched after such edits, " +"avoiding surprising side effects and results that could become misleading" +" once the data no longer matches the stored analysis parameters" +msgstr "" +"Les résultats d'analyse existants sont désormais laissés intacts après de" +" telles modifications, évitant des effets de bord inattendus et des " +"résultats susceptibles de devenir trompeurs lorsque les données ne " +"correspondent plus aux paramètres d'analyse enregistrés" + +msgid "" +"Ordinary replay and ordinary mutations do not recompute analyses; " +"however, in History edit mode, editing upstream parameters recomputes " +"downstream analysis actions through the cascade" +msgstr "" +"La relecture ordinaire et les mutations ordinaires ne recalculent pas les" +" analyses ; toutefois, en mode d'édition de l'historique, la modification" +" de paramètres en amont recalcule les actions d'analyse en aval par " +"propagation en cascade" + +msgid "" +"The familiar **\"Recompute\"** action (Edit menu, `Ctrl+R`) now refreshes" +" both processing *and* analysis results, giving you full control over " +"when analyses are updated" +msgstr "" +"L'action familière **\"Recalculer\"** (menu Édition, `Ctrl+R`) actualise " +"désormais à la fois les résultats de traitement *et* d'analyse, vous " +"permettant de maîtriser pleinement le moment où les analyses sont mises à" +" jour" + +msgid "" +"For developers, the former panel-level `recompute_analysis` entry point " +"has been renamed to `recompute_selected`; `recompute_analysis` now refers" +" to a different processor-level helper dedicated to explicit 1-to-0 " +"analysis refresh" +msgstr "" +"Pour les développeurs, l'ancien point d'entrée `recompute_analysis` au " +"niveau du panneau a été renommé `recompute_selected` ; " +"`recompute_analysis` désigne désormais une autre fonction auxiliaire au " +"niveau du processeur, dédiée à l'actualisation explicite des analyses " +"1-vers-0" + +msgid "🛠️ Bug Fixes" +msgstr "" + +#, fuzzy +msgid "**History Panel:**" +msgstr "**Sessions du panneau d'historique :**" + +msgid "" +"Fixed replay of load actions doing nothing when the loaded objects had " +"been deleted while recording was active — the objects are now reloaded " +"from their files" +msgstr "" -msgid "Existing analysis results are now left untouched after such edits, avoiding surprising side effects and results that could become misleading once the data no longer matches the stored analysis parameters" -msgstr "Les résultats d'analyse existants sont désormais laissés intacts après de telles modifications, évitant des effets de bord inattendus et des résultats susceptibles de devenir trompeurs lorsque les données ne correspondent plus aux paramètres d'analyse enregistrés" +msgid "" +"Fixed duplicated processing chains interfering with their source chain: " +"replaying either session now only affects its own objects" +msgstr "" -msgid "Ordinary replay and ordinary mutations do not recompute analyses; however, in History edit mode, editing upstream parameters recomputes downstream analysis actions through the cascade" -msgstr "La relecture ordinaire et les mutations ordinaires ne recalculent pas les analyses ; toutefois, en mode d'édition de l'historique, la modification de paramètres en amont recalcule les actions d'analyse en aval par propagation en cascade" +msgid "" +"Fixed session replay aborting when the session contained a recorded " +"object deletion — recorded deletions that can no longer be safely applied" +" (captured state mismatch, targets re-created earlier in the same replay," +" or targets belonging to another session) are now skipped with a warning" +msgstr "" -msgid "The familiar **\"Recompute\"** action (Edit menu, `Ctrl+R`) now refreshes both processing *and* analysis results, giving you full control over when analyses are updated" -msgstr "L'action familière **\"Recalculer\"** (menu Édition, `Ctrl+R`) actualise désormais à la fois les résultats de traitement *et* d'analyse, vous permettant de maîtriser pleinement le moment où les analyses sont mises à jour" +msgid "" +"Removed the yellow highlight that could persist on history entries after " +"a failed replay" +msgstr "" + +msgid "" +"Fixed outdated steps having no visual indication in the history tree — " +"actions left outdated by a failed or interrupted recompute, or by " +"parameter edits pending propagation, are now highlighted with an amber " +"background and a tooltip suggesting to replay them" +msgstr "" + +msgid "" +"Fixed potential crashes or corrupted histories when clicking History " +"panel commands (Replay, Delete, Duplicate, ...) while a long replay or " +"recompute was still running — commands are now unavailable until the run " +"completes" +msgstr "" + +msgid "" +"Fixed a single corrupted history entry (e.g. a ROI saved by an " +"incompatible version) preventing an entire `.dlhist` file or HDF5 " +"workspace history from loading — the affected action now loads as " +"incompatible while the rest of the history loads normally" +msgstr "" + +msgid "" +"Fixed recording aborting the user's operation when a selected object had " +"no data" +msgstr "" + +msgid "" +"Improved performance: opening many files or replaying long processing " +"chains no longer freezes the interface while the History panel repeatedly" +" rechecks action compatibility" +msgstr "" -msgid "For developers, the former panel-level `recompute_analysis` entry point has been renamed to `recompute_selected`; `recompute_analysis` now refers to a different processor-level helper dedicated to explicit 1-to-0 analysis refresh" -msgstr "Pour les développeurs, l'ancien point d'entrée `recompute_analysis` au niveau du panneau a été renommé `recompute_selected` ; `recompute_analysis` désigne désormais une autre fonction auxiliaire au niveau du processeur, dédiée à l'actualisation explicite des analyses 1-vers-0" From 6678f6fb97dac8dd008c8a1d9ea8e867e979911c Mon Sep 17 00:00:00 2001 From: Stefano Pierini <s.pierini@codra.fr> Date: Fri, 14 Aug 2026 17:19:40 +0200 Subject: [PATCH 105/108] Doc: history panel - remove obsolete comment --- doc/intro/tutorials/history_panel.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/intro/tutorials/history_panel.rst b/doc/intro/tutorials/history_panel.rst index 895f161da..2b46e3fb2 100644 --- a/doc/intro/tutorials/history_panel.rst +++ b/doc/intro/tutorials/history_panel.rst @@ -135,8 +135,7 @@ deleted, so the action cannot be directly applied in the current workspace. .. figure:: ../../images/tutorials/history_panel/06.png - The deleted fitted signal is no longer listed in the Signal Panel. Its fit - action and the recorded deletion are grayed in the History Panel because + The deleted fitted signal is no longer listed in the Signal Panel. The recorded deletion is grayed in the History Panel because they cannot be replayed in the current workspace. We can now replay the fitting action: the resulting signal is recreated in the From 144609de697e83cdb82b92063ff842c9ff827859 Mon Sep 17 00:00:00 2001 From: Stefano Pierini <s.pierini@codra.fr> Date: Fri, 14 Aug 2026 17:21:12 +0200 Subject: [PATCH 106/108] Add French translations for the History Panel tutorial --- .../intro/tutorials/history_panel.po | 461 ++++++++++++++++++ 1 file changed, 461 insertions(+) create mode 100644 doc/locale/fr/LC_MESSAGES/intro/tutorials/history_panel.po diff --git a/doc/locale/fr/LC_MESSAGES/intro/tutorials/history_panel.po b/doc/locale/fr/LC_MESSAGES/intro/tutorials/history_panel.po new file mode 100644 index 000000000..9a5edcae0 --- /dev/null +++ b/doc/locale/fr/LC_MESSAGES/intro/tutorials/history_panel.po @@ -0,0 +1,461 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2023, DataLab Platform Developers +# This file is distributed under the same license as the DataLab package. +# FIRST AUTHOR <EMAIL@ADDRESS>, 2026. +# +msgid "" +msgstr "" +"Language: fr\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "" +"Tutorial on how to record, replay and share a processing chain with the " +"History Panel of DataLab, the open-source scientific data analysis and " +"visualization platform" +msgstr "" +"Tutoriel expliquant comment enregistrer, rejouer et partager une chaîne de " +"traitement avec le panneau d'historique de DataLab, la plateforme libre " +"d'analyse et de visualisation de données scientifiques" + +msgid "" +"DataLab, tutorial, history, record, replay, session, reproducibility, " +"processing chain, dlhist, HDF5" +msgstr "" +"DataLab, tutoriel, historique, enregistrement, rejeu, session, " +"reproductibilité, chaîne de traitement, dlhist, HDF5" + +msgid "" +":octicon:`book;1em;sd-text-info` Recording and replaying a processing " +"chain" +msgstr "" +":octicon:`book;1em;sd-text-info` Enregistrer et rejouer une chaîne de " +"traitement" + +msgid "" +"This tutorial shows how to use the **History Panel** to make a processing" +" workflow reproducible:" +msgstr "" +"Ce tutoriel explique comment utiliser le **panneau d'historique** afin de " +"rendre un flux de traitement reproductible :" + +msgid "Record a complete processing chain on a test signal" +msgstr "Enregistrer une chaîne de traitement complète sur un signal de test" + +msgid "Inspect the recorded actions and their workspace state" +msgstr "Inspecter les actions enregistrées et leur état de l'espace de travail" + +msgid "Replay the chain, and replay it step-by-step with modified parameters" +msgstr "Rejouer la chaîne, pas à pas et avec des paramètres modifiés" + +msgid "Duplicate a session to compare two processing variants" +msgstr "Dupliquer une session pour comparer deux variantes de traitement" + +msgid "Save the session and re-apply it to a different dataset" +msgstr "Enregistrer la session et l'appliquer à un autre jeu de données" + +msgid "" +"The reference documentation of the panel (toolbar, tree view, persistence" +" rules, chain reconnection) is available in the :ref:`historypanel` " +"section." +msgstr "" +"La documentation de référence du panneau (barre d'outils, vue en arbre, " +"règles de persistance et reconnexion de chaîne) est disponible dans la " +"section :ref:`historypanel`." + +msgid "Showing the History Panel" +msgstr "Afficher le panneau d'historique" + +msgid "" +"The History Panel is visible by default, but could be hidden in your " +"configuration. In this case, to display it, check the \"History Panel\" " +"entry in the \"View\" menu." +msgstr "" +"Le panneau d'historique est visible par défaut, mais il peut être masqué " +"dans votre configuration. Dans ce cas, cochez l'entrée \"Panneau " +"d'historique\" dans le menu \"Affichage\"." + +msgid "" +"The \"View > History Panel\" menu entry, which toggles the visibility of " +"the panel." +msgstr "" +"L'entrée \"Affichage > Panneau d'historique\", qui affiche ou masque le " +"panneau." + +msgid "" +"The panel is empty when it is first displayed. It is made of three parts:" +" a toolbar at the top, the tree of recorded sessions and actions in the " +"middle (with the \"Title\", \"Date and time\" and \"Description\" " +"columns), and the workspace state tables at the bottom (\"Signal\" / " +"\"Shape\" on the left, \"Image\" / \"Dimensions\" on the right)." +msgstr "" +"Le panneau est vide lors de sa première ouverture. Il comprend trois " +"parties : une barre d'outils en haut, l'arbre des sessions et actions " +"enregistrées au centre (colonnes \"Titre\", \"Date et heure\" et " +"\"Description\"), et les tableaux d'état de l'espace de travail en bas " +"(\"Signal\" / \"Forme\" à gauche, \"Image\" / \"Dimensions\" à droite)." + +msgid "The empty History Panel: toolbar, action tree and workspace state tables." +msgstr "" +"Le panneau d'historique vide : barre d'outils, arbre des actions et tableaux " +"d'état de l'espace de travail." + +msgid "" +"Like the other panels of DataLab, the History Panel is dockable: it can " +"be moved to any side of the main window, or detached as a floating " +"window. Here, it is docked on the left side, next to the Signal Panel, so" +" that the recorded actions remain visible while working on the data. We " +"use this configuration in the rest of the tutorial, but you can choose " +"any layout that suits your workflow." +msgstr "" +"Comme les autres panneaux de DataLab, le panneau d'historique est ancrable : " +"il peut être déplacé sur n'importe quel côté de la fenêtre principale ou " +"détaché dans une fenêtre flottante. Ici, il est ancré à gauche, près du " +"panneau des signaux, afin que les actions enregistrées restent visibles " +"pendant le traitement des données. Cette configuration est utilisée dans la " +"suite du tutoriel, mais vous pouvez choisir celle qui convient à votre flux." + +msgid "The History Panel docked on the left side of the main window." +msgstr "Le panneau d'historique ancré à gauche de la fenêtre principale." + +msgid "Recording a processing chain" +msgstr "Enregistrer une chaîne de traitement" + +msgid "" +"Recording is disabled by default: the History Panel only starts " +"collecting actions once the |record| **Record mode** button is enabled in" +" its toolbar." +msgstr "" +"L'enregistrement est désactivé par défaut : le panneau d'historique ne " +"commence à collecter les actions qu'après l'activation du bouton |record| " +"**Mode d'enregistrement** de sa barre d'outils." + +msgid "record" +msgstr "enregistrer" + +msgid "" +"The first object created after enabling the recording opens a new " +"**session**, which acts as a container for the whole processing chain. " +"From then on, every action producing or modifying an object -- creating a" +" signal, running a computation, removing an object -- is appended to that" +" session." +msgstr "" +"Le premier objet créé après l'activation de l'enregistrement ouvre une " +"nouvelle **session**, qui contient toute la chaîne de traitement. Dès lors, " +"chaque action produisant ou modifiant un objet -- création d'un signal, " +"exécution d'un calcul, suppression d'un objet -- est ajoutée à cette session." + +msgid "" +"When a new object is created afterwards, DataLab asks whether the current" +" session should be closed and a new one started. Since we want to record " +"a single, continuous processing chain, we answer **No** to keep appending" +" to the session already in progress." +msgstr "" +"Lorsqu'un nouvel objet est ensuite créé, DataLab demande si la session " +"courante doit être fermée et si une nouvelle doit être ouverte. Comme nous " +"voulons enregistrer une unique chaîne de traitement continue, nous répondons " +"**Non** afin de continuer à ajouter les actions à la session en cours." + +msgid "" +"To illustrate the recording of a processing chain, let's create a test " +"using the \"Create > Gaussian\" menu entry and then add to it some noise " +"using \"Processing > Noise Addition > Gaussian Noise\"." +msgstr "" +"Pour illustrer l'enregistrement d'une chaîne de traitement, créons un " +"signal de test avec l'entrée \"Créer > Gaussienne\", puis ajoutons-lui du " +"bruit avec \"Traitement > Ajout de bruit > Bruit gaussien\"." + +msgid "The History Panel after creating a Gaussian signal and adding noise to it." +msgstr "" +"Le panneau d'historique après la création d'un signal gaussien et l'ajout de " +"bruit." + +msgid "" +"The tree now contains a **Processing** session with the two recorded " +"actions: the creation of the Gaussian signal and the addition of Gaussian" +" noise. The selected noise action exposes its parameters in the " +"description column. The Signal Panel shows both the original and " +"resulting signals, while the Processing Parameters panel displays the " +"seed, mean and standard deviation used for the selected action." +msgstr "" +"L'arbre contient maintenant une session **Traitement** avec les deux actions " +"enregistrées : la création du signal gaussien et l'ajout de bruit gaussien. " +"L'action de bruit sélectionnée expose ses paramètres dans la colonne de " +"description. Le panneau des signaux affiche les signaux d'origine et " +"résultant, tandis que le panneau des paramètres de traitement affiche la " +"graine, la moyenne et l'écart type utilisés par l'action sélectionnée." + +msgid "" +"To create a longer chain, we can apply a few more processing steps, for " +"example a fitting. Once done, the action is recorded in the History " +"Panel, and the resulting signal is displayed in the Signal Panel." +msgstr "" +"Pour créer une chaîne plus longue, nous pouvons appliquer quelques étapes de " +"traitement supplémentaires, par exemple un ajustement. Une fois terminé, " +"l'action est enregistrée dans le panneau d'historique et le signal résultant " +"est affiché dans le panneau des signaux." + +msgid "The History Panel after fitting the noisy signal." +msgstr "Le panneau d'historique après l'ajustement du signal bruité." + +msgid "Familiarizing with the history panel commands" +msgstr "Découvrir les commandes du panneau d'historique" + +msgid "" +"Now we have a very simple processing chain, which is enough to illustrate" +" the main features of the History Panel. The toolbar provides the " +"following commands:" +msgstr "" +"Nous disposons maintenant d'une chaîne de traitement très simple, suffisante " +"pour illustrer les principales fonctionnalités du panneau d'historique. La " +"barre d'outils propose les commandes suivantes :" + +msgid "**Record mode** toggles the recording of subsequent actions." +msgstr "Le **Mode d'enregistrement** active ou désactive l'enregistrement des actions suivantes." + +msgid "**New session** starts a separate history session." +msgstr "**Nouvelle session** ouvre une session d'historique distincte." + +msgid "" +"**Open history file** and **Save history file** load or save a standalone" +" ``.dlhist`` history file." +msgstr "" +"**Ouvrir un fichier d'historique** et **Enregistrer un fichier d'historique** " +"chargent ou enregistrent un fichier d'historique autonome ``.dlhist``." + +msgid "" +"**Previous step** and **Next step** select the adjacent action in the " +"current session." +msgstr "" +"**Étape précédente** et **Étape suivante** sélectionnent l'action voisine " +"dans la session courante." + +msgid "" +"**Replay** applies the selected session or action without showing " +"parameter dialogs, whereas **Step-by-step** replays it while allowing " +"parameters to be edited at each step." +msgstr "" +"**Rejouer** applique la session ou l'action sélectionnée sans afficher de " +"dialogue de paramètres, tandis que **Pas à pas** la rejoue en permettant de " +"modifier les paramètres à chaque étape." + +msgid "" +"**Duplicate** copies the selected session, or the complete session " +"containing the selected action, to compare a processing variant." +msgstr "" +"**Dupliquer** copie la session sélectionnée, ou la session complète contenant " +"l'action sélectionnée, afin de comparer une variante de traitement." + +msgid "" +"**Remove incompatible** removes actions that cannot be directly applied " +"in the current workspace (i.e. because a signal has been deleted), and " +"**Delete** removes the selected history entry." +msgstr "" +"**Supprimer les incompatibles** supprime les actions qui ne peuvent pas être " +"appliquées directement dans l'espace de travail courant (par exemple parce " +"qu'un signal a été supprimé), et **Supprimer** efface l'entrée d'historique " +"sélectionnée." + +msgid "" +"When an action is selected in the tree, the corresponding resulting " +"signal is displayed in the Signal Panel." +msgstr "" +"Lorsqu'une action est sélectionnée dans l'arbre, le signal résultant " +"correspondant est affiché dans le panneau des signaux." + +msgid "" +"Now select the fitting signal in the Signal Panel, and delete it using " +"the \"Delete\" button in the toolbar or pressing the \"Delete\" key. The " +"fitting action is still available in the History Panel, as it can be " +"replayed using the **Replay** button. In addition, the delete action has " +"been recorded in the history, but it is grayed: the reason is that the " +"fitting signal has been deleted, so the action cannot be directly applied" +" in the current workspace." +msgstr "" +"Sélectionnez maintenant le signal ajusté dans le panneau des signaux et " +"supprimez-le avec le bouton \"Supprimer\" de la barre d'outils ou la touche " +"\"Supprimer\". L'action d'ajustement reste disponible dans le panneau " +"d'historique, car elle peut être rejouée avec le bouton **Rejouer**. L'action " +"de suppression est également enregistrée dans l'historique, mais elle est " +"grisée : le signal ajusté a été supprimé, l'action ne peut donc pas être " +"appliquée directement dans l'espace de travail courant." + +msgid "" +"The deleted fitted signal is no longer listed in the Signal Panel. The " +"recorded deletion is grayed in the History Panel because they cannot be " +"replayed in the current workspace." +msgstr "" +"Le signal ajusté supprimé ne figure plus dans le panneau des signaux. La " +"suppression enregistrée est grisée dans le panneau d'historique, car elle ne " +"peut pas être rejouée dans l'espace de travail courant." + +msgid "" +"We can now replay the fitting action: the resulting signal is recreated " +"in the Signal Panel and the \"delete\" action is no longer grayed, as it " +"can now be applied to the newly created signal." +msgstr "" +"Nous pouvons maintenant rejouer l'action d'ajustement : le signal résultant " +"est recréé dans le panneau des signaux et l'action \"supprimer\" n'est plus " +"grisée, car elle peut désormais être appliquée au signal nouvellement créé." + +msgid "" +"Replaying the fit recreates the fitting signal. All recorded actions are " +"again compatible with the current workspace." +msgstr "" +"Le rejeu de l'ajustement recrée le signal ajusté. Toutes les actions " +"enregistrées sont de nouveau compatibles avec l'espace de travail courant." + +msgid "Duplicating the chain to compare variants" +msgstr "Dupliquer la chaîne pour comparer des variantes" + +msgid "" +"We can now duplicate the chain to compare two processing variants. First " +"of all, delete the \"Remove selected objects\" history record using the " +"Delete key. Then select the **Processing** session in the History Panel " +"and click **Duplicate**. DataLab creates a new **Processing Copy** " +"session and a ``Copy - Processing`` group in the Signal Panel. This group" +" contains independent copies of the signals used and produced by the " +"original chain." +msgstr "" +"Nous pouvons maintenant dupliquer la chaîne pour comparer deux variantes de " +"traitement. Commencez par supprimer l'enregistrement \"Supprimer les objets " +"sélectionnés\" avec la touche Supprimer. Sélectionnez ensuite la session " +"**Traitement** dans le panneau d'historique et cliquez sur **Dupliquer**. " +"DataLab crée une nouvelle session **Copie de traitement** et un groupe " +"``Copie - Traitement`` dans le panneau des signaux. Ce groupe contient des " +"copies indépendantes des signaux utilisés et produits par la chaîne d'origine." + +msgid "" +"The **Processing Copy** session contains the duplicated actions. The " +"``Copy - Processing`` group contains the independent signal copies." +msgstr "" +"La session **Copie de traitement** contient les actions dupliquées. Le groupe " +"``Copie - Traitement`` contient les copies indépendantes des signaux." + +msgid "" +"To create a variant, select the **Processing Copy** session and click " +"**Step-by-step**. DataLab displays a parameter dialog for each action. In" +" the **Add Gaussian noise** dialog, change the noise level, for example " +"set ``sigma`` to ``0.05``, then accept the remaining dialogs. The copied " +"signal chain is recomputed in place: its noisy signal and fit now use the" +" new noise level, while the original **Processing** session remains " +"unchanged." +msgstr "" +"Pour créer une variante, sélectionnez la session **Copie de traitement** et " +"cliquez sur **Pas à pas**. DataLab affiche un dialogue de paramètres pour " +"chaque action. Dans le dialogue **Ajouter du bruit gaussien**, modifiez le " +"niveau de bruit, par exemple en réglant ``sigma`` à ``0.05``, puis validez " +"les dialogues restants. La chaîne de signaux copiée est recalculée sur place : " +"son signal bruité et son ajustement utilisent alors le nouveau niveau de " +"bruit, tandis que la session **Traitement** d'origine reste inchangée." + +msgid "" +"The selected noise action in **Processing Copy** uses ``sigma = 0.05``. " +"The original chain and the modified copy remain available side by side." +msgstr "" +"L'action de bruit sélectionnée dans **Copie de traitement** utilise " +"``sigma = 0.05``. La chaîne d'origine et la copie modifiée restent " +"disponibles côte à côte." + +msgid "" +"This can be useful to compare the effect of the noise level on the " +"fitting result, or to explore other processing variants. In this example," +" selecting both the original and copied fitting signals in the Signal " +"Panel shows a difference between them, but it is quite slight." +msgstr "" +"Cela peut servir à comparer l'effet du niveau de bruit sur le résultat de " +"l'ajustement, ou à explorer d'autres variantes de traitement. Dans cet " +"exemple, sélectionner les signaux ajustés d'origine et copié dans le panneau " +"des signaux montre une différence, mais elle est faible." + +msgid "Recording an image-to-signal workflow" +msgstr "Enregistrer un flux de traitement d'image vers signal" + +msgid "" +"The History Panel records workflows across both data panels in the same " +"session. Unlike the Signal Panel and Image Panel, it is not divided by " +"data type: its chronological tree shows image operations and any signals " +"that they produce together." +msgstr "" +"Le panneau d'historique enregistre les flux de travail des deux panneaux de " +"données dans une même session. Contrairement aux panneaux des signaux et des " +"images, il n'est pas séparé par type de données : son arbre chronologique " +"affiche ensemble les opérations sur les images et les signaux qu'elles " +"produisent." + +msgid "" +"To illustrate this behavior, we will start from a clean workspace. " +"Alternatively, click **New session** in the History Panel to record it in" +" a new session of your current workspace." +msgstr "" +"Pour illustrer ce comportement, nous partirons d'un espace de travail vide. " +"Vous pouvez aussi cliquer sur **Nouvelle session** dans le panneau " +"d'historique afin de l'enregistrer dans une nouvelle session de l'espace de " +"travail courant." + +msgid "" +"In both cases, activate the history recording and switch to the **Image " +"Panel**." +msgstr "" +"Dans les deux cas, activez l'enregistrement de l'historique et basculez vers " +"le **panneau des images**." + +msgid "" +"Create or open a test image and apply a first noise-reduction operation, " +"for example **Processing > Noise reduction > Moving Average**. As you can" +" see, for images the history is recorded at the same way that it is for " +"signals." +msgstr "" +"Créez ou ouvrez une image de test et appliquez une première opération de " +"réduction du bruit, par exemple **Traitement > Réduction du bruit > Moyenne " +"mobile**. Comme vous le constatez, l'historique des images est enregistré de " +"la même façon que celui des signaux." + +msgid "" +"The new image and its moving-average result are recorded in the same " +"History Panel session." +msgstr "" +"La nouvelle image et le résultat de sa moyenne mobile sont enregistrés dans " +"la même session du panneau d'historique." + +msgid "" +"Select the filtered image and choose **Analysis > Intensity profiles > " +"Line profile...**. Set the horizontal line in the profile dialog, then " +"confirm it. DataLab adds the extracted profile to the Signal Panel, while" +" the History Panel appends the **Line profile** action to the same " +"session after the image-processing actions." +msgstr "" +"Sélectionnez l'image filtrée et choisissez **Analyse > Profils d'intensité > " +"Profil linéaire...**. Définissez la ligne horizontale dans le dialogue de " +"profil, puis validez. DataLab ajoute le profil extrait au panneau des " +"signaux, tandis que le panneau d'historique ajoute l'action **Profil " +"linéaire** à la même session, après les actions de traitement d'image." + +msgid "" +"Choose the horizontal line used to extract the profile from the filtered " +"image." +msgstr "" +"Choisissez la ligne horizontale utilisée pour extraire le profil de l'image " +"filtrée." + +msgid "" +"This single history session therefore captures the full workflow: image " +"creation, noise reduction, and conversion of image data into a signal. " +"Selecting the image actions in the History Panel activates the Image " +"Panel; selecting the profile action activates the Signal Panel and " +"selects the resulting signal." +msgstr "" +"Cette unique session d'historique capture donc tout le flux de travail : " +"création d'image, réduction du bruit et conversion des données d'image en " +"signal. La sélection d'une action sur une image dans le panneau d'historique " +"active le panneau des images ; celle de l'action de profil active le panneau " +"des signaux et sélectionne le signal résultant." + +msgid "" +"The History Panel records the image operations and the resulting signal " +"in one chronological session." +msgstr "" +"Le panneau d'historique enregistre les opérations sur l'image et le signal " +"résultant dans une unique session chronologique." From 627ff33e94e677844ab10e82a352fc324de52bb5 Mon Sep 17 00:00:00 2001 From: Stefano Pierini <s.pierini@codra.fr> Date: Fri, 14 Aug 2026 17:50:55 +0200 Subject: [PATCH 107/108] Doc: improve History Panel tutorial and update French translations --- doc/intro/tutorials/history_panel.rst | 16 +++++----- .../intro/tutorials/history_panel.po | 30 +++++++++---------- 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/doc/intro/tutorials/history_panel.rst b/doc/intro/tutorials/history_panel.rst index 2b46e3fb2..682f14711 100644 --- a/doc/intro/tutorials/history_panel.rst +++ b/doc/intro/tutorials/history_panel.rst @@ -17,7 +17,6 @@ workflow reproducible: - Inspect the recorded actions and their workspace state - Replay the chain, and replay it step-by-step with modified parameters - Duplicate a session to compare two processing variants -- Save the session and re-apply it to a different dataset .. seealso:: @@ -135,8 +134,9 @@ deleted, so the action cannot be directly applied in the current workspace. .. figure:: ../../images/tutorials/history_panel/06.png - The deleted fitted signal is no longer listed in the Signal Panel. The recorded deletion is grayed in the History Panel because - they cannot be replayed in the current workspace. + The deleted fitted signal is no longer listed in the Signal Panel. The + recorded deletion is grayed in the History Panel because it cannot be + replayed in the current workspace. We can now replay the fitting action: the resulting signal is recreated in the Signal Panel and the "delete" action is no longer grayed, as it can now be @@ -153,11 +153,11 @@ Duplicating the chain to compare variants ----------------------------------------- We can now duplicate the chain to compare two processing variants. First of all, -delete the "Remove selected objects" history record using the Delete key. Then -select the **Processing** session in the History Panel and click **Duplicate**. +select the "Remove selected objects" entry in the History Panel and press the +Delete key. Then select the **Processing** session and click **Duplicate**. DataLab creates a new **Processing Copy** session and a ``Copy - Processing`` -group in the Signal Panel. This group contains independent copies of the signals -used and produced by the original chain. +group in the Signal Panel. This group contains independent copies of the +signals used and produced by the original chain. .. figure:: ../../images/tutorials/history_panel/08.png @@ -197,7 +197,7 @@ In both cases, activate the history recording and switch to the **Image Panel**. Create or open a test image and apply a first noise-reduction operation, for example **Processing > Noise reduction > Moving Average**. As you can see, for -images the history is recorded at the same way that it is for signals. +images the history is recorded in the same way that it is for signals. .. figure:: ../../images/tutorials/history_panel/10.png diff --git a/doc/locale/fr/LC_MESSAGES/intro/tutorials/history_panel.po b/doc/locale/fr/LC_MESSAGES/intro/tutorials/history_panel.po index 9a5edcae0..76e4e9ad7 100644 --- a/doc/locale/fr/LC_MESSAGES/intro/tutorials/history_panel.po +++ b/doc/locale/fr/LC_MESSAGES/intro/tutorials/history_panel.po @@ -53,9 +53,6 @@ msgstr "Rejouer la chaîne, pas à pas et avec des paramètres modifiés" msgid "Duplicate a session to compare two processing variants" msgstr "Dupliquer une session pour comparer deux variantes de traitement" -msgid "Save the session and re-apply it to a different dataset" -msgstr "Enregistrer la session et l'appliquer à un autre jeu de données" - msgid "" "The reference documentation of the panel (toolbar, tree view, persistence" " rules, chain reconnection) is available in the :ref:`historypanel` " @@ -284,7 +281,7 @@ msgstr "" msgid "" "The deleted fitted signal is no longer listed in the Signal Panel. The " -"recorded deletion is grayed in the History Panel because they cannot be " +"recorded deletion is grayed in the History Panel because it cannot be " "replayed in the current workspace." msgstr "" "Le signal ajusté supprimé ne figure plus dans le panneau des signaux. La " @@ -312,20 +309,21 @@ msgstr "Dupliquer la chaîne pour comparer des variantes" msgid "" "We can now duplicate the chain to compare two processing variants. First " -"of all, delete the \"Remove selected objects\" history record using the " -"Delete key. Then select the **Processing** session in the History Panel " -"and click **Duplicate**. DataLab creates a new **Processing Copy** " -"session and a ``Copy - Processing`` group in the Signal Panel. This group" -" contains independent copies of the signals used and produced by the " +"of all, select the \"Remove selected objects\" entry in the History Panel " +"and press the Delete key. Then select the **Processing** session and " +"click **Duplicate**. DataLab creates a new **Processing Copy** session " +"and a ``Copy - Processing`` group in the Signal Panel. This group " +"contains independent copies of the signals used and produced by the " "original chain." msgstr "" "Nous pouvons maintenant dupliquer la chaîne pour comparer deux variantes de " -"traitement. Commencez par supprimer l'enregistrement \"Supprimer les objets " -"sélectionnés\" avec la touche Supprimer. Sélectionnez ensuite la session " -"**Traitement** dans le panneau d'historique et cliquez sur **Dupliquer**. " -"DataLab crée une nouvelle session **Copie de traitement** et un groupe " -"``Copie - Traitement`` dans le panneau des signaux. Ce groupe contient des " -"copies indépendantes des signaux utilisés et produits par la chaîne d'origine." +"traitement. Commencez par sélectionner l'entrée \"Supprimer les objets " +"sélectionnés\" dans le panneau d'historique, puis appuyez sur la touche " +"Supprimer. Sélectionnez ensuite la session **Traitement** et cliquez sur " +"**Dupliquer**. DataLab crée une nouvelle session **Copie de traitement** et " +"un groupe ``Copie - Traitement`` dans le panneau des signaux. Ce groupe " +"contient des copies indépendantes des signaux utilisés et produits par la " +"chaîne d'origine." msgid "" "The **Processing Copy** session contains the duplicated actions. The " @@ -405,7 +403,7 @@ msgstr "" msgid "" "Create or open a test image and apply a first noise-reduction operation, " "for example **Processing > Noise reduction > Moving Average**. As you can" -" see, for images the history is recorded at the same way that it is for " +" see, for images the history is recorded in the same way that it is for " "signals." msgstr "" "Créez ou ouvrez une image de test et appliquez une première opération de " From 53c20b11d5cd44686d31c1bce517cc6263c06b1a Mon Sep 17 00:00:00 2001 From: Stefano Pierini <s.pierini@codra.fr> Date: Fri, 14 Aug 2026 19:08:06 +0200 Subject: [PATCH 108/108] Update French translations for history panel and related messages --- datalab/locale/fr/LC_MESSAGES/datalab.po | 671 ++++++++++++++++++----- 1 file changed, 544 insertions(+), 127 deletions(-) diff --git a/datalab/locale/fr/LC_MESSAGES/datalab.po b/datalab/locale/fr/LC_MESSAGES/datalab.po index 5681f2dc5..ce50938ec 100644 --- a/datalab/locale/fr/LC_MESSAGES/datalab.po +++ b/datalab/locale/fr/LC_MESSAGES/datalab.po @@ -4,6 +4,7 @@ # msgid "" msgstr "" +"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" @@ -373,12 +374,6 @@ msgstr "Sélectionner le ou les objets source utilisés pour créer l'objet %s s msgid "Edit title of selected %s or group" msgstr "Modifier le titre de l'objet %s ou du groupe sélectionné" -msgid "Reset to computed title" -msgstr "Réinitialiser au titre calculé" - -msgid "Restore the title generated by the processing operation" -msgstr "Restaurer le titre généré par l'opération de traitement" - msgid "New group..." msgstr "Nouveau groupe..." @@ -954,6 +949,9 @@ msgstr "Tapez pour rechercher une commande…" msgid "Search a command…" msgstr "Rechercher une commande…" +msgid "Custom signal" +msgstr "Signal personnalisé" + msgid "Process signal" msgstr "Traiter le signal" @@ -967,6 +965,46 @@ msgstr "Troncature de données uint32 en int32." msgid "No supported data available in HDF5 file(s)." msgstr "Aucune donnée prise en charge dans le(s) fichier(s) HDF5." +msgid "A new object was loaded. Start a new history session?" +msgstr "Un nouvel objet a été chargé. Démarrer une nouvelle session d'historique ?" + +msgid "A new object was created. Start a new history session?" +msgstr "Un nouvel objet a été créé. Démarrer une nouvelle session d'historique ?" + +msgid "New history session" +msgstr "Nouvelle session d'historique" + +msgid "Initial state" +msgstr "État initial" + +msgid "Chain copy" +msgstr "Copie de chaîne" + +msgid "" +"Do you really want to delete the selected items?\n" +"\n" +"Note: deleting an intermediate action splits its processing chain; downstream steps become an independent chain." +msgstr "" +"Êtes-vous sûr de vouloir supprimer les éléments sélectionnés ?\n" +"\n" +"Remarque : la suppression d'une action intermédiaire divise sa chaîne de traitement ; les étapes en aval deviennent une chaîne indépendante." + +msgid "Do you really want to delete the selected items?" +msgstr "Êtes-vous sûr de vouloir supprimer le(s) groupe(s) sélectionné(s) ?" + +msgid "The deleted action(s) produced object(s) still present in the workspace. Do you want to remove the associated object(s) as well?" +msgstr "La ou les actions supprimées ont produit des objets encore présents dans l'espace de travail. Voulez-vous également supprimer le ou les objets associés ?" + +msgid "Remove incompatible" +msgstr "Supprimer les actions incompatibles" + +msgid "All actions are compatible with the current workspace." +msgstr "Toutes les actions sont compatibles avec l'espace de travail actuel." + +#, python-format +msgid "%d incompatible action(s) will be removed. Continue?" +msgstr "%d action(s) incompatible(s) seront supprimées. Continuer ?" + msgid "Macro simple example" msgstr "Exemple simple de macro" @@ -1213,6 +1251,9 @@ msgstr "Console" msgid "Macro Panel" msgstr "Gestionnaire de Macros" +msgid "History Panel" +msgstr "Historique" + msgid "Disable auto-refresh?" msgstr "Désactiver le rafraîchissement automatique ?" @@ -1250,6 +1291,17 @@ msgstr "Ouvrir" msgid "HDF5 files (*.h5 *.hdf5 *.hdf *.he5);;All files (*)" msgstr "Fichiers HDF5 (*.h5 *.hdf5 *.hdf *.he5);;Tous les fichiers (*)" +#, python-format +msgid "Open %d HDF5 files" +msgstr "Ouvrir %d fichiers HDF5" + +msgid "Open HDF5 file" +msgstr "Ouvrir un fichier HDF5" + +#, python-format +msgid "New %s" +msgstr "Créer un nouvel objet %s" + msgid "not started" msgstr "non démarré" @@ -1313,9 +1365,6 @@ msgstr "Modifier la courbe graphiquement" msgid "Insert point" msgstr "Insérer un point" -msgid "Custom signal" -msgstr "Signal personnalisé" - msgid "Object metadata" msgstr "Métadonnées de l'objet" @@ -1328,12 +1377,6 @@ msgstr "groupe" msgid "Source objects" msgstr "Objets source" -msgid "deleted" -msgstr "supprimé" - -msgid "Deleted source objects" -msgstr "Objets source supprimés" - msgid "Drag files here to open" msgstr "Déposer des fichiers ici pour les ouvrir" @@ -1405,15 +1448,6 @@ msgstr "" "Échec de la conversion des paramètres de création historiques :\n" "%s" -msgid "Signal was modified in-place." -msgstr "Le signal a été modifié en place." - -msgid "Image was modified in-place." -msgstr "L'image a été modifiée en place." - -msgid "If computation were performed based on this object, they may need to be redone." -msgstr "Si des calculs ont été effectués à partir de cet objet, il peut être nécessaire de les refaire." - #, python-format msgid "" "Failed to recreate object with new parameters:\n" @@ -1422,12 +1456,67 @@ msgstr "" "Échec de la recréation de l'objet avec les nouveaux paramètres :\n" "%s" +msgid "Signal was recreated." +msgstr "Le signal a été recréé." + +msgid "Image was recreated." +msgstr "L'image a été recréée." + msgid "Processing Parameters" msgstr "Paramètres de traitement" +msgid "Auto-recompute on edit" +msgstr "Recalcul automatique lors de l'édition" + +msgid "Automatically re-run processing when parameters are modified" +msgstr "Relancer automatiquement le traitement à chaque modification de paramètre" + +msgid "Analysis Parameters" +msgstr "Paramètres d'analyse" + +msgid "Analysis metadata is incomplete." +msgstr "Les métadonnées d'analyse sont incomplètes." + +#, python-format +msgid "" +"Failed to recompute analysis:\n" +"%s" +msgstr "" +"Échec du recalcul de l'analyse :\n" +"%s" + +msgid "Failed to recompute analysis." +msgstr "Échec du recalcul de l'analyse." + +msgid "Analysis was recomputed." +msgstr "L'analyse a été recalculée." + msgid "No processing object available." msgstr "Aucun objet de traitement disponible." +msgid "Processing metadata is incomplete." +msgstr "Les métadonnées de traitement sont incomplètes." + +msgid "Source object no longer exists." +msgstr "L'objet source n'existe plus." + +msgid "The object that was used to create this processed object has been deleted and cannot be used for reprocessing." +msgstr "L'objet qui a été utilisé pour créer cet objet traité a été supprimé et ne peut pas être utilisé pour le retraitement." + +#, python-format +msgid "" +"Failed to reprocess object:\n" +"%s" +msgstr "" +"Échec du retraitement de l'objet :\n" +"%s" + +msgid "Processing was cancelled." +msgstr "Le traitement a été annulé." + +msgid "Failed to reprocess object." +msgstr "Échec du retraitement de l'objet." + msgid "Geometry results" msgstr "Résultats géométriques" @@ -1440,6 +1529,9 @@ msgstr "Autres métadonnées" msgid "Save to directory" msgstr "Enregistrer dans un répertoire" +msgid "Pattern help" +msgstr "Aide sur le motif" + msgid "Directory" msgstr "Répertoire" @@ -1491,6 +1583,9 @@ msgstr "Modèle de valeur" msgid "Conversion" msgstr "Conversion" +msgid "Duplicate object or group" +msgstr "Dupliquer l'objet ou le groupe" + msgid "Select what to keep from the clipboard.<br><br>Result shapes and annotations, if kept, will be merged with existing ones. <u>All other metadata will be replaced</u>." msgstr "Sélectionnez ce que vous souhaitez conserver dans le presse-papier.<br><br>Les formes graphiques et les annotations, si conservées, seront fusionnées avec celles existantes. <u>Toutes les autres métadonnées seront remplacées</u>." @@ -1500,6 +1595,9 @@ msgstr "Supprimer le(s) groupe(s)" msgid "Are you sure you want to delete the selected group(s)?" msgstr "Êtes-vous sûr de vouloir supprimer le(s) groupe(s) sélectionné(s) ?" +msgid "Remove selected objects" +msgstr "Supprimer les objets sélectionnés" + #, python-format msgid "Do you want to delete all objects (%s)?" msgstr "Souhaitez-vous supprimer tous les objets (%s) ?" @@ -1510,11 +1608,18 @@ msgstr "Supprimer les métadonnées" msgid "Some selected objects have regions of interest.<br>Do you want to delete them as well?" msgstr "Certains objets sélectionnés ont des régions d'intérêt.<br>Souhaitez-vous les supprimer également ?" +msgid "New group" +msgstr "Nouveau groupe" + msgid "Group name:" msgstr "Nom du groupe :" -msgid "New group" -msgstr "Nouveau groupe" +#, python-format +msgid "New group \"%s\"" +msgstr "Nouveau groupe \"%s\"" + +msgid "Rename selected object or group" +msgstr "Renommer l'objet ou le groupe sélectionné" msgid "Rename object" msgstr "Renommer l'objet" @@ -1525,18 +1630,42 @@ msgstr "Nom de l'objet :" msgid "Rename group" msgstr "Renommer le groupe" +#, python-format +msgid "Set current object title to \"%s\"" +msgstr "Définir le titre de l'objet courant à \"%s\"" + msgid "Reading objects from file" msgstr "Lecture des objets depuis le fichier" msgid "Adding objects to workspace" msgstr "Ajout d'objets à l'espace de travail" +#, python-format +msgid "Load from directory \"%s\"" +msgstr "Charger depuis le répertoire \"%s\"" + msgid "Scanning directory" msgstr "Analyse du répertoire" +#, python-format +msgid "Load from %d files" +msgstr "Charger depuis %d fichiers" + +#, python-format +msgid "Load \"%s\"" +msgstr "Charger \"%s\"" + msgid "Save as" msgstr "Enregistrer sous" +#, python-format +msgid "Save to %d different files" +msgstr "Enregistrer dans %d fichiers différents" + +#, python-format +msgid "Save to \"%s\"" +msgstr "Enregistrer dans \"%s\"" + msgid "Saving..." msgstr "Enregistrement en cours..." @@ -1552,80 +1681,309 @@ msgstr "L'objet (ou les objets) sélectionné(s) n'ont pas de paramètres de tra msgid "Recomputing objects" msgstr "Retraitement des objets" -msgid "Failed to recompute object" -msgstr "Échec du retraitement de l'objet" +msgid "Failed to recompute object" +msgstr "Échec du retraitement de l'objet" + +msgid "Do you want to continue with the next object?" +msgstr "Souhaitez-vous continuer avec l'objet suivant ?" + +msgid "Recomputing analyses" +msgstr "Recalcul des analyses" + +msgid "Analysis computation failed." +msgstr "Le calcul de l'analyse a échoué." + +msgid "Failed to recompute analysis" +msgstr "Échec du recalcul de l'analyse" + +msgid "Selected object does not have processing metadata." +msgstr "L'objet sélectionné n'a pas de métadonnées de traitement." + +msgid "Selected object does not have source object references." +msgstr "L'objet sélectionné n'a pas de références d'objet source." + +msgid "Source objects no longer exist." +msgstr "Les objets source n'existent plus." + +msgid "Selected a single source object" +msgstr "Un seul objet source sélectionné" + +#, python-format +msgid "Selected %d source objects" +msgstr "%d objets source sélectionnés" + +msgid "1 source object no longer exists" +msgstr "1 objet source n'existe plus." + +#, python-format +msgid "%d source objects no longer exist" +msgstr "%d objets source n'existent plus." + +msgid "No result currently available for this object." +msgstr "Aucun résultat disponible pour le moment." + +msgid "This feature leverages the results of previous analysis performed on the selected object(s).<br><br>To compute results, select one or more objects and choose a feature in the <u>Analysis</u> menu." +msgstr "Cette fonctionnalité exploite les résultats d'analyse précédents.<br><br>Pour calculer des résultats, sélectionnez un ou plusieurs objets et choisissez une fonctionnalité dans le menu <u>Analyse</u>." + +msgid "Indices" +msgstr "Indices" + +msgid "Plot kind" +msgstr "Type de graphique" + +msgid "One curve per object (or ROI) and per result title" +msgstr "Une courbe par objet (ou ROI) et par titre de résultat" + +msgid "One curve per result title" +msgstr "Une courbe par titre de résultat" + +msgid "X axis" +msgstr "Axe des X" + +msgid "Y axis" +msgstr "Axe des Y" + +#, python-format +msgid "Plot results obtained from previous analyses.<br><br>This plot is based on results associated with '%s' prefix." +msgstr "Tracer les résultats obtenus avec des analyses réalisées précédemment.<br><br>Ce graphique est basé sur les résultats associés au préfixe '%s'." + +msgid "All objects associated with results must have the same regions of interest (ROIs) to plot results together." +msgstr "Tous les objets associés aux résultats doivent avoir les mêmes ROIs pour tracer les résultats ensemble." + +msgid "Are you sure you want to delete all results of the selected object(s)?" +msgstr "Êtes-vous sûr de vouloir supprimer tous les résultats des objets sélectionnés ?" + +msgid "Add object title to plot" +msgstr "Ajouter le titre de l'objet au graphique" + +msgid "Add label with title" +msgstr "Ajouter une étiquette avec le titre" + +msgid "Annotation added" +msgstr "Annotation ajoutée" + +msgid "The label has been added as an annotation. You can edit or remove it using the annotation editing window.<br><br>Choosing to ignore this message will prevent it from being displayed again." +msgstr "L'étiquette a été ajoutée comme annotation. Vous pouvez la modifier ou la supprimer en utilisant la fenêtre d'édition des annotations.<br><br>Ignorer ce message empêchera son affichage ultérieur." + +#, python-format +msgid "“%s” has dependent operations but no valid source to reconnect to — downstream results are left unchanged." +msgstr "« %s » possède des opérations dépendantes mais aucune source valide à laquelle se reconnecter — les résultats en aval restent inchangés." + +msgid "Some operations could not be reconnected after deletion:" +msgstr "Certaines opérations n'ont pas pu être reconnectées après la suppression :" + +msgid "Commit edit mode changes?" +msgstr "Valider les modifications du mode d'édition ?" + +msgid "" +"You are about to exit Edit mode.\n" +"\n" +"All parameter changes made during this session will be permanently kept.\n" +"This action cannot be undone — Restore will no longer be available.\n" +"\n" +"Do you want to continue?" +msgstr "" +"Vous êtes sur le point de quitter le mode d'édition.\n" +"\n" +"Toutes les modifications de paramètres effectuées lors de cette session seront conservées de façon permanente.\n" +"Cette action est irréversible — la fonction Restaurer ne sera plus disponible.\n" +"\n" +"Souhaitez-vous continuer ?" + +msgid "Broken processing chain" +msgstr "Chaîne de traitement rompue" + +#, python-format +msgid "" +"One or more objects used by the selected processing chain were deleted: the chain is broken and the following entries can no longer be replayed:\n" +"%s\n" +"\n" +"Repair the history by removing the broken actions (and the actions depending on them), then continue with the remaining actions?" +msgstr "" +"Un ou plusieurs objets utilisés par la chaîne de traitement sélectionnée ont été supprimés : la chaîne est rompue et les entrées suivantes ne peuvent plus être rejouées :\n" +"%s\n" +"\n" +"Réparer l'historique en supprimant les actions rompues (ainsi que les actions qui en dépendent), puis continuer avec les actions restantes ?" + +msgid "Repair and continue" +msgstr "Réparer et continuer" + +msgid "Parameters" +msgstr "Paramètres" + +msgid "Replay file save" +msgstr "Rejouer l'enregistrement de fichier" + +#, python-format +msgid "" +"This action will overwrite the following file(s):\n" +"%s\n" +"\n" +"Replay it?" +msgstr "" +"Cette action écrasera le(s) fichier(s) suivant(s) :\n" +"%s\n" +"\n" +"La rejouer ?" + +#, python-format +msgid "Action %s was skipped: its recorded workspace state no longer matches the current workspace." +msgstr "L'action %s a été ignorée : l'état de l'espace de travail enregistré ne correspond plus à l'espace de travail actuel." + +#, python-format +msgid "Action %s would delete objects that this replay just recomputed and was skipped." +msgstr "L'action %s supprimerait des objets que ce rejeu vient de recalculer ; elle a été ignorée." + +#, python-format +msgid "Action %s targets objects produced by another session and was skipped." +msgstr "L'action %s cible des objets produits par une autre session ; elle a été ignorée." + +#, python-format +msgid "Action %s has no recorded pattern and cannot be replayed." +msgstr "L'action %s n'a pas de motif enregistré et ne peut pas être rejouée." + +#, python-format +msgid "Action %s was skipped: its recorded parameters could not be read from the history file." +msgstr "L'action %s a été ignorée : ses paramètres enregistrés n'ont pas pu être lus depuis le fichier d'historique." + +msgid "History panel" +msgstr "Panneau d'historique" + +msgid "History files" +msgstr "Fichiers d'historique" + +#, python-format +msgid "Action %s: target panel not found — skipping." +msgstr "Action %s : panneau cible introuvable — ignorée." + +#, python-format +msgid "Action %s: no recorded mutation target — skipping." +msgstr "Action %s : aucune cible de mutation enregistrée — ignorée." + +#, python-format +msgid "Action %s: target object(s) no longer exist — skipping." +msgstr "Action %s : le ou les objets cibles n'existent plus — ignorée." + +#, python-format +msgid "Action %s: %d target object(s) were deleted — applying to the rest." +msgstr "Action %s : %d objet(s) cible(s) ont été supprimés — appliquée aux autres." + +#, python-format +msgid "Action %s uses pattern %r which is not recomputable yet." +msgstr "L'action %s utilise le motif %r qui n'est pas encore recalculable." + +#, python-format +msgid "Action %s could not be fully recomputed." +msgstr "L'action %s n'a pas pu être entièrement recalculée." + +#, python-format +msgid "Recompute failed for action %s: %s" +msgstr "Échec du recalcul pour l'action %s : %s" + +#, python-format +msgid "" +"Action %(name)s skipped: plugin '%(loc)s' is missing.\n" +"Required parameter class: %(param)s\n" +"Reinstall the plugin to re-enable this action." +msgstr "" +"Action %(name)s ignorée : le plugin '%(loc)s' est manquant.\n" +"Classe de paramètre requise : %(param)s\n" +"Réinstallez le plugin pour réactiver cette action." + +#, python-format +msgid "Action %s: no recorded output object — skipping." +msgstr "Action %s : aucun objet de sortie enregistré — ignorée." + +#, python-format +msgid "Action %s: the initial object was deleted and cannot be re-created (no creation parameters)." +msgstr "Action %s : l'objet initial a été supprimé et ne peut pas être recréé (aucun paramètre de création)." + +#, python-format +msgid "Action %s: creation parameters could not be prepared — skipping." +msgstr "Action %s : les paramètres de création n'ont pas pu être préparés — ignorée." + +msgid "Second operand" +msgstr "Second opérande" + +#, python-format +msgid "Action %s: no recorded source object — skipping." +msgstr "Action %s : aucun objet source enregistré — ignorée." + +#, python-format +msgid "Action %s: no recorded second operand — skipping." +msgstr "Action %s : aucun second opérande enregistré — ignorée." -msgid "Do you want to continue with the next object?" -msgstr "Souhaitez-vous continuer avec l'objet suivant ?" +#, python-format +msgid "Action %s: source object(s) were deleted — skipping." +msgstr "Action %s : le ou les objets source ont été supprimés — ignorée." -msgid "Recomputing analyses" -msgstr "Recalcul des analyses" +#, python-format +msgid "Action %s: recompute returned %d output(s), expected %d." +msgstr "Action %s : le recalcul a renvoyé %d sortie(s), %d attendue(s)." -msgid "Selected object does not have processing metadata." -msgstr "L'objet sélectionné n'a pas de métadonnées de traitement." +#, python-format +msgid "Action %s: %d analysed object(s) were deleted — skipping." +msgstr "Action %s : %d objet(s) analysé(s) ont été supprimés — ignorée." -msgid "Selected object does not have source object references." -msgstr "L'objet sélectionné n'a pas de références d'objet source." +msgid "Cascade recompute" +msgstr "Recalcul en cascade" -msgid "Source object no longer exists." -msgstr "L'objet source n'existe plus." +msgid "Some downstream actions could not be recomputed:" +msgstr "Certaines actions en aval n'ont pas pu être recalculées :" -msgid "Source objects no longer exist." -msgstr "Les objets source n'existent plus." +msgid "Record mode" +msgstr "Mode d'enregistrement" -msgid "Selected a single source object" -msgstr "Un seul objet source sélectionné" +msgid "New session" +msgstr "Nouvelle session" -#, python-format -msgid "Selected %d source objects" -msgstr "%d objets source sélectionnés" +msgid "Start a new history session" +msgstr "Démarrer une nouvelle session d'historique" -msgid "1 source object no longer exists" -msgstr "1 objet source n'existe plus." +msgid "Open history file..." +msgstr "Ouvrir un fichier d'historique..." -#, python-format -msgid "%d source objects no longer exist" -msgstr "%d objets source n'existent plus." +msgid "Open history from a standalone .dlhist file" +msgstr "Ouvrir l'historique depuis un fichier .dlhist autonome" -msgid "No result currently available for this object." -msgstr "Aucun résultat disponible pour le moment." +msgid "Save history file..." +msgstr "Enregistrer un fichier d'historique..." -msgid "This feature leverages the results of previous analysis performed on the selected object(s).<br><br>To compute results, select one or more objects and choose a feature in the <u>Analysis</u> menu." -msgstr "Cette fonctionnalité exploite les résultats d'analyse précédents.<br><br>Pour calculer des résultats, sélectionnez un ou plusieurs objets et choisissez une fonctionnalité dans le menu <u>Analyse</u>." +msgid "Save history to a standalone .dlhist file" +msgstr "Enregistrer l'historique dans un fichier .dlhist autonome" -msgid "Indices" -msgstr "Indices" +msgid "Duplicate selected history action/session" +msgstr "Dupliquer l'action ou la session d'historique sélectionnée" -msgid "Plot kind" -msgstr "Type de graphique" +msgid "Previous step" +msgstr "Étape précédente" -msgid "One curve per object (or ROI) and per result title" -msgstr "Une courbe par objet (ou ROI) et par titre de résultat" +msgid "Select the previous action in the current session" +msgstr "Sélectionner l'action précédente dans la session courante" -msgid "One curve per result title" -msgstr "Une courbe par titre de résultat" +msgid "Next step" +msgstr "Étape suivante" -msgid "X axis" -msgstr "Axe des X" +msgid "Select the next action in the current session" +msgstr "Sélectionner l'action suivante dans la session courante" -msgid "Y axis" -msgstr "Axe des Y" +msgid "Remove actions incompatible with the current workspace" +msgstr "Supprimer les actions incompatibles avec l'espace de travail courant" -#, python-format -msgid "Plot results obtained from previous analyses.<br><br>This plot is based on results associated with '%s' prefix." -msgstr "Tracer les résultats obtenus avec des analyses réalisées précédemment.<br><br>Ce graphique est basé sur les résultats associés au préfixe '%s'." +msgid "Replay" +msgstr "Rejouer" -msgid "All objects associated with results must have the same regions of interest (ROIs) to plot results together." -msgstr "Tous les objets associés aux résultats doivent avoir les mêmes ROIs pour tracer les résultats ensemble." +msgid "Replay the selection silently (no parameter dialogs)" +msgstr "Rejouer la sélection silencieusement (sans boîtes de dialogue de paramètres)" -msgid "Are you sure you want to delete all results of the selected object(s)?" -msgstr "Êtes-vous sûr de vouloir supprimer tous les résultats des objets sélectionnés ?" +msgid "Step-by-step" +msgstr "Pas à pas" -msgid "Annotation added" -msgstr "Annotation ajoutée" +msgid "Replay the selection step by step, editing parameters at each step" +msgstr "Rejouer la sélection pas à pas, en modifiant les paramètres à chaque étape" -msgid "The label has been added as an annotation. You can edit or remove it using the annotation editing window.<br><br>Choosing to ignore this message will prevent it from being displayed again." -msgstr "L'étiquette a été ajoutée comme annotation. Vous pouvez la modifier ou la supprimer en utilisant la fenêtre d'édition des annotations.<br><br>Ignorer ce message empêchera son affichage ultérieur." +msgid "New image" +msgstr "Nouvelle image" msgid "Recent macros" msgstr "Macros récentes" @@ -1720,6 +2078,9 @@ msgstr "Lorsqu'elle est fermée, une macro est <u>détruite de manière définit msgid "Do you want to continue?" msgstr "Souhaitez-vous vraiment continuer ?" +msgid "New signal" +msgstr "Nouveau signal" + msgid "Creating geometric shapes" msgstr "Création des formes géométriques" @@ -1870,29 +2231,9 @@ msgstr "" msgid "Yes to All" msgstr "Oui à tout" -msgid "Processing metadata is incomplete." -msgstr "Les métadonnées de traitement sont incomplètes." - msgid "Processing metadata is incomplete (missing source UUID)." msgstr "Les métadonnées de traitement sont incomplètes (UUID source manquant)." -msgid "The object that was used to create this processed object has been deleted and cannot be used for reprocessing." -msgstr "L'objet qui a été utilisé pour créer cet objet traité a été supprimé et ne peut pas être utilisé pour le retraitement." - -#, python-format -msgid "" -"Failed to reprocess object:\n" -"%s" -msgstr "" -"Échec du retraitement de l'objet :\n" -"%s" - -msgid "Processing was cancelled." -msgstr "Le traitement a été annulé." - -msgid "Failed to reprocess object." -msgstr "Échec du retraitement de l'objet." - msgid "Signal was reprocessed." msgstr "Le signal a été retraité." @@ -1918,9 +2259,6 @@ msgstr "En mode 'pairwise', vous devez sélectionner des objets dans au moins de msgid "In pairwise mode, you need to select the same number of objects in each group." msgstr "En mode 'pairwise', vous devez sélectionner le même nombre d'objets dans chaque groupe." -msgid "Parameters" -msgstr "Paramètres" - #, python-format msgid "Calculating: %s" msgstr "Calcul : %s" @@ -1936,9 +2274,6 @@ msgstr "<u>Note :</u> le mode d'opération est <i>pairwise</i> : %s objet(s) att msgid "<u>Note:</u> operation mode is <i>single operand</i>: 1 object expected" msgstr "<u>Note :</u> le mode d'opération est <i>single</i> : 1 objet attendu" -msgid "Second operand" -msgstr "Second opérande" - msgid "Regions of Interest" msgstr "Régions d'intérêt" @@ -1952,6 +2287,10 @@ msgstr "Supprimer la ROI" msgid "Are you sure you want to remove ROI '%s'?" msgstr "Êtes-vous sûr de vouloir supprimer la ROI '%s' ?" +#, python-format +msgid "Remove ROI '%s'" +msgstr "Supprimer la ROI '%s'" + msgid "Sum" msgstr "Addition" @@ -2875,6 +3214,42 @@ msgstr "Interpoler systématiquement" msgid "Behavior when X-axis arrays are incompatible in multi-signal computations:<ul><li><b>Ask</b>: display confirmation dialog (default)</li><li><b>Interpolate</b>: automatically interpolate signals</li></ul>" msgstr "Comportement lorsque les tableaux des X sont incompatibles dans les calculs multi-signaux :<ul><li><b>Demander</b> : afficher une boîte de dialogue de confirmation (par défaut)</li><li><b>Interpoler</b> : interpoler automatiquement les signaux</li></ul>" +msgid "History sessions" +msgstr "Sessions d'historique" + +msgid "New object or file" +msgstr "Nouvel objet ou fichier" + +msgid "Ask" +msgstr "Demander" + +msgid "Always start a new session" +msgstr "Toujours démarrer une nouvelle session" + +msgid "Continue in the current session" +msgstr "Continuer dans la session courante" + +msgid "Behavior when a new object or file is added to a populated history session." +msgstr "Comportement lorsqu'un nouvel objet ou fichier est ajouté à une session d'historique non vide." + +msgid "Plugin-created object" +msgstr "Objet créé par un plugin" + +msgid "Behavior when a plugin adds an object to a populated history session." +msgstr "Comportement lorsqu'un plugin ajoute un objet à une session d'historique non vide." + +msgid "Plugin multi-load" +msgstr "Chargement multiple par un plugin" + +msgid "Ask once" +msgstr "Demander une seule fois" + +msgid "Start a new session" +msgstr "Démarrer une nouvelle session" + +msgid "Behavior when a plugin loads multiple objects into a populated history session." +msgstr "Comportement lorsqu'un plugin charge plusieurs objets dans une session d'historique non vide." + msgid "Settings for results management" msgstr "Réglages de la gestion des résultats" @@ -2893,18 +3268,6 @@ msgstr "Afficher automatiquement la boîte de dialogue des résultats après le msgid "If enabled, the results dialog will be shown automatically after each processing operation producing results.<br>If disabled, the results dialog will not be shown automatically." msgstr "Si activé, la boîte de dialogue des résultats sera affichée automatiquement après chaque opération de traitement produisant des résultats.<br>Si désactivé, la boîte de dialogue des résultats ne sera pas affichée automatiquement." -msgid "Result titles" -msgstr "Titres des résultats" - -msgid "Source object short identifier" -msgstr "Identifiant court de l'objet source" - -msgid "Source object title" -msgstr "Titre de l'objet source" - -msgid "How source objects are referenced in result titles after a computation (display only):<ul><li><b>Short identifier</b>: e.g. <i>fft(s001)</i> (default)</li><li><b>Title</b>: e.g. <i>fft(My signal)</i></li></ul>Result titles update automatically when a source object is renamed." -msgstr "Manière dont les objets source sont référencés dans les titres des résultats après un calcul (affichage uniquement) :<ul><li><b>Identifiant court</b> : par ex. <i>fft(s001)</i> (par défaut)</li><li><b>Titre</b> : par ex. <i>fft(Mon signal)</i></li></ul>Les titres des résultats sont mis à jour automatiquement lorsqu'un objet source est renommé." - msgid "Default image visualization settings" msgstr "Réglages d'affichage d'images par défaut" @@ -3243,6 +3606,27 @@ msgstr "C'est la fin de la visite guidée !" msgid "You can show the tour again, or close this dialog box." msgstr "Vous pouvez afficher la visite guidée à nouveau, ou fermer cette boîte de dialogue." +msgid "Save history file" +msgstr "Enregistrer un fichier d'historique" + +msgid "Open history file" +msgstr "Ouvrir un fichier d'historique" + +msgid "Imported" +msgstr "Importé" + +#, python-format +msgid "Failed to deserialize history DataSet kwarg %r." +msgstr "Échec de la désérialisation de l'argument DataSet de l'historique %r." + +#, python-format +msgid "Failed to deserialize history ROI kwarg %r." +msgstr "Échec de la désérialisation de l'argument ROI de l'historique %r." + +#, python-format +msgid "Failed to deserialize history DataSet-list kwarg %r." +msgstr "Échec de la désérialisation de l'argument DataSet-list de l'historique %r." + msgid "Registered plugins:" msgstr "Plugins enregistrés :" @@ -3384,12 +3768,12 @@ msgstr "Cliquer sur OK pour démarrer la démo.<br><br><u>Note :</u><br>- La dé msgid "Click OK to end demo." msgstr "Cliquer sur OK pour terminer la démo." -msgid "Context" -msgstr "Contexte" - msgid "Error:" msgstr "Erreur:" +msgid "Context" +msgstr "Contexte" + #, python-format msgid "The file %s could not be read:" msgstr "Le fichier %s n'a pas pu être ouvert :" @@ -3606,18 +3990,18 @@ msgstr "Déplier la sélection" msgid "HDF5 Browser" msgstr "Explorateur HDF5" -msgid "Value" -msgstr "Valeur" - -msgid "Name" -msgstr "Nom" - msgid "Size" msgstr "Taille" msgid "Type" msgstr "Type" +msgid "Value" +msgstr "Valeur" + +msgid "Name" +msgstr "Nom" + msgid "Unsupported data" msgstr "Données non prises en charge" @@ -3654,6 +4038,30 @@ msgstr "Afficher uniquement les données prises en charge" msgid "Show values" msgstr "Afficher les valeurs" +msgid "Show details" +msgstr "Afficher les détails" + +msgid "Hide details" +msgstr "Masquer les détails" + +msgid "Date and time" +msgstr "Date et heure" + +msgid "Title" +msgstr "Titre" + +msgid "Action is compatible with the current workspace state." +msgstr "L'action est compatible avec l'état actuel de l'espace de travail." + +msgid "Action is not compatible with the current workspace state." +msgstr "L'action n'est pas compatible avec l'état actuel de l'espace de travail." + +msgid "This step is outdated: replay it to refresh its result." +msgstr "Cette étape est obsolète : rejouez-la pour actualiser son résultat." + +msgid "Active recording session." +msgstr "Session d'enregistrement active." + msgid "Image background selection" msgstr "Sélection de l'arrière-plan de l'image" @@ -3938,9 +4346,6 @@ msgstr "Tout sélectionner" msgid "Adding data to the plot" msgstr "Ajout des données au graphique" -msgid "Title" -msgstr "Titre" - msgid "X label" msgstr "Titre X" @@ -4031,6 +4436,18 @@ msgstr "Merci de sélectionner le fichier à importer." msgid "Example Wizard" msgstr "Assistant exemple" +msgid "Signal" +msgstr "Signal" + +msgid "Shape" +msgstr "Forme" + +msgid "Image" +msgstr "Image" + +msgid "Dimensions" +msgstr "Dimensions" + msgid "Minimum value" msgstr "Valeur minimum"