arrayview 0.29.0__tar.gz → 0.29.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {arrayview-0.29.0 → arrayview-0.29.2}/.mex/context/lifecycle.md +1 -1
- {arrayview-0.29.0 → arrayview-0.29.2}/PKG-INFO +1 -1
- arrayview-0.29.2/docs/vscode-window-routing-plan.md +37 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/pyproject.toml +1 -1
- {arrayview-0.29.0 → arrayview-0.29.2}/scripts/release.sh +25 -16
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_launcher.py +6 -4
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_viewer.html +24 -88
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_vscode_extension.py +1 -1
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_vscode_signal.py +124 -93
- arrayview-0.29.2/src/arrayview/arrayview-opener.vsix +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/tests/test_api.py +67 -4
- {arrayview-0.29.0 → arrayview-0.29.2}/tests/test_lifecycle_contract.py +165 -4
- {arrayview-0.29.0 → arrayview-0.29.2}/tests/test_view_component_integration.py +22 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/uv.lock +1 -1
- {arrayview-0.29.0 → arrayview-0.29.2}/vscode-extension/extension.js +14 -1
- {arrayview-0.29.0 → arrayview-0.29.2}/vscode-extension/lifecycle_helpers.js +5 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/vscode-extension/package.json +1 -1
- {arrayview-0.29.0 → arrayview-0.29.2}/vscode-extension/test_lifecycle_helpers.js +6 -0
- arrayview-0.29.0/src/arrayview/arrayview-opener.vsix +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.agents/skills/frontend-designer/SKILL.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.agents/skills/invocation-consistency/SKILL.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.agents/skills/modes-consistency/SKILL.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.agents/skills/playwright-cli/SKILL.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.agents/skills/playwright-cli/references/element-attributes.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.agents/skills/playwright-cli/references/playwright-tests.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.agents/skills/playwright-cli/references/request-mocking.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.agents/skills/playwright-cli/references/running-code.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.agents/skills/playwright-cli/references/session-management.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.agents/skills/playwright-cli/references/storage-state.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.agents/skills/playwright-cli/references/test-generation.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.agents/skills/playwright-cli/references/tracing.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.agents/skills/playwright-cli/references/video-recording.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.agents/skills/todo-workflow/SKILL.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.agents/skills/ui-consistency-audit/SKILL.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.agents/skills/viewer-ui-checklist/SKILL.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.agents/skills/visual-bug-fixing/SKILL.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.github/copilot-instructions.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.github/workflows/docs.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.github/workflows/python-publish.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.gitignore +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.ignore +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.mex/AGENTS.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.mex/ROUTER.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.mex/SETUP.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.mex/SYNC.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.mex/context/architecture.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.mex/context/conventions.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.mex/context/decisions.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.mex/context/frontend.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.mex/context/project-state.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.mex/context/render-pipeline.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.mex/context/setup.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.mex/context/stack.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.mex/patterns/INDEX.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.mex/patterns/README.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.mex/patterns/add-file-format.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.mex/patterns/add-server-endpoint.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.mex/patterns/animation-verify.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.mex/patterns/debug-render.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.mex/patterns/debug-vscode-extension-python.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.mex/patterns/extend-compare-mode.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.mex/patterns/extract-server-route-module.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.mex/patterns/frontend-change.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.mex/setup.sh +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.mex/sync.sh +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.opencode/opencode.json +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-06T18-46-49-737Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-06T18-48-21-979Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-06T18-51-35-665Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-06T19-07-01-393Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-06T19-14-37-969Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-06T19-21-30-940Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-06T19-23-08-126Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-06T19-29-33-155Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-06T19-31-25-336Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-06T19-31-53-789Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-06T19-39-12-257Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-06T19-39-16-449Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-06T20-15-25-513Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-06T20-25-13-179Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-06T20-39-01-435Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-06T21-01-27-659Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-06T21-01-41-283Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-06T21-03-00-625Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-06T21-04-12-887Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-06T21-33-39-044Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-06T21-38-01-530Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-06T21-45-20-383Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-06T21-55-11-545Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-06T21-56-03-307Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-06T21-56-35-733Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-06T21-57-12-181Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-06T21-57-37-748Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-06T21-58-13-679Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-06T22-37-23-895Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-07T00-39-18-637Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-07T01-41-46-243Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-07T04-31-48-472Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-07T12-14-15-632Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-07T12-14-47-582Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-07T12-16-23-471Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-07T12-17-10-247Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-07T12-18-24-707Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-07T12-20-06-164Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-07T12-20-28-342Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-07T12-21-54-962Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-07T12-22-34-666Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-07T12-23-11-336Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-07T12-23-36-260Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-07T12-24-09-267Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-07T12-24-35-434Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-07T12-25-57-010Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-07T12-34-48-823Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-07T12-46-46-468Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-07T12-48-17-930Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-07T12-49-26-400Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-07T12-50-31-563Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/page-2026-05-07T12-56-45-568Z.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.playwright-cli/theme-dark.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.python-version +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/.vscode/settings.json +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/AGENTS.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/CONTRIBUTING.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/DESIGN.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/LICENSE +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/README.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/docs/comparing.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/docs/configuration.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/docs/display.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/docs/index.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/docs/launch-routing-refactor.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/docs/lifecycle.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/docs/loading.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/docs/logo.png +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/docs/measurement.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/docs/remote.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/docs/stylesheets/extra.css +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/docs/viewing.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/experiments/ws_tunnel_diag/ws_tunnel_diag.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/matlab/arrayview.m +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/mkdocs.yml +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/plans/2026-04-14-immersive-animation.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/plans/2026-05-07-unified-colormap-picker.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/plans/arrayview_tool_menu_fix_prompt.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/plans/arrayview_tool_menu_implementation_plan.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/plans/egg-placement-mockup.html +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/plans/refactoring_plan.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/plans/roi-analysis-requirements.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/plans/webview/LOG.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/scripts/demo.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/ARCHITECTURE.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/__init__.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/__main__.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_analysis.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_app.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_codex_open.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_config.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_diff.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_icon.png +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_imaging.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_io.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_launch_plan.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_lifecycle.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_overlays.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_platform.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_render.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_routes_analysis.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_routes_export.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_routes_loading.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_routes_persistence.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_routes_preload.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_routes_query.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_routes_rendering.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_routes_segmentation.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_routes_state.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_routes_vectorfield.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_routes_websocket.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_segmentation.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_server.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_session.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_shell.html +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_synthetic_mri.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_torch.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_vectorfield.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_vscode.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/_vscode_browser.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/src/arrayview/gsap.min.js +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/tests/capture_v_animation.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/tests/conftest.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/tests/lifecycle_matrix.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/tests/make_vectorfield_test_arrays.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/tests/test_backend_shared.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/tests/test_browser.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/tests/test_cli.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/tests/test_colorbar_hover_highlight.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/tests/test_command_reachability.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/tests/test_config.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/tests/test_cross_mode_parametrized.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/tests/test_interactions.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/tests/test_io.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/tests/test_large_arrays.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/tests/test_launch_plan.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/tests/test_loading_server.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/tests/test_mode_consistency.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/tests/test_mode_matrix.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/tests/test_mode_roundtrip.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/tests/test_nifti_meta.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/tests/test_nifti_series.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/tests/test_rgb_pixel_art.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/tests/test_torch.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/tests/test_view_component_unit.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/tests/ui_audit.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/tests/v_anim_frames/.gitkeep +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/tests/visual_smoke.py +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/vscode-extension/AGENTS.md +0 -0
- {arrayview-0.29.0 → arrayview-0.29.2}/vscode-extension/LICENSE +0 -0
|
@@ -60,7 +60,7 @@ This contract describes who owns the backend, when it starts, and what closes it
|
|
|
60
60
|
|
|
61
61
|
- Remote or tunnel launches may persist when `--serve` or tunnel display ownership requires it.
|
|
62
62
|
- VS Code tunnel display uses forwarded localhost URLs; the extension should configure the port, promote privacy when available, and resolve the URL with `asExternalUri`.
|
|
63
|
-
- With multiple registered tunnel windows, a missing or stale `ARRAYVIEW_WINDOW_ID`
|
|
63
|
+
- With multiple registered tunnel windows, a missing or stale `ARRAYVIEW_WINDOW_ID` uses the shared broadcast signal; only the focused VS Code window may claim it.
|
|
64
64
|
- An exact registered `ARRAYVIEW_WINDOW_ID` wins; do not redirect it to a newer same-parent registration because live tunnel windows can share ancestry.
|
|
65
65
|
- Plain SSH should use `localhost` forwarding guidance and stay transient unless a shared server was explicitly requested.
|
|
66
66
|
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# VS Code Window Routing Plan
|
|
2
|
+
|
|
3
|
+
## Problem
|
|
4
|
+
|
|
5
|
+
ArrayView can open the viewer tab in the wrong VS Code window when multiple
|
|
6
|
+
local windows and multiple remote/tunnel windows are active. The unsafe cases
|
|
7
|
+
are the ones where Python cannot prove the originating window and falls back to
|
|
8
|
+
writing multiple signal files or a shared signal file.
|
|
9
|
+
|
|
10
|
+
## Contract
|
|
11
|
+
|
|
12
|
+
- An exact `ARRAYVIEW_WINDOW_ID` wins when its registration exists.
|
|
13
|
+
- A missing or stale `ARRAYVIEW_WINDOW_ID` with multiple active registrations
|
|
14
|
+
fails closed with a diagnostic.
|
|
15
|
+
- PID ancestry and IPC hook matching are allowed only when they identify a
|
|
16
|
+
single window.
|
|
17
|
+
- tmux client fallback is allowed only when all attached clients for the current
|
|
18
|
+
tmux session report the same `ARRAYVIEW_WINDOW_ID`.
|
|
19
|
+
- File-explorer opens launched by the extension keep using the extension's own
|
|
20
|
+
`ARRAYVIEW_WINDOW_ID`.
|
|
21
|
+
|
|
22
|
+
## Implementation Slice
|
|
23
|
+
|
|
24
|
+
- Tighten `src/arrayview/_vscode_signal.py` window selection.
|
|
25
|
+
- Add focused lifecycle tests for local ambiguity, stale exact IDs, exact-ID
|
|
26
|
+
ownership, and tmux multi-client ambiguity.
|
|
27
|
+
- Avoid changing `_app.py` or the viewer frontend.
|
|
28
|
+
|
|
29
|
+
## Manual Verification Targets
|
|
30
|
+
|
|
31
|
+
- Local VS Code terminal, one window: opens in that window.
|
|
32
|
+
- Local VS Code terminal, several windows: stale/missing exact ID prints a
|
|
33
|
+
diagnostic instead of opening elsewhere.
|
|
34
|
+
- Remote/tunnel terminal, several windows: exact ID opens the matching window;
|
|
35
|
+
stale/missing ID fails closed.
|
|
36
|
+
- File explorer custom editor: spawned Python receives the extension window ID
|
|
37
|
+
and opens back into the same window.
|
|
@@ -8,7 +8,7 @@ set -euo pipefail
|
|
|
8
8
|
BUMP="minor"
|
|
9
9
|
DRY_RUN=true
|
|
10
10
|
NO_AI=false
|
|
11
|
-
AI_TOOL="
|
|
11
|
+
AI_TOOL="codex"
|
|
12
12
|
|
|
13
13
|
usage() {
|
|
14
14
|
cat <<EOF
|
|
@@ -16,7 +16,7 @@ Usage: $(basename "$0") [OPTIONS]
|
|
|
16
16
|
|
|
17
17
|
Options:
|
|
18
18
|
--bump {major,minor,patch} Version bump type (default: minor)
|
|
19
|
-
--ai {claude,codex} AI tool for release notes (default:
|
|
19
|
+
--ai {claude,codex} AI tool for release notes (default: codex)
|
|
20
20
|
--execute Actually run (default is dry-run)
|
|
21
21
|
--no-ai Skip AI release notes, use GitHub's --generate-notes
|
|
22
22
|
-h, --help Show this help
|
|
@@ -116,9 +116,13 @@ Rules:
|
|
|
116
116
|
if command -v "$CODEX_BIN" &>/dev/null; then
|
|
117
117
|
echo "Generating release notes with Codex..."
|
|
118
118
|
tmpfile=$(mktemp)
|
|
119
|
-
|
|
120
|
-
|
|
119
|
+
errfile=$(mktemp)
|
|
120
|
+
trap 'rm -f "$tmpfile" "$errfile"' EXIT
|
|
121
|
+
if printf '%s\n' "$PROMPT" | "$CODEX_BIN" exec --output-last-message "$tmpfile" - >/dev/null 2>"$errfile"; then
|
|
121
122
|
NOTES=$(<"$tmpfile")
|
|
123
|
+
elif [[ -s "$errfile" ]]; then
|
|
124
|
+
echo "Codex release notes failed:"
|
|
125
|
+
sed 's/^/ /' "$errfile"
|
|
122
126
|
fi
|
|
123
127
|
fi
|
|
124
128
|
;;
|
|
@@ -127,7 +131,19 @@ fi
|
|
|
127
131
|
|
|
128
132
|
if [[ -z "$NOTES" ]]; then
|
|
129
133
|
if [[ "$NO_AI" == false ]]; then
|
|
130
|
-
echo "AI notes unavailable, falling back to
|
|
134
|
+
echo "AI notes unavailable, falling back to commit-based notes"
|
|
135
|
+
fi
|
|
136
|
+
NOTES="## What's new in $TAG"
|
|
137
|
+
if [[ -n "$COMMITS" ]]; then
|
|
138
|
+
while IFS= read -r commit; do
|
|
139
|
+
[[ -z "$commit" ]] && continue
|
|
140
|
+
message="${commit#* }"
|
|
141
|
+
NOTES+=$'\n'
|
|
142
|
+
NOTES+="- ${message}"
|
|
143
|
+
done <<< "$COMMITS"
|
|
144
|
+
else
|
|
145
|
+
NOTES+=$'\n'
|
|
146
|
+
NOTES+="- Maintenance release."
|
|
131
147
|
fi
|
|
132
148
|
fi
|
|
133
149
|
|
|
@@ -146,17 +162,10 @@ run git push origin main
|
|
|
146
162
|
run git tag "$TAG"
|
|
147
163
|
run git push origin "$TAG"
|
|
148
164
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
--prerelease
|
|
154
|
-
else
|
|
155
|
-
run gh release create "$TAG" \
|
|
156
|
-
--title "$TAG" \
|
|
157
|
-
--generate-notes \
|
|
158
|
-
--prerelease
|
|
159
|
-
fi
|
|
165
|
+
run gh release create "$TAG" \
|
|
166
|
+
--title "$TAG" \
|
|
167
|
+
--notes "$NOTES" \
|
|
168
|
+
--prerelease
|
|
160
169
|
|
|
161
170
|
if [[ "$DRY_RUN" == true ]]; then
|
|
162
171
|
echo ""
|
|
@@ -677,9 +677,7 @@ def _activate_early_cli_native_shell(
|
|
|
677
677
|
notified = bool(notify_result.get("notified"))
|
|
678
678
|
except Exception:
|
|
679
679
|
notified = False
|
|
680
|
-
if notified and
|
|
681
|
-
port, viewer_before=viewer_before
|
|
682
|
-
):
|
|
680
|
+
if notified and _wait_for_viewer_connection(port, before=viewer_before):
|
|
683
681
|
return True
|
|
684
682
|
_vprint(
|
|
685
683
|
"[ArrayView] Native window did not connect to the backend; falling back to browser",
|
|
@@ -1216,8 +1214,12 @@ def _handle_cli_spawned_daemon(
|
|
|
1216
1214
|
and not is_remote
|
|
1217
1215
|
and not overlay_files
|
|
1218
1216
|
and not compare_files
|
|
1217
|
+
and not sys.platform.startswith("linux")
|
|
1219
1218
|
):
|
|
1220
|
-
|
|
1219
|
+
# Linux QtWebEngine denies sessionStorage to the viewer iframe when its
|
|
1220
|
+
# parent shell was created from inline data. Let Linux open the normal
|
|
1221
|
+
# HTTP shell after the daemon is listening instead.
|
|
1222
|
+
url_shell_early = f"http://{_LOOPBACK_HOST}:{port}/shell"
|
|
1221
1223
|
early_native_shell_opened, early_native_shell_proc = _open_webview_cli_tracked(
|
|
1222
1224
|
url_shell_early, 1400, 900, shell_port=port
|
|
1223
1225
|
)
|
|
@@ -439,7 +439,6 @@
|
|
|
439
439
|
#mv-cb { border: none; }
|
|
440
440
|
.highlight { color: var(--highlight); font-weight: bold; }
|
|
441
441
|
.dim-size { opacity: 0.28; font-size: 0.68em; font-weight: normal; }
|
|
442
|
-
.dim-hover-idx { font-size: 0.68em; font-weight: normal; color: var(--dim-hover, #777); opacity: 1; }
|
|
443
442
|
.active-dim { font-weight: bold; }
|
|
444
443
|
.playing-dim { font-weight: bold; }
|
|
445
444
|
.vfield-t-dim { color: var(--vfield-t-dim); }
|
|
@@ -3338,6 +3337,7 @@
|
|
|
3338
3337
|
#mv-panes.mv-crosshair-active .mv-pane::after {
|
|
3339
3338
|
content: ''; position: absolute; inset: 0; z-index: 4;
|
|
3340
3339
|
box-shadow: inset 0 0 0 var(--mv-plane-border-width, 1px) var(--mv-plane-border, var(--active-dim));
|
|
3340
|
+
opacity: 0.45;
|
|
3341
3341
|
border-radius: inherit; box-sizing: border-box;
|
|
3342
3342
|
pointer-events: none;
|
|
3343
3343
|
}
|
|
@@ -13885,7 +13885,6 @@
|
|
|
13885
13885
|
if (!['circle', 'rect', 'freehand', 'floodfill'].includes(_roiShape)) _roiShape = 'circle';
|
|
13886
13886
|
_roiVisible = true;
|
|
13887
13887
|
hideAllPixelInfo();
|
|
13888
|
-
_resetDimbarHover();
|
|
13889
13888
|
canvas.style.cursor = 'crosshair';
|
|
13890
13889
|
if (qmriActive) qmriViews.forEach(v => { v.canvas.style.cursor = 'crosshair'; });
|
|
13891
13890
|
if (multiViewActive) mvViews.forEach(v => { v.canvas.style.cursor = 'crosshair'; });
|
|
@@ -16481,38 +16480,6 @@
|
|
|
16481
16480
|
_updateMvPaneFill();
|
|
16482
16481
|
}
|
|
16483
16482
|
|
|
16484
|
-
function _dimHoverPadded(val, maxVal) {
|
|
16485
|
-
const maxStr = String(maxVal);
|
|
16486
|
-
const valStr = String(val);
|
|
16487
|
-
const padLen = maxStr.length - valStr.length;
|
|
16488
|
-
if (padLen <= 0) return '/' + valStr;
|
|
16489
|
-
return '/<span style="opacity:0.28">' + '0'.repeat(padLen) + '</span>' + valStr;
|
|
16490
|
-
}
|
|
16491
|
-
function _updateDimbarHover(px, py, xLabel, yLabel, pz) {
|
|
16492
|
-
// xLabel/yLabel: 'x','y','z' — which dimbar label to update (default x,y)
|
|
16493
|
-
// pz: optional z index (for mosaic mode)
|
|
16494
|
-
const xl = xLabel || 'x', yl = yLabel || 'y';
|
|
16495
|
-
const xEl = document.getElementById('dim-' + xl + '-size');
|
|
16496
|
-
const yEl = document.getElementById('dim-' + yl + '-size');
|
|
16497
|
-
const zEl = document.getElementById('dim-z-size');
|
|
16498
|
-
// Resolve label to shape dim index for padding width
|
|
16499
|
-
const labelToDim = (multiViewActive || compareMvActive)
|
|
16500
|
-
? { x: (multiViewActive ? mvDims : compareMvDims)[0], y: (multiViewActive ? mvDims : compareMvDims)[1], z: (multiViewActive ? mvDims : compareMvDims)[2] }
|
|
16501
|
-
: { x: dim_x, y: dim_y, z: dim_z };
|
|
16502
|
-
const xMax = labelToDim[xl] >= 0 ? shape[labelToDim[xl]] : 1;
|
|
16503
|
-
const yMax = labelToDim[yl] >= 0 ? shape[labelToDim[yl]] : 1;
|
|
16504
|
-
if (xEl) { xEl.innerHTML = _dimHoverPadded(px, xMax); xEl.className = 'dim-hover-idx'; }
|
|
16505
|
-
if (yEl) { yEl.innerHTML = _dimHoverPadded(py, yMax); yEl.className = 'dim-hover-idx'; }
|
|
16506
|
-
if (zEl && pz != null) {
|
|
16507
|
-
const zMax = dim_z >= 0 ? shape[dim_z] : 1;
|
|
16508
|
-
zEl.innerHTML = _dimHoverPadded(pz + 1, zMax); zEl.className = 'dim-hover-idx';
|
|
16509
|
-
}
|
|
16510
|
-
}
|
|
16511
|
-
function _resetDimbarHover() {
|
|
16512
|
-
// Re-render dimbar to restore correct max sizes for all modes
|
|
16513
|
-
renderInfo();
|
|
16514
|
-
}
|
|
16515
|
-
|
|
16516
16483
|
// Gnomon visibility: shown while a dim-bar token is hovered, or flashed
|
|
16517
16484
|
// briefly when activeDim changes via h/l/←/→. Hidden otherwise.
|
|
16518
16485
|
// In oblique mode the x/y labels no longer name axis-aligned directions,
|
|
@@ -17711,13 +17678,18 @@
|
|
|
17711
17678
|
|
|
17712
17679
|
function saveState() {
|
|
17713
17680
|
if (!sid) return;
|
|
17714
|
-
|
|
17681
|
+
try {
|
|
17682
|
+
sessionStorage.setItem('av_' + sid, JSON.stringify(collectStateSnapshot()));
|
|
17683
|
+
} catch (e) {
|
|
17684
|
+
// Some embedded webviews deny storage access. Viewing must keep
|
|
17685
|
+
// working even when this optional convenience is unavailable.
|
|
17686
|
+
}
|
|
17715
17687
|
}
|
|
17716
17688
|
|
|
17717
17689
|
function restoreStateFromSessionStorage() {
|
|
17718
|
-
const raw = sessionStorage.getItem('av_' + sid);
|
|
17719
|
-
if (!raw) return false;
|
|
17720
17690
|
try {
|
|
17691
|
+
const raw = sessionStorage.getItem('av_' + sid);
|
|
17692
|
+
if (!raw) return false;
|
|
17721
17693
|
return applyStateSnapshot(JSON.parse(raw));
|
|
17722
17694
|
} catch (e) {
|
|
17723
17695
|
return false;
|
|
@@ -20117,7 +20089,6 @@
|
|
|
20117
20089
|
showPixelInfo(document.getElementById('main-pixel-info'), { valueText: _pixelFmt(d.value, _activeNumericContext()), rawX, rawY }, e.clientX, e.clientY);
|
|
20118
20090
|
}).catch(() => {});
|
|
20119
20091
|
}
|
|
20120
|
-
_updateDimbarHover(localX, localY, null, null, zIdx);
|
|
20121
20092
|
return;
|
|
20122
20093
|
}
|
|
20123
20094
|
|
|
@@ -20131,11 +20102,6 @@
|
|
|
20131
20102
|
imgW: canvas.width,
|
|
20132
20103
|
imgH: canvas.height,
|
|
20133
20104
|
displayEl: document.getElementById('main-pixel-info'),
|
|
20134
|
-
onResult: (d, px, py) => {
|
|
20135
|
-
if (_pixelInfoActive() && !multiViewActive && !compareActive) {
|
|
20136
|
-
_updateDimbarHover(px, py);
|
|
20137
|
-
}
|
|
20138
|
-
},
|
|
20139
20105
|
});
|
|
20140
20106
|
});
|
|
20141
20107
|
canvas.addEventListener('mouseleave', () => {
|
|
@@ -20154,8 +20120,7 @@
|
|
|
20154
20120
|
if (_pixelInfoHeld) {
|
|
20155
20121
|
_pixelInfoHeld = false;
|
|
20156
20122
|
if (!_pixelInfoVisible) {
|
|
20157
|
-
|
|
20158
|
-
if (piEl) piEl.style.display = 'none';
|
|
20123
|
+
hideAllPixelInfo();
|
|
20159
20124
|
}
|
|
20160
20125
|
}
|
|
20161
20126
|
});
|
|
@@ -20924,7 +20889,6 @@
|
|
|
20924
20889
|
if (!_pixelInfoVisible) {
|
|
20925
20890
|
_clearHoverPins();
|
|
20926
20891
|
hideAllPixelInfo();
|
|
20927
|
-
_resetDimbarHover();
|
|
20928
20892
|
const axEl = document.getElementById('main-axes-svg');
|
|
20929
20893
|
if (axEl) {
|
|
20930
20894
|
axEl.querySelector('.axes-lbl-x').textContent = 'x';
|
|
@@ -26047,21 +26011,6 @@
|
|
|
26047
26011
|
imgH: view.lastH,
|
|
26048
26012
|
view,
|
|
26049
26013
|
displayEl: view.pixelInfoEl,
|
|
26050
|
-
onResult: (d, px, py) => {
|
|
26051
|
-
if (_pixelInfoActive()) {
|
|
26052
|
-
// Map pane dims to dimbar x/y/z labels
|
|
26053
|
-
const labels = ['x','y','z'];
|
|
26054
|
-
const activeDims = multiViewActive ? mvDims : (compareMvActive ? compareMvDims : []);
|
|
26055
|
-
const posX = activeDims.indexOf(view.dimX);
|
|
26056
|
-
const posY = activeDims.indexOf(view.dimY);
|
|
26057
|
-
const lblX = labels[posX] || 'x';
|
|
26058
|
-
const lblY = labels[posY] || 'y';
|
|
26059
|
-
const elX = document.getElementById('dim-' + lblX + '-size');
|
|
26060
|
-
const elY = document.getElementById('dim-' + lblY + '-size');
|
|
26061
|
-
if (elX) { elX.textContent = '/' + px; elX.className = 'dim-hover-idx'; }
|
|
26062
|
-
if (elY) { elY.textContent = '/' + py; elY.className = 'dim-hover-idx'; }
|
|
26063
|
-
}
|
|
26064
|
-
},
|
|
26065
26014
|
});
|
|
26066
26015
|
});
|
|
26067
26016
|
cv.addEventListener('mouseleave', () => {
|
|
@@ -26072,7 +26021,6 @@
|
|
|
26072
26021
|
if (tq) tq.classList.remove('visible');
|
|
26073
26022
|
_roiSuppressPixelInfo = false;
|
|
26074
26023
|
if (!mvDraggingView && view.pixelInfoEl) view.pixelInfoEl.style.display = 'none';
|
|
26075
|
-
if (_pixelInfoActive()) _resetDimbarHover();
|
|
26076
26024
|
});
|
|
26077
26025
|
// Click-to-copy: multiview canvases
|
|
26078
26026
|
let _mvClickDown = null;
|
|
@@ -26935,7 +26883,6 @@
|
|
|
26935
26883
|
view,
|
|
26936
26884
|
onResult: (d, px, py) => {
|
|
26937
26885
|
if (_pixelInfoActive()) {
|
|
26938
|
-
_updateDimbarHover(px, py);
|
|
26939
26886
|
return; // hover mode: only show hovered pane's value
|
|
26940
26887
|
}
|
|
26941
26888
|
// Non-hover: fetch for all other qmri views at same pixel
|
|
@@ -26962,10 +26909,9 @@
|
|
|
26962
26909
|
});
|
|
26963
26910
|
});
|
|
26964
26911
|
cv.addEventListener('mouseleave', () => {
|
|
26965
|
-
|
|
26966
|
-
|
|
26967
|
-
|
|
26968
|
-
});
|
|
26912
|
+
if (_qmriLoupeDrag && _qmriLoupeDrag.canvas === cv) _endQmriLoupe();
|
|
26913
|
+
qmriViews.forEach(v => { if (v.pixelInfoEl) v.pixelInfoEl.style.display = 'none'; });
|
|
26914
|
+
});
|
|
26969
26915
|
// ROI drawing on qMRI canvases
|
|
26970
26916
|
if (rectRoiMode) cv.style.cursor = 'crosshair';
|
|
26971
26917
|
cv.addEventListener('mousemove', (e) => {
|
|
@@ -27029,6 +26975,11 @@
|
|
|
27029
26975
|
}
|
|
27030
26976
|
});
|
|
27031
26977
|
cv.addEventListener('mousedown', (e) => {
|
|
26978
|
+
if (!rectRoiMode && e.button === 0 && !e.shiftKey && !e.metaKey && !e.ctrlKey && !e.altKey
|
|
26979
|
+
&& !_cropActive && !_segMode && !_rulerMode) {
|
|
26980
|
+
_pixelInfoHeld = true;
|
|
26981
|
+
cv.dispatchEvent(new MouseEvent('mousemove', { clientX: e.clientX, clientY: e.clientY, bubbles: true }));
|
|
26982
|
+
}
|
|
27032
26983
|
if (!rectRoiMode || e.button !== 0 || e.shiftKey || e.metaKey) return;
|
|
27033
26984
|
e.preventDefault(); sink.focus();
|
|
27034
26985
|
const rect = cv.getBoundingClientRect();
|
|
@@ -27449,15 +27400,17 @@
|
|
|
27449
27400
|
view,
|
|
27450
27401
|
displayEl: view.pixelInfoEl,
|
|
27451
27402
|
qmriRole: view.qmriRole,
|
|
27452
|
-
onResult: (d, px, py) => {
|
|
27453
|
-
if (_pixelInfoActive()) _updateDimbarHover(px, py);
|
|
27454
|
-
},
|
|
27455
27403
|
});
|
|
27456
27404
|
});
|
|
27405
|
+
cv.addEventListener('mousedown', (e) => {
|
|
27406
|
+
if (e.button !== 0 || e.shiftKey || e.metaKey || e.ctrlKey || e.altKey
|
|
27407
|
+
|| _cropActive || _segMode || _rulerMode) return;
|
|
27408
|
+
_pixelInfoHeld = true;
|
|
27409
|
+
cv.dispatchEvent(new MouseEvent('mousemove', { clientX: e.clientX, clientY: e.clientY, bubbles: true }));
|
|
27410
|
+
});
|
|
27457
27411
|
cv.addEventListener('mouseleave', () => {
|
|
27458
27412
|
if (_qmriLoupeDrag && _qmriLoupeDrag.canvas === cv) _endQmriLoupe();
|
|
27459
27413
|
compareQmriViews.forEach(v => { if (v.pixelInfoEl) v.pixelInfoEl.style.display = 'none'; });
|
|
27460
|
-
if (_pixelInfoActive()) _resetDimbarHover();
|
|
27461
27414
|
});
|
|
27462
27415
|
if (!httpTransport) {
|
|
27463
27416
|
view.ws = createTransport(sidVal,
|
|
@@ -27936,20 +27889,6 @@
|
|
|
27936
27889
|
imgH: view.lastH,
|
|
27937
27890
|
view,
|
|
27938
27891
|
displayEl: view.pixelInfoEl,
|
|
27939
|
-
onResult: (d, px, py) => {
|
|
27940
|
-
if (_pixelInfoActive()) {
|
|
27941
|
-
const labels = ['x','y','z'];
|
|
27942
|
-
const activeDims = compareMvDims || [];
|
|
27943
|
-
const posX = activeDims.indexOf(view.dimX);
|
|
27944
|
-
const posY = activeDims.indexOf(view.dimY);
|
|
27945
|
-
const lblX = labels[posX] || 'x';
|
|
27946
|
-
const lblY = labels[posY] || 'y';
|
|
27947
|
-
const elX = document.getElementById('dim-' + lblX + '-size');
|
|
27948
|
-
const elY = document.getElementById('dim-' + lblY + '-size');
|
|
27949
|
-
if (elX) { elX.textContent = '/' + px; elX.className = 'dim-hover-idx'; }
|
|
27950
|
-
if (elY) { elY.textContent = '/' + py; elY.className = 'dim-hover-idx'; }
|
|
27951
|
-
}
|
|
27952
|
-
},
|
|
27953
27892
|
});
|
|
27954
27893
|
});
|
|
27955
27894
|
cv.addEventListener('mouseleave', () => {
|
|
@@ -27957,7 +27896,6 @@
|
|
|
27957
27896
|
if (!cmvDraggingView) {
|
|
27958
27897
|
compareMvViews.forEach(v => { if (v.pixelInfoEl) v.pixelInfoEl.style.display = 'none'; });
|
|
27959
27898
|
}
|
|
27960
|
-
if (_pixelInfoActive()) _resetDimbarHover();
|
|
27961
27899
|
});
|
|
27962
27900
|
// Click-to-copy: compare-multiview canvases
|
|
27963
27901
|
let _cmvClickDown = null;
|
|
@@ -30116,7 +30054,6 @@
|
|
|
30116
30054
|
displayEl: piEl,
|
|
30117
30055
|
onResult: (d, px, py) => {
|
|
30118
30056
|
if (!_pixelInfoActive()) return;
|
|
30119
|
-
_updateDimbarHover(px, py);
|
|
30120
30057
|
// Show value on other compare panes at the same pixel
|
|
30121
30058
|
const ver = indices.join(',') + ':' + dim_x + ':' + dim_y + ':' + complexMode + ':' + logScale;
|
|
30122
30059
|
compareCanvases.forEach((ocv, j) => {
|
|
@@ -30145,7 +30082,6 @@
|
|
|
30145
30082
|
cv.addEventListener('mouseleave', () => {
|
|
30146
30083
|
_comparePiEls.forEach(p => { if (p) p.style.display = 'none'; });
|
|
30147
30084
|
hideCompareCrosshairs();
|
|
30148
|
-
if (_pixelInfoActive()) _resetDimbarHover();
|
|
30149
30085
|
});
|
|
30150
30086
|
});
|
|
30151
30087
|
// Click-to-copy: compare canvases
|
|
@@ -44,7 +44,7 @@ def _vscode_app_bundle() -> str | None:
|
|
|
44
44
|
|
|
45
45
|
_VSCODE_EXT_INSTALLED = False # cached so we only check once per process
|
|
46
46
|
_VSCODE_EXT_FRESH_INSTALL = False # True if we just installed it this session
|
|
47
|
-
_VSCODE_EXT_VERSION = "0.14.
|
|
47
|
+
_VSCODE_EXT_VERSION = "0.14.35" # current bundled extension version
|
|
48
48
|
|
|
49
49
|
def _bundled_vscode_vsix_version(vsix_path: str) -> str | None:
|
|
50
50
|
"""Return the bundled opener extension version recorded inside the VSIX."""
|