Commit Graph

4788 Commits

Author SHA1 Message Date
Martín Lucas Golini
51b88fa125 fix(ui): harden asynchronous document search
Snapshot document search state before dispatching highlight workers and
retain the searched document for the duration of each job.

Publish results through MainThreadLifetime and reject results when the
editor has changed document or search parameters. Remove the obsolete
worker counter and destructor wait used for editor lifetime management.

Use atomic cancellation flags in TextDocument::findAll() and protect
active-search map inspection during destruction.

Add regression coverage for concurrent cancellation, stale highlight
results, rapid backtick searches after a large multiline paste, and
editor destruction during active search.

Refs SpartanJ/ecode#956.
2026-09-21 01:55:58 -03:00
Martín Lucas Golini
311d3e701a Fix tests in Windows build. 2026-09-20 16:34:29 -03:00
Martín Lucas Golini
2beab631a2 Implemented the live-indexing fix + Fixed opening and closing the context menu no longer changes the scrollback position.
- Centralized .gitignore, .prjallowed, and .prjdisallowed filtering in src/tools/ecode/projectdirectorytree.cpp:392.
  - Live directories now require an already-admitted parent and use (parentDirectory, filename) matching before insertion.
  - Live file additions use the same shared filtering.
  - Newly admitted directories still load their own nested .gitignore before recursive scanning.
  - Added eight direct regression tests in src/tests/unit_tests/projectdirectorytree_tests.cpp:84.
  - Added the required ecode sources to both Premake unit-test targets.
  - No FileSystemListener changes; directory moves remain outside this Add-focused patch.
  - Context menu issue cause was terminal focus reporting: Codex enables focus events, and opening the popup sent ESC [ O through the ordinary input path, which scrolls to the bottom. Focus reports now use the non-scrolling protocol-write path while still reaching the application correctly.
2026-09-20 14:41:47 -03:00
Martín Lucas Golini
66962c6a82 Merge branch 'develop' of github.com:SpartanJ/eepp into develop 2026-09-20 13:11:55 -03:00
Martín Lucas Golini
cae1af6098 Do not depend on pcap at build time for eproc. 2026-09-20 13:11:45 -03:00
Martín Lucas Golini
7568ec5f22 Fix missing include. 2026-09-20 12:16:01 -03:00
Martín Lucas Golini
e4af29af4b Merge branch 'develop' of github.com:SpartanJ/eepp into develop 2026-09-20 02:37:02 -03:00
Martín Lucas Golini
1ae2b7180b Add initial eproc system monitor
- Add the eproc process-monitoring application and persistent window/table state
  - Implement Linux process, network, GPU, icon, and GUI-window collection
  - Add optional process columns, styling, i18n-ready strings, and command copying
  - Retain exited processes for one update and color them as ended
  - Extend table sizing and header behavior for persisted column layouts
  - Organize Linux-specific sources under platform/linux
  - Keep unsupported platforms buildable with a startup WIP warning
2026-09-20 02:36:54 -03:00
Martín Lucas Golini
d885c6b31a Update svector and unordered_dense to its latest releases. 2026-09-19 21:52:07 -03:00
Martín Lucas Golini
cdde2ec49e Fix file associations in macOS. 2026-09-18 20:47:22 -03:00
Martín Lucas Golini
b838a42fee Fix lTrim/rTrim asymmetry with trim. Fix readBySeparator on an empty buffer.
Reuse RegEx match data and bound the pattern cache.

lTrim and rTrim returned an all-separator string unchanged where trim() returns empty;
all sixteen overloads now drop everything when no non-separator is left.
readBySeparator handed the callback one empty chunk for an empty buffer; it hands none
now, as the UTF-32 overloads already did.

RegEx::matches allocated its match data per call, four allocations per row while
filtering over a table. It is created once per object now, held by a unique_ptr whose
deleter knows the engine, so the destructor no longer repeats that split. RegEx is
movable but not copyable: it was implicitly copyable while owning that block, and a
copy taken after a match released it twice. syntaxtokenizer.cpp was copying its
std::variant temporary because the user-declared destructor suppressed the implicit
move; it moves now.

RegExCache held two unordered_maps, hash to pattern and hash to options, and never
evicted. It is one DynamicLRU<8192, size_t, shared_ptr<void>> now: the engine lives in
each pattern's deleter so the options map is gone, and values own the pattern, because
an eviction must not free one a live RegEx is still matching with. That also fixes a
racing insert that leaked the loser's pattern. The bound leaves ample room over the
working set and cache hits stay allocation-free (0 new, 0 malloc per 1000
constructions). New tests: lTrimAndRTrim, readBySeparator, splitCb, cacheIsBounded.
Release and AddressSanitizer suites pass 1216 tests each.
2026-09-18 17:12:13 -03:00
Martín Lucas Golini
c100d93896 Fix String::trim on all-separator input. Fix RegEx freeing Oniguruma patterns.
String::trim: when the input consisted only of separators, both find_first_not_of
and find_last_not_of returned npos and the pos2 fallback computed length() - 1, so
trim("  ") returned " " and every all-separator value came back one character
shorter instead of empty, making an all-whitespace value look non-empty to callers.
All eight overloads were affected: std::string, std::string_view, String and
String::View, in their char and separator-set forms. Return an empty result when
there is no non-separator, and compute the trimmed range as
substr(pos1, pos2 - pos1 + 1).

RegEx: mCompiledPattern stores whichever engine compiled the pattern, a pcre2_code*
or an OnigRegex, but the destructor released it with pcre2_code_free() whenever
RegExCache did not own it. With useCache = false that freed an Oniguruma pattern as
a PCRE2 block, which corrupts the heap: constructing and destroying such a RegEx
crashes with SIGSEGV, a path snippetparser.cpp reaches by passing Utf |
AllowFallback with useCache = false. Release the pattern with the deallocator of the
engine recorded in Options::UseOniguruma, the predicate matches(), getCaptureCount()
and RegExCache::clear() already use, and remove the mOnigEngine flag, which was
never set or read anywhere.

Both fixes come with regression tests. String.trim covers the all-separator boundary
and the trimmed range of every overload. RegExEngines.uncachedPatternIsFreedByItsOwnEngine
destroys uncached patterns from both engines; it crashed the test binary before the fix.
2026-09-18 15:51:39 -03:00
Martín Lucas Golini
128abc692e Fix UIDropDown listbox mis-positioning.
Fix sort indicator in UIAbstractTableView not displaying when sorted.
2026-09-18 13:59:11 -03:00
Martín Lucas Golini
f18ba006fb Fix application cursor keys in terminal sessions
Read application cursor, keypad, and NumLock state from the worker display
when encoding mapped keys. These are display modes rather than terminal text
modes, so checking mTerm.mode caused full-screen applications such as htop
and nvtop to receive normal cursor sequences instead of application-mode
sequences.

Add regression coverage for application-mode Up and Down keys.
2026-09-18 00:26:56 -03:00
Martín Lucas Golini
2edf4cfd43 Fix terminal scroll anFix terminal scroll and selection synchronization
eterm:
    - derive scroll and history notifications from adopted snapshots instead
      of delayed worker events
    - prevent PTY parsing from publishing its temporary live-buffer viewport
    - restore scrollback correctly when new output wraps the history ring
    - keep selections attached to their text during output and absolute scrolling
    - preserve terminal focus and selection while interacting with the scrollbar
    - keep the scrollbar available while a selection is active
    - suppress application mouse reports when Shift overrides mouse capture
    - preserve scrollback when Kitty reports standalone modifier keys
    - retain scroll-to-bottom behavior for regular and modified input keys
    - remove obsolete worker scroll and history event tracking
    - add regression coverage for viewport, selection, focus, keyboard, and
      history behaviord selection synchronization
2026-09-17 20:33:24 -03:00
Martín Lucas Golini
0898e20f2a Fix MSVC build. 2026-09-17 13:23:17 -03:00
Martín Lucas Golini
c530e4bd6e feat: add cross-platform file association management
Add an EE::System::FileAssociation abstraction with XDG, Windows,
and macOS implementations.

Expose extensions from syntax predefinitions and add custom widget
support to UISettingsPanel. Add an ecode settings page for selecting
file associations and installing an XDG desktop entry.

Apply changes asynchronously with lifecycle-safe UI handling, disable
controls while applying, and avoid redundant XDG database updates.

Add translations and coverage for the new functionality.

Implements SpartanJ/ecode#192
2026-09-17 11:04:25 -03:00
Martín Lucas Golini
9956f38c2a Refine terminal search highlighting and placement
eterm:
  - render the active match with palette yellow and black text
  - use translucent palette yellow for inactive matches
  - share search color handling across all terminal rendering paths
  - collect the complete visible range of wrapped active matches
  - move the find bar below matches in either of the first two rows
  - remove unreliable horizontal overlap checks from find bar placement
2026-09-16 11:12:00 -03:00
Martín Lucas Golini
25a492094e Improve terminal find bar positioning and transitions
eterm:
  - expose the visible active terminal search range
  - move the find bar below first-row matches it would otherwise occlude
  - restore the top-right position when no overlap exists
  - recalculate find bar placement when the terminal is resized
  - clip animated find bar content to the terminal bounds
  - serialize and tag visibility transitions to prevent conflicting actions
2026-09-16 02:42:42 -03:00
Martín Lucas Golini
f829f18920 ecode: separate plugin detachment from destruction
Add an explicit Plugin::shutdown() phase that removes all application-facing
state while the complete plugin type is still alive. Detach editor and
document commands, listeners, clients, UI objects, and queued callbacks on
the main thread before scheduling resource-only destruction on a worker.

Move plugin-specific cleanup into unregisterEditors() and the PluginBase
unregister hooks. Keep potentially blocking cleanup, such as stopping LSP
servers or joining workers, in destructors so normal plugin unload does not
stall the UI.

Stop plugin reloads, broadcasts, late ready callbacks, and unlocked command
dispatch once application closing begins. During final shutdown, unload
plugins synchronously and wait for any previously queued destruction.

Document the Plugin and PluginBase lifecycle, cleanup checklist, and a
complete implementation example.

Previously, plugin destructors could mutate editor and UI state from a worker
thread, while destructor-time virtual dispatch skipped derived unregister
logic. This could leave commands capturing a destroyed plugin instance or
race registrations from a newly loaded generation. A queued key event during
application close could then execute one of these stale callbacks and jump to
invalid memory.
2026-09-16 01:53:22 -03:00
Martín Lucas Golini
4e3c2d966f ecode: allow deleting untracked files from Git status
- Add a Delete action for untracked files and the Untracked section, with
  confirmation before permanently removing the selected paths.

  - Decode Git-quoted status paths using new byte-oriented std::string
  String::escape() and String::unescape() overloads, preventing quoted or
  octal-escaped filenames from breaking deletion.

  - Add translations and regression tests for string escaping and quoted
  untracked paths.
2026-09-15 13:19:24 -03:00
Martín Lucas Golini
50a0594038 Repect click step in UITerminal mouse wheel scroll. 2026-09-14 20:05:30 -03:00
Martín Lucas Golini
be685c3fda Fixed the CI-dependent assertion.
The test now compares the plugin position against EventDispatcher::getMousePos(), which is the actual scene-space value passed by UICodeEditor. Native pixel coordinates can differ by one after DPI/view mapping.
2026-09-14 18:45:18 -03:00
Martín Lucas Golini
71360cb896 Simplify mouse-over ancestry tracking
- Derive isMouseOverMeOrChildren() from the event dispatcher's committed
  mouse-over node instead of maintaining a transient flag on every node.

  - Remove the mouse-over tracking set, per-frame flag clearing, and hover
  bookkeeping side effects from hit testing. This makes hover ancestry
  available between scene updates while reducing SceneNode size and
  eliminating hash-set operations during overFind().

  - Add coverage for persistent ancestry, sibling transitions, hover state
  synchronization, and side-effect-free hit testing.
2026-09-14 18:29:51 -03:00
Martín Lucas Golini
51afa1870a Fix mouse wheel bubbling and plugin event handling
- Queue native wheel events until hover state has been rebuilt, restoring
  scroll propagation from children that cannot scroll to their scrollable
  ancestors.

  - Add MouseWheelEvent and UICodeEditorPlugin::onMouseWheel() so plugins can
  consume precise wheel input before the editor handles it. Migrate
  autocomplete and AI Assistant wheel handlers to the new API while
  preserving the existing virtual event dispatch semantics.

  - Add regressions for wheel bubbling, plugin interception, generic wheel
  listeners, and override-based callback suppression.
2026-09-14 17:58:06 -03:00
Martín Lucas Golini
6bccec171e ecode: improve read-only file handling
- add -r/--read-only to lock files opened from the command line
  - preserve read-only mode when forwarding files over IPC
  - apply locking only to the input files
  - fix the Read Only checkbox by routing it through lock-toggle
  - correctly process each path when opening multiple input files

Implements SpartanJ/ecode#954
2026-09-14 13:46:53 -03:00
Martín Lucas Golini
d41025b91b Fix multi-window input routing regressions
Add a backend-neutral Input::pushEvent() API with SDL2 and SDL3
implementations, allowing native input translation and routing to be
covered without requiring physical input or backend-specific test code.

Add regression coverage ensuring a native mouse-wheel event is emitted
exactly once and delivered only to its target application window.

Resolve event coordinates and resize dimensions using the target
window's scale instead of the window polling SDL's global event queue.
This preserves correct input and sizing across windows on displays with
different DPI scales.

Also restore SDL3 compatibility with versions older than 3.2.12 when
deriving integer wheel directions from floating-point offsets.
2026-09-14 00:12:46 -03:00
Martín Lucas Golini
56e13bbbe8 And also fix it for SDL3. 2026-09-13 22:33:43 -03:00
Martín Lucas Golini
ca3432fb5a Fix accidental duplicated mouse wheel events! 2026-09-13 22:29:41 -03:00
Martín Lucas Golini
071bc5d697 Add optional smooth scrolling across UI scrollable widgets
Introduce UIScrollController to provide frame-rate-independent wheel
interpolation, touch dragging, and momentum for code editors, terminals,
scroll views, and scrollable widgets while preserving the legacy instant
scrolling path.

Add a UISceneNode-level smooth-scrolling policy. Embedded scenes inherit
the root scene setting, new widgets snapshot it during construction, and
setSmoothScrollEnabled() can optionally apply changes to existing widgets
across the complete embedded-scene hierarchy.

Move native macOS scrolling and title-bar helpers into PlatformHelper,
enable native momentum from UIApplication, and explicitly enable it in
ecode. Preserve precise SDL2 and SDL3 wheel deltas for fractional momentum
events without changing normal integer wheel steps.

Replace the separate editor and terminal preferences in ecode and eterm
with one global smooth-scrolling setting, including legacy configuration
migration, live updates, and localized settings text.

Improve UITouchDraggableWidget momentum handling and add regression tests
for scrolling interpolation, pixel-aligned editor positions, scene
inheritance, widget overrides, and immediate policy application.
2026-09-13 20:27:37 -03:00
Martín Lucas Golini
42de99cf3b Fix GL resource sharing across native application windows
Decouple GL object sharing between native windows from auxiliary worker-thread context support. Platforms without threaded GL contexts, such as Haiku, must still share textures and other GL resources between their window contexts.

Always configure SDL_GL_SHARE_WITH_CURRENT_CONTEXT according to the requested context settings, while continuing to create the auxiliary thread context only on supported platforms. Explicitly reset the SDL attribute for non-shared contexts to avoid leaking state into subsequent window creation.

Apply the fix to both SDL2 and SDL3 backends. Also link the Haiku unit test executable against libbsd and libnetwork to resolve its PTY and socket dependencies.
2026-09-12 01:51:17 -03:00
Martín Lucas Golini
5d3be27a9d fix: release compression state and skip offscreen maximize
Finalize zlib streams on every success and failure path after initialization,
preventing terminal frame compression from leaking encoder allocations.

Skip SDL window maximization in headless and terminal runtimes, where it is
meaningless and can leave worker-thread SDL error/TLS allocations alive.

Also correct the dormant Brotli streaming encoder loop so it validates
parameters, handles empty input and read failures, drains pending output,
finishes the stream completely, and destroys its state on every exit path.
2026-09-12 01:11:35 -03:00
Martín Lucas Golini
e88d068acc window: use native SDL drivers for terminal runtime
Use Cocoa, Windows, and Haiku native drivers for terminal-mode OpenGL context
hosts instead of the unsupported offscreen driver. Keep hosts hidden and work
around Haiku SDL2 showing hidden windows during creation.
2026-09-12 00:51:33 -03:00
Martín Lucas Golini
86277832fc Fix SystemPath.workingDirectoryRoundTripsUnicode in macOS test. 2026-09-11 00:37:03 -03:00
Martín Lucas Golini
60ac3a0ffa Fixed the Unicode-path crash and misleading AI Assistant teardown fault (SpartanJ/ecode#953).
- Windows executable paths now always use GetModuleFileNameW(), with dynamic long-path support.
  - Sys::getProcessPath() derives directly from the UTF-8 executable path.
  - Windows working-directory APIs now use wide-character functions under both MinGW and MSVC.
  - AI Assistant teardown checks that the editor splitter exists during partial initialization.
  - Added process-path and Unicode working-directory regression tests using EXPECT_STDSTREQ.
2026-09-11 00:03:03 -03:00
Martín Lucas Golini
3effffd16f Add shared controls for multi-file diff views
- Introduce UIMultiDiffView as a first-class container for multi-file diffs, with a compact toolbar for expanding or collapsing all files, switching between unified and split views, and displaying aggregate file and line-change statistics.
	- Calculate addition and removal totals during diff preparation so asynchronously prepared diffs do not need to rescan their contents on the UI thread. Cache the child diff views and expose the multi-diff state through the new component.
	- Use UIMultiDiffView for regular diff tabs and Git commit details, removing the duplicated commit-specific toolbar, styling logic, tokenizer state, and view-mode handling. Preserve the original Git commit toolbar appearance, spacing, icons, tooltips, and colored changed-files summary.
	- Keep the existing UIDiffView multi-file factory available for compatibility and add regression coverage for aggregate statistics, toolbar visibility, unified/split propagation, collapse state, prepared diffs, and large patches.
	- Add localized changed-files summaries to all ecode translation catalogs.
	- Fix the secondary-window UI test to use the appropriate std::string assertion helper.
2026-09-10 23:15:46 -03:00
Martín Lucas Golini
095fe7919e feat(ui): add native multi-window application support
- let UIApplication create, manage, render, and destroy multiple native windows
  - add scoped scene and GL window-context switching
  - route input events to the scene belonging to each native window
  - share application fonts, themes, icons, styles, and graphics resources safely
  - add NewInApplicationWindow factories for UIWindow, UIFileDialog, and UIMessageBox
  - support native parent relationships, modality, minimum sizes, and optional positioning
  - close child windows when the primary application window closes
  - defer native context destruction until the end of the application tick
  - fall back to in-scene windows for Emscripten and terminal rendering
  - reapply renderer state caches when switching OpenGL contexts
  - fix SDL2/SDL3 display bounds and multi-window lifecycle handling
  - add a native file-dialog and message-box multi-window example
  - add integration coverage for context switching, input, resources, modality, and closing
2026-09-10 19:27:29 -03:00
Martín Lucas Golini
3493e849a2 Remove tabulate because it's getting annoying. 2026-09-10 13:43:18 -03:00
Martín Lucas Golini
01bc68957e Fix Windows build. 2026-09-10 13:04:13 -03:00
Martín Lucas Golini
6ccb433dd5 perf: optimize and benchmark terminal frame damage detection
Extract frame damage detection into a private reusable implementation and add
release benchmarks for representative GUI damage patterns at 720p, 1080p,
and 4K.

Use tile-major traversal for smaller framebuffers and cache-friendly row-major
traversal above 16 MiB, with reusable scratch storage and no whole-frame
equality precheck. Determine full-frame updates from the completed damage
bounds instead of prematurely falling back based on dirty-tile area.

Present benchmark results as a table showing each strategy, the selected
production path, its gap to the fastest candidate, and resulting transfer
size.
2026-09-10 12:03:15 -03:00
Martín Lucas Golini
fcc3a412fb fix: restrict persistent Kitty updates to eterm by default
Enable persistent root-image and damage updates automatically only when
TERM=eterm, since Kitty a=f root-image edits are not consistently supported
by other terminal emulators.

Use reliable anonymous full-frame transfers elsewhere while preserving the
environment variables as explicit overrides. Document the compatibility
rationale and the dependency of damage updates on persistent images.
2026-09-10 01:42:51 -03:00
Martín Lucas Golini
95d52cdbb3 eepp:
- add reusable-buffer String::toUtf8() conversion
  - extract shared find-bar CSS into UIFindBarStyle
  - reuse the shared style from UIDocFindReplace

  ecode:
  - enable terminal find, next, and previous shortcuts
  - install terminal bindings after conflicting editor bindings are removed

  eterm:
  - add searchable terminal history with plain text, RegEx, and LuaPattern modes
  - support case-sensitive and whole-word matching across wrapped rows
  - debounce searches and avoid unnecessary string allocations
  - add an animated find bar with status and wrapped result navigation
  - expose find commands through configurable keybindings and the context menu
  - render and navigate search matches in terminal history
  - forward right-button releases when applications capture the mouse
  - fix UITabWidgetSplitter ownership during shutdown

  tests:
  - cover UTF-8 buffer reuse and terminal search behavior
  - verify wrapped lines, Unicode, pattern modes, invalid expressions, and navigation
  - verify SGR right-button release encoding

  tooling:
  - clarify the mandatory optimized build workflow for performance work
  - require direct release test execution before falling back to Xvfb
2026-09-10 00:57:56 -03:00
Martín Lucas Golini
a294d78733 eterm: extract settings actions and fix macOS efsw linkage
Build:
  - Link eterm with CoreFoundation and CoreServices on macOS
  - Satisfy the framework dependencies required by efsw's FSEvents backend

  Applications:
  - Move eterm settings operations into a dedicated SettingsActions class
  - Centralize settings window lifecycle and font configuration actions
  - Route settings panel font-size updates through SettingsActions
2026-09-09 17:06:38 -03:00
Martín Lucas Golini
fe91253276 eterm:
- persist keybindings in keybindings.cfg with configurable primary and secondary modifiers
  - hot-reload bindings and merge newly introduced defaults
  - open keybindings.cfg in a terminal-font-sized code editor tab
  - indicate unsaved keybinding changes using the modified-tab marker
  - share tab and split commands between terminals and the keybindings editor
  - add bindings for terminal actions, tab navigation, numbered tabs, splits, renaming, and tab movement
  - expose keybindings through terminal and tab context menus
  - add tab split and move-left/right context menu actions
2026-09-09 14:32:43 -03:00
Martín Lucas Golini
410c9ba09f eterm: fix configuration and window state persistence
- load preferences and window state from their configuration files
  - persist CLI overrides after applying them
  - capture window state before closing the native window
  - restore window position and defer maximization until initialization completes
  - avoid applying pixel density twice when restoring window dimensions
  - display active keybindings in terminal and tab context menus
  - add the New Terminal context-menu action
2026-09-09 11:35:35 -03:00
Martín Lucas Golini
71ede34599 eepp: add reusable UISettingsPanel
- add the generic settings model and panel to EE::UI::Tools
  - support category navigation, filtering, and lazy materialization
  - add UISettingsPanel model and filtering tests

ecode: migrate settings to UISettingsPanel
  - replace the application-specific settings model
  - use the generic settings panel implementation
  - add monitor refresh rate as a frame limit option
  - normalize UI labels and translations

eterm: add persistent configuration and settings panel
  - persist application preferences and window state
  - use saved values as defaults for command-line options
  - persist command-line overrides
  - add graphical settings with live application
  - expose renderer, terminal behavior, appearance, font, and scale options
2026-09-09 00:56:03 -03:00
Martín Lucas Golini
64512ab44d eterm: expand tab controls and fix maximized tab lifecycle
- add ellipsized tabs and ecode-style context actions to eterm
  - support session rename, exclusive mode, tab movement, and maximize/restore
  - restore maximized tab widgets before close or split operations
  - track detached tab state directly to prevent stale references in ecode
  - keep dirty rows valid during asynchronous terminal resize
  - expose eterm's widget inspector and disable default UI effects
  - localize the new exclusive-mode action
2026-09-08 01:57:35 -03:00
Martín Lucas Golini
a24eb12182 Add SDL3 non-text clipboard data support
Expose MIME-based clipboard data operations through the Clipboard interface, with unsupported defaults for SDL2.
Implement lazy data providers, cleanup callbacks, MIME type enumeration, data retrieval, availability checks, and clipboard clearing for SDL3.
2026-09-07 00:31:27 -03:00
Martín Lucas Golini
827f5d7524 ecode: fix stale and symbolic remote branch entries
Exclude symbolic remote refs such as origin/HEAD from the branch list.
Remove the corresponding local remote-tracking ref after deleting a
remote branch, and prune stale refs when pulling.
2026-09-06 21:39:11 -03:00
Martín Lucas Golini
90499462ea Fix Reset zoom in new eeiv port. 2026-09-06 21:18:06 -03:00