plexora 0.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- plexora/__init__.py +129 -0
- plexora/__main__.py +15 -0
- plexora/_url.py +105 -0
- plexora/api/__init__.py +55 -0
- plexora/api/dataset.py +398 -0
- plexora/api/http.py +19 -0
- plexora/api/plugin.py +541 -0
- plexora/api/store.py +221 -0
- plexora/cli.py +777 -0
- plexora/client/dist/354_bundle.js +2 -0
- plexora/client/dist/354_bundle.js.LICENSE.txt +20 -0
- plexora/client/dist/418_bundle.js +2 -0
- plexora/client/dist/418_bundle.js.LICENSE.txt +1 -0
- plexora/client/dist/693b935cb1f907814be9c6199a68c217.svg +19 -0
- plexora/client/dist/713c134ff47cd328a5b711526f151082.svg +18 -0
- plexora/client/dist/770_bundle.js +1 -0
- plexora/client/dist/ff743f408972e0e96ca9153ed5ae4c83.svg +23 -0
- plexora/client/dist/vendor_bundle.js +2 -0
- plexora/client/dist/vendor_bundle.js.LICENSE.txt +308 -0
- plexora/client/external/openseadragon-bin-2.4.0/LICENSE.txt +28 -0
- plexora/client/external/openseadragon-bin-2.4.0/canvas-overlay-hd.js +140 -0
- plexora/client/external/openseadragon-bin-2.4.0/changelog.txt +501 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/.gitattributes +17 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/LICENSE.txt +116 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/Toolbar.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/fullpage.psd +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/home.psd +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/next.psd +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/previous.psd +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/rotateleft.psd +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/rotateright.psd +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/zoom.psd +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/README.md +9 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/fullpage_grouphover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/fullpage_hover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/fullpage_pressed.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/fullpage_rest.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/home_grouphover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/home_hover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/home_pressed.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/home_rest.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/next_grouphover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/next_hover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/next_pressed.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/next_rest.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/previous_grouphover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/previous_hover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/previous_pressed.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/previous_rest.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateleft_grouphover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateleft_hover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateleft_pressed.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateleft_rest.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateright_grouphover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateright_hover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateright_pressed.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateright_rest.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomin_grouphover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomin_hover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomin_pressed.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomin_rest.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomout_grouphover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomout_hover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomout_pressed.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomout_rest.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-scalebar.js +562 -0
- plexora/client/src/css/import.css +474 -0
- plexora/client/src/css/main.css +903 -0
- plexora/client/src/css/openProject.css +363 -0
- plexora/client/src/css/quickView.css +166 -0
- plexora/client/src/css/tokens.css +51 -0
- plexora/client/src/css/viewer.css +1655 -0
- plexora/client/src/img/apple-touch-icon.png +0 -0
- plexora/client/src/img/favicon.ico +0 -0
- plexora/client/src/img/logo.ai +8892 -33
- plexora/client/src/img/logo.svg +1 -0
- plexora/client/src/img/logo_with_text.ai +9011 -34
- plexora/client/src/img/logo_with_text.svg +1 -0
- plexora/client/src/js/main.js +704 -0
- plexora/client/src/js/pluginRegistry.js +108 -0
- plexora/client/src/js/services/appStatus.js +286 -0
- plexora/client/src/js/services/browsePicker.js +73 -0
- plexora/client/src/js/services/dataLayer.js +400 -0
- plexora/client/src/js/services/datasetContext.js +143 -0
- plexora/client/src/js/services/glRenderer.js +143 -0
- plexora/client/src/js/services/importFormValidation.js +257 -0
- plexora/client/src/js/services/numericData.js +100 -0
- plexora/client/src/js/services/passVariablesToFrontend.js +20 -0
- plexora/client/src/js/services/simpleEventHandler.js +25 -0
- plexora/client/src/js/vendor.js +29 -0
- plexora/client/src/js/views/channelList.js +663 -0
- plexora/client/src/js/views/colorSwatchPicker.js +202 -0
- plexora/client/src/js/views/columnClassifier.js +146 -0
- plexora/client/src/js/views/coordinateField.js +133 -0
- plexora/client/src/js/views/dataSourceField.js +276 -0
- plexora/client/src/js/views/imageViewer.js +3306 -0
- plexora/client/src/js/views/miniMap.js +787 -0
- plexora/client/src/js/views/navbarControls.js +178 -0
- plexora/client/src/js/views/openProjectPage.js +239 -0
- plexora/client/src/js/views/projectEdit.js +335 -0
- plexora/client/src/js/views/quickViewLanding.js +136 -0
- plexora/client/src/js/views/rainbow.js +326 -0
- plexora/client/src/js/views/requirementsModal.js +572 -0
- plexora/client/src/js/views/rgbImageViewer.js +115 -0
- plexora/client/src/js/views/searchableSelect.js +411 -0
- plexora/client/src/js/views/segmentationProgress.js +122 -0
- plexora/client/src/js/views/toolLoader.js +747 -0
- plexora/client/src/js/views/viewerControls.js +689 -0
- plexora/client/src/js/views/viewerManager.js +434 -0
- plexora/client/src/js/views/viewerSidebar.js +1117 -0
- plexora/client/src/js/workers/tileDecoder.js +130 -0
- plexora/client/src/shaders/frag.glsl +528 -0
- plexora/client/src/shaders/vert.glsl +12 -0
- plexora/client/templates/base.html +212 -0
- plexora/client/templates/index.html +238 -0
- plexora/client/templates/open_project.html +96 -0
- plexora/client/templates/project_columns.html +86 -0
- plexora/client/templates/project_edit.html +196 -0
- plexora/client/templates/upload.html +118 -0
- plexora/connect.py +528 -0
- plexora/datasource.py +782 -0
- plexora/jupyter.py +406 -0
- plexora/notebook_env.py +232 -0
- plexora/paths.py +486 -0
- plexora/plugins/__init__.py +12 -0
- plexora/plugins/cell_explorer/__init__.py +100 -0
- plexora/plugins/cell_explorer/server/__init__.py +11 -0
- plexora/plugins/cell_explorer/server/routes.py +167 -0
- plexora/plugins/cell_explorer/server/state.py +281 -0
- plexora/plugins/cell_explorer/server/values.py +145 -0
- plexora/plugins/cell_explorer/server/variables.py +367 -0
- plexora/plugins/cell_explorer/static/cellExplorerApi.js +158 -0
- plexora/plugins/cell_explorer/static/cellExplorerColors.js +316 -0
- plexora/plugins/cell_explorer/static/cellExplorerContinuous.js +403 -0
- plexora/plugins/cell_explorer/static/cellExplorerFigureBridge.js +133 -0
- plexora/plugins/cell_explorer/static/cellExplorerLegend.js +188 -0
- plexora/plugins/cell_explorer/static/cellExplorerRoiBridge.js +822 -0
- plexora/plugins/cell_explorer/static/cellExplorerSidebarController.js +826 -0
- plexora/plugins/cell_explorer/static/cellExplorerState.js +372 -0
- plexora/plugins/cell_explorer/static/cell_explorer.css +752 -0
- plexora/plugins/cell_explorer/templates/cell_explorer/panel.html +137 -0
- plexora/plugins/figure_builder/__init__.py +125 -0
- plexora/plugins/figure_builder/server/__init__.py +7 -0
- plexora/plugins/figure_builder/server/compose.py +365 -0
- plexora/plugins/figure_builder/server/export.py +784 -0
- plexora/plugins/figure_builder/server/export_jobs.py +148 -0
- plexora/plugins/figure_builder/server/operations.py +556 -0
- plexora/plugins/figure_builder/server/pixels.py +142 -0
- plexora/plugins/figure_builder/server/provenance.py +174 -0
- plexora/plugins/figure_builder/server/render.py +278 -0
- plexora/plugins/figure_builder/server/repository.py +701 -0
- plexora/plugins/figure_builder/server/routes.py +594 -0
- plexora/plugins/figure_builder/server/schema.py +1023 -0
- plexora/plugins/figure_builder/server/sources.py +120 -0
- plexora/plugins/figure_builder/server/textmetrics.py +155 -0
- plexora/plugins/figure_builder/static/figureActions.js +363 -0
- plexora/plugins/figure_builder/static/figureBuilderApi.js +255 -0
- plexora/plugins/figure_builder/static/figureCanvas.js +2362 -0
- plexora/plugins/figure_builder/static/figureCaptureBoxes.js +369 -0
- plexora/plugins/figure_builder/static/figureCaptureDock.js +466 -0
- plexora/plugins/figure_builder/static/figureCaptureTool.js +1034 -0
- plexora/plugins/figure_builder/static/figureConfirm.js +136 -0
- plexora/plugins/figure_builder/static/figureContextBar.js +1193 -0
- plexora/plugins/figure_builder/static/figureContextMenu.js +253 -0
- plexora/plugins/figure_builder/static/figureDocumentState.js +275 -0
- plexora/plugins/figure_builder/static/figureExportUi.js +174 -0
- plexora/plugins/figure_builder/static/figureLibrary.js +247 -0
- plexora/plugins/figure_builder/static/figureQuickEdit.js +628 -0
- plexora/plugins/figure_builder/static/figureRichText.js +634 -0
- plexora/plugins/figure_builder/static/figureSceneSnapshot.js +361 -0
- plexora/plugins/figure_builder/static/figureSchema.js +218 -0
- plexora/plugins/figure_builder/static/figureSidebarController.js +1159 -0
- plexora/plugins/figure_builder/static/figureTextEditor.js +503 -0
- plexora/plugins/figure_builder/static/figureTextPanel.js +491 -0
- plexora/plugins/figure_builder/static/figureViewOptions.js +273 -0
- plexora/plugins/figure_builder/static/figureWorkspace.js +2030 -0
- plexora/plugins/figure_builder/static/figure_builder.css +3292 -0
- plexora/plugins/figure_builder/templates/figure_builder/library.html +74 -0
- plexora/plugins/figure_builder/templates/figure_builder/workspace.html +27 -0
- plexora/plugins/figure_builder/templates/figure_builder/workspace_body.html +458 -0
- plexora/plugins/gating/__init__.py +76 -0
- plexora/plugins/gating/server/__init__.py +0 -0
- plexora/plugins/gating/server/anndata_gates.py +367 -0
- plexora/plugins/gating/server/database.py +16 -0
- plexora/plugins/gating/server/model.py +320 -0
- plexora/plugins/gating/server/routes.py +235 -0
- plexora/plugins/gating/static/csvGatingList.js +947 -0
- plexora/plugins/gating/static/gating.css +289 -0
- plexora/plugins/gating/static/gatingApi.js +221 -0
- plexora/plugins/gating/static/gatingSidebarController.js +513 -0
- plexora/plugins/gating/templates/gating/legacy.html +26 -0
- plexora/plugins/gating/templates/gating/panel.html +69 -0
- plexora/plugins/roi/__init__.py +95 -0
- plexora/plugins/roi/server/__init__.py +8 -0
- plexora/plugins/roi/server/adapters.py +655 -0
- plexora/plugins/roi/server/geojson.py +267 -0
- plexora/plugins/roi/server/geometry.py +181 -0
- plexora/plugins/roi/server/mapping.py +169 -0
- plexora/plugins/roi/server/operations.py +293 -0
- plexora/plugins/roi/server/repository.py +215 -0
- plexora/plugins/roi/server/routes.py +409 -0
- plexora/plugins/roi/server/schema.py +323 -0
- plexora/plugins/roi/static/roi.css +583 -0
- plexora/plugins/roi/static/roiApi.js +177 -0
- plexora/plugins/roi/static/roiFigureBridge.js +107 -0
- plexora/plugins/roi/static/roiGeometry.js +350 -0
- plexora/plugins/roi/static/roiRenderer.js +278 -0
- plexora/plugins/roi/static/roiSidebarController.js +1038 -0
- plexora/plugins/roi/static/roiState.js +518 -0
- plexora/plugins/roi/static/roiTools.js +993 -0
- plexora/plugins/roi/templates/roi/panel.html +240 -0
- plexora/proxy.py +57 -0
- plexora/server/models/adapters/__init__.py +94 -0
- plexora/server/models/adapters/anndata_adapter.py +388 -0
- plexora/server/models/adapters/base.py +93 -0
- plexora/server/models/adapters/classify.py +192 -0
- plexora/server/models/adapters/csv_adapter.py +105 -0
- plexora/server/models/adapters/inspection.py +265 -0
- plexora/server/models/adapters/spatialdata_adapter.py +248 -0
- plexora/server/models/centroid_tiles.py +305 -0
- plexora/server/models/data_model.py +1659 -0
- plexora/server/models/database_model.py +169 -0
- plexora/server/models/project.py +1270 -0
- plexora/server/plugins.py +199 -0
- plexora/server/routes/browse_routes.py +41 -0
- plexora/server/routes/data_routes.py +294 -0
- plexora/server/routes/import_routes.py +603 -0
- plexora/server/routes/page_routes.py +139 -0
- plexora/server/routes/project_routes.py +438 -0
- plexora/server/routes/quick_view_routes.py +62 -0
- plexora/server/routes/system_routes.py +39 -0
- plexora/server/routes/tool_routes.py +418 -0
- plexora/server/utils/addHEColumns.py +11 -0
- plexora/server/utils/fast_png.py +97 -0
- plexora/server/utils/fullConversion.py +50 -0
- plexora/server/utils/native_dialog.py +168 -0
- plexora/server/utils/pre_normalization.py +47 -0
- plexora/server/utils/segmentation_pyramid.py +598 -0
- plexora/server/utils/smallestenclosingcircle.py +126 -0
- plexora/server/utils/tiffsurgeon.py +372 -0
- plexora/server_cli.py +48 -0
- plexora/test.py +0 -0
- plexora-0.0.1.dist-info/METADATA +341 -0
- plexora-0.0.1.dist-info/RECORD +248 -0
- plexora-0.0.1.dist-info/WHEEL +5 -0
- plexora-0.0.1.dist-info/entry_points.txt +12 -0
- plexora-0.0.1.dist-info/licenses/LICENSE +207 -0
- plexora-0.0.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,583 @@
|
|
|
1
|
+
/* Regions panel.
|
|
2
|
+
*
|
|
3
|
+
* This plugin's appearance, in this plugin's directory: core cannot ship the
|
|
4
|
+
* look of a tool it may not have installed, and nothing here may style a
|
|
5
|
+
* core-owned element (both directions are asserted by
|
|
6
|
+
* tests/test_plugin_css_boundary.py). Colours come from tokens.css, which
|
|
7
|
+
* base.html loads for every page, so the panel matches the rest of the sidebar
|
|
8
|
+
* without restating any of it. */
|
|
9
|
+
|
|
10
|
+
#roi_panel_section {
|
|
11
|
+
border-color: rgba(56, 189, 248, 0.28);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
#roi_panel_section .section-heading h2 {
|
|
15
|
+
color: #dff1ff;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.roi-hidden-file {
|
|
19
|
+
display: none;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/* -- banners: the two states where saving cannot proceed ---------------- */
|
|
23
|
+
|
|
24
|
+
.roi-banner {
|
|
25
|
+
align-items: flex-start;
|
|
26
|
+
border-radius: var(--radius-sm);
|
|
27
|
+
display: flex;
|
|
28
|
+
font-size: 12px;
|
|
29
|
+
gap: var(--space-2);
|
|
30
|
+
line-height: 1.45;
|
|
31
|
+
margin-bottom: var(--space-3);
|
|
32
|
+
padding: var(--space-3);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.roi-banner-danger {
|
|
36
|
+
background: var(--accent-danger-soft);
|
|
37
|
+
border: 1px solid var(--accent-danger);
|
|
38
|
+
color: #ffe4e4;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.roi-banner-warning {
|
|
42
|
+
background: var(--accent-warning-soft);
|
|
43
|
+
border: 1px solid var(--accent-warning);
|
|
44
|
+
color: #fdf0d5;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.roi-banner-detail {
|
|
48
|
+
color: var(--text-secondary);
|
|
49
|
+
font-size: 11px;
|
|
50
|
+
margin-top: var(--space-1);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.roi-banner-actions {
|
|
54
|
+
display: flex;
|
|
55
|
+
flex-wrap: wrap;
|
|
56
|
+
gap: var(--space-2);
|
|
57
|
+
margin-top: var(--space-2);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.roi-banner-actions .sidebar-action {
|
|
61
|
+
font-size: 11px;
|
|
62
|
+
padding: 4px 8px;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/* -- toolbar ------------------------------------------------------------ */
|
|
66
|
+
|
|
67
|
+
.roi-toolbar {
|
|
68
|
+
display: grid;
|
|
69
|
+
gap: var(--space-2);
|
|
70
|
+
grid-template-columns: repeat(4, 1fr);
|
|
71
|
+
margin-bottom: var(--space-2);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.roi-tool {
|
|
75
|
+
align-items: center;
|
|
76
|
+
background: rgba(255, 255, 255, 0.06);
|
|
77
|
+
border: 1px solid var(--border-subtle);
|
|
78
|
+
border-radius: var(--radius-sm);
|
|
79
|
+
color: var(--text-secondary);
|
|
80
|
+
cursor: pointer;
|
|
81
|
+
display: flex;
|
|
82
|
+
flex-direction: column;
|
|
83
|
+
gap: 2px;
|
|
84
|
+
padding: var(--space-2) 0;
|
|
85
|
+
transition: background var(--duration-fast) var(--ease-standard),
|
|
86
|
+
border-color var(--duration-fast) var(--ease-standard);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.roi-tool:hover:not(:disabled) {
|
|
90
|
+
background: rgba(255, 255, 255, 0.12);
|
|
91
|
+
color: #ffffff;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.roi-tool.is-active {
|
|
95
|
+
background: var(--accent-channel-soft);
|
|
96
|
+
border-color: var(--accent-channel);
|
|
97
|
+
color: #ffffff;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.roi-tool:disabled {
|
|
101
|
+
cursor: default;
|
|
102
|
+
opacity: 0.4;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.roi-tool-key {
|
|
106
|
+
font-size: 9px;
|
|
107
|
+
letter-spacing: 0.06em;
|
|
108
|
+
opacity: 0.7;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.roi-hint {
|
|
112
|
+
color: var(--text-muted);
|
|
113
|
+
font-size: 11px;
|
|
114
|
+
line-height: 1.5;
|
|
115
|
+
margin-bottom: var(--space-3);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.roi-hint kbd {
|
|
119
|
+
background: rgba(255, 255, 255, 0.1);
|
|
120
|
+
border: 1px solid var(--border-subtle);
|
|
121
|
+
border-radius: 3px;
|
|
122
|
+
font-family: inherit;
|
|
123
|
+
font-size: 10px;
|
|
124
|
+
padding: 1px 4px;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/* -- categories --------------------------------------------------------- */
|
|
128
|
+
|
|
129
|
+
.roi-category-list {
|
|
130
|
+
display: flex;
|
|
131
|
+
flex-direction: column;
|
|
132
|
+
gap: var(--space-1);
|
|
133
|
+
margin-bottom: var(--space-2);
|
|
134
|
+
max-height: 220px;
|
|
135
|
+
overflow-y: auto;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.roi-category {
|
|
139
|
+
align-items: center;
|
|
140
|
+
border: 1px solid transparent;
|
|
141
|
+
border-radius: var(--radius-sm);
|
|
142
|
+
display: flex;
|
|
143
|
+
gap: var(--space-2);
|
|
144
|
+
padding: 3px var(--space-2) 3px 3px;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.roi-category.is-active {
|
|
148
|
+
background: rgba(255, 255, 255, 0.07);
|
|
149
|
+
border-color: var(--border-strong);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/* Hidden categories stay listed and stay operable -- being unable to find the
|
|
153
|
+
control that un-hides something is worse than the thing being hidden. */
|
|
154
|
+
.roi-category.is-hidden .roi-category-label,
|
|
155
|
+
.roi-category.is-hidden .roi-category-count {
|
|
156
|
+
opacity: 0.45;
|
|
157
|
+
text-decoration: line-through;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.roi-swatch {
|
|
161
|
+
background: none;
|
|
162
|
+
border: 1px solid var(--border-subtle);
|
|
163
|
+
border-radius: var(--radius-sm);
|
|
164
|
+
cursor: pointer;
|
|
165
|
+
flex: 0 0 auto;
|
|
166
|
+
height: 22px;
|
|
167
|
+
padding: 0;
|
|
168
|
+
width: 22px;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.roi-category-label {
|
|
172
|
+
background: none;
|
|
173
|
+
border: 0;
|
|
174
|
+
color: var(--text-primary);
|
|
175
|
+
cursor: pointer;
|
|
176
|
+
flex: 1 1 auto;
|
|
177
|
+
font-size: 12px;
|
|
178
|
+
min-width: 0;
|
|
179
|
+
overflow: hidden;
|
|
180
|
+
padding: 0;
|
|
181
|
+
text-align: left;
|
|
182
|
+
text-overflow: ellipsis;
|
|
183
|
+
white-space: nowrap;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.roi-category-count {
|
|
187
|
+
color: var(--text-muted);
|
|
188
|
+
flex: 0 0 auto;
|
|
189
|
+
font-size: 11px;
|
|
190
|
+
font-variant-numeric: tabular-nums;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
.roi-category-action {
|
|
194
|
+
flex: 0 0 auto;
|
|
195
|
+
font-size: 10px;
|
|
196
|
+
height: 22px;
|
|
197
|
+
width: 22px;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/* Core's main.css carries a global `.fa-trash { color: black }`, written for a
|
|
201
|
+
light surface somewhere else in the app. It targets the GLYPH, so it beats
|
|
202
|
+
any colour inherited from the button around it -- which is why every trash
|
|
203
|
+
icon in this panel rendered as a black shape on a dark background no matter
|
|
204
|
+
what the button was set to. Handing the glyph back to its button is enough;
|
|
205
|
+
the rule is core's and other pages may be leaning on it, so it stays put and
|
|
206
|
+
this override is scoped to this plugin's own section. */
|
|
207
|
+
#roi_panel_section .fa-trash {
|
|
208
|
+
color: inherit;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/* And `.icon-button` carries `min-width: 28px`, sized for the buttons in a
|
|
212
|
+
section heading. The three small ones on this panel sit inside rows of text
|
|
213
|
+
and set their own smaller width, which that floor was quietly overriding --
|
|
214
|
+
leaving each of them wider than it is tall. Squares, as drawn. */
|
|
215
|
+
.roi-category-action,
|
|
216
|
+
.roi-selection-action,
|
|
217
|
+
.roi-destination-close,
|
|
218
|
+
.roi-modal-close {
|
|
219
|
+
min-width: 0;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.roi-modal-close {
|
|
223
|
+
flex: 0 0 auto;
|
|
224
|
+
font-size: 12px;
|
|
225
|
+
height: 26px;
|
|
226
|
+
width: 26px;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/* The controls that destroy something, coloured so they do not read as another
|
|
230
|
+
toggle sitting next to the eye and the padlock. Amber at rest, red under the
|
|
231
|
+
cursor: careful, then dangerous. Both trash buttons on this panel share the
|
|
232
|
+
rule, so they can never come to mean two different degrees of danger. */
|
|
233
|
+
.roi-category-delete,
|
|
234
|
+
.roi-danger-action {
|
|
235
|
+
color: var(--accent-warning);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
.roi-category-delete:hover,
|
|
239
|
+
.roi-danger-action:hover {
|
|
240
|
+
background: var(--accent-danger-soft);
|
|
241
|
+
color: var(--accent-danger);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/* -- nothing here yet ---------------------------------------------------- */
|
|
245
|
+
|
|
246
|
+
.roi-empty {
|
|
247
|
+
background: var(--surface-2);
|
|
248
|
+
border: 1px dashed var(--border-subtle);
|
|
249
|
+
border-radius: var(--radius-sm);
|
|
250
|
+
margin-bottom: var(--space-2);
|
|
251
|
+
padding: var(--space-2);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
.roi-category-add {
|
|
255
|
+
display: flex;
|
|
256
|
+
gap: var(--space-2);
|
|
257
|
+
margin-bottom: var(--space-3);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/* One rule for every text control this panel owns -- the category name, the
|
|
261
|
+
region name, the category dropdown, the destination. They sit within a few
|
|
262
|
+
rows of each other in a 320px column, and three heights there read as three
|
|
263
|
+
different kinds of control. */
|
|
264
|
+
.roi-input {
|
|
265
|
+
background: var(--surface-2);
|
|
266
|
+
border: 1px solid var(--border-subtle);
|
|
267
|
+
border-radius: var(--radius-sm);
|
|
268
|
+
box-sizing: border-box;
|
|
269
|
+
color: var(--text-primary);
|
|
270
|
+
font-family: inherit;
|
|
271
|
+
font-size: 12px;
|
|
272
|
+
min-width: 0;
|
|
273
|
+
padding: 6px var(--space-2);
|
|
274
|
+
width: 100%;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
.roi-input:focus {
|
|
278
|
+
border-color: var(--accent-channel);
|
|
279
|
+
outline: none;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
.roi-category-add .roi-input {
|
|
283
|
+
flex: 1 1 auto;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/* -- selected region ---------------------------------------------------- */
|
|
287
|
+
|
|
288
|
+
.roi-selection-head {
|
|
289
|
+
align-items: center;
|
|
290
|
+
display: flex;
|
|
291
|
+
gap: var(--space-2);
|
|
292
|
+
justify-content: space-between;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/* `.control-label` is written for a label stacked above its field, so it
|
|
296
|
+
carries a bottom margin. Both of this panel's heading rows put a label beside
|
|
297
|
+
something else instead, and have to take that margin back. */
|
|
298
|
+
.roi-selection-head .control-label,
|
|
299
|
+
.roi-destination-head .control-label {
|
|
300
|
+
margin: 0;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
.roi-selection-tools {
|
|
304
|
+
display: flex;
|
|
305
|
+
gap: var(--space-1);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
.roi-selection-action {
|
|
309
|
+
flex: 0 0 auto;
|
|
310
|
+
font-size: 11px;
|
|
311
|
+
height: 24px;
|
|
312
|
+
width: 24px;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
.roi-selection-action.is-active {
|
|
316
|
+
color: var(--accent-channel);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/* Which padlock is showing, decided by the button's own pressed state. See the
|
|
320
|
+
note in panel.html: this is a CSS swap because FontAwesome replaces the span
|
|
321
|
+
with an <svg> whose class cannot be rewritten without breaking it. */
|
|
322
|
+
#roi_selection_locked .fa-lock,
|
|
323
|
+
#roi_selection_locked[aria-pressed="true"] .fa-lock-open {
|
|
324
|
+
display: none;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
#roi_selection_locked[aria-pressed="true"] .fa-lock {
|
|
328
|
+
display: inline-block;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
.roi-selection-row {
|
|
332
|
+
align-items: center;
|
|
333
|
+
display: flex;
|
|
334
|
+
gap: var(--space-2);
|
|
335
|
+
margin: var(--space-1) 0 var(--space-2);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
.roi-selection-name {
|
|
339
|
+
flex: 1 1 58%;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
.roi-select-wrap {
|
|
343
|
+
flex: 0 1 42%;
|
|
344
|
+
min-width: 0;
|
|
345
|
+
position: relative;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/* Room for the swatch, which sits over this padding rather than in the flow --
|
|
349
|
+
a <select> cannot hold an element. */
|
|
350
|
+
.roi-select-wrap .roi-input {
|
|
351
|
+
padding-left: 24px;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
.roi-selection-swatch {
|
|
355
|
+
border-radius: 50%;
|
|
356
|
+
height: 9px;
|
|
357
|
+
left: 9px;
|
|
358
|
+
pointer-events: none;
|
|
359
|
+
position: absolute;
|
|
360
|
+
top: 50%;
|
|
361
|
+
transform: translateY(-50%);
|
|
362
|
+
width: 9px;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
.roi-selection-note {
|
|
366
|
+
margin-bottom: var(--space-2);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/* -- where a native save goes ------------------------------------------- */
|
|
370
|
+
|
|
371
|
+
/* Opened by the save button, closed by the save. Bordered and inset so that a
|
|
372
|
+
block which appears mid-panel reads as a step in the thing above it rather
|
|
373
|
+
than as another control that has always been there. */
|
|
374
|
+
.roi-destination {
|
|
375
|
+
background: rgba(255, 255, 255, 0.05);
|
|
376
|
+
border: 1px solid var(--border-subtle);
|
|
377
|
+
border-radius: var(--radius-sm);
|
|
378
|
+
margin-bottom: var(--space-2);
|
|
379
|
+
padding: var(--space-2);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
.roi-destination-head {
|
|
383
|
+
align-items: center;
|
|
384
|
+
display: flex;
|
|
385
|
+
gap: var(--space-2);
|
|
386
|
+
justify-content: space-between;
|
|
387
|
+
margin-bottom: var(--space-1);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
.roi-destination-close {
|
|
391
|
+
flex: 0 0 auto;
|
|
392
|
+
font-size: 11px;
|
|
393
|
+
height: 22px;
|
|
394
|
+
width: 22px;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
.roi-destination-hint {
|
|
398
|
+
margin: var(--space-1) 0 0;
|
|
399
|
+
overflow-wrap: anywhere;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
/* -- the two ways out, on one row --------------------------------------- */
|
|
403
|
+
|
|
404
|
+
/* Save and Map to cells are peers, not steps, so they sit beside each other.
|
|
405
|
+
Flex rather than a grid of fixed tracks: exactly one of the two save buttons
|
|
406
|
+
is shown at a time and the mapping pair is absent altogether without a table,
|
|
407
|
+
and `flex: 1 1 0` gives whatever survives the full width without this file
|
|
408
|
+
having to know which combination it got.
|
|
409
|
+
|
|
410
|
+
`.sidebar-action-fancy` is core's, sized to stand alone: full width, its own
|
|
411
|
+
top margin, 12px of side padding. All three are wrong for a button sharing a
|
|
412
|
+
row 288px wide, so they are taken back here -- scoped inside this plugin's
|
|
413
|
+
own row, which is the only place the assumption does not hold. */
|
|
414
|
+
.roi-actions {
|
|
415
|
+
align-items: center;
|
|
416
|
+
display: flex;
|
|
417
|
+
gap: var(--space-2);
|
|
418
|
+
margin-top: 14px;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
.roi-actions .sidebar-action-fancy {
|
|
422
|
+
flex: 1 1 0;
|
|
423
|
+
font-size: 12px;
|
|
424
|
+
gap: 6px;
|
|
425
|
+
letter-spacing: 0;
|
|
426
|
+
margin-top: 0;
|
|
427
|
+
min-width: 0;
|
|
428
|
+
overflow: hidden;
|
|
429
|
+
padding: 0 8px;
|
|
430
|
+
white-space: nowrap;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/* Both labels fit the narrowest sidebar with room to spare, on the fonts this
|
|
434
|
+
app ships. This is for the ones it does not: a label that outgrows its half
|
|
435
|
+
of the row is cut with an ellipsis rather than escaping the button. */
|
|
436
|
+
.roi-actions .sidebar-action-fancy > span:last-child {
|
|
437
|
+
min-width: 0;
|
|
438
|
+
overflow: hidden;
|
|
439
|
+
text-overflow: ellipsis;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/* The ? next to Map to cells. Square, quiet, and the same height as the icon
|
|
443
|
+
buttons elsewhere on the panel -- it explains a button, it does not compete
|
|
444
|
+
with one. */
|
|
445
|
+
.roi-map-info {
|
|
446
|
+
flex: 0 0 auto;
|
|
447
|
+
font-size: 11px;
|
|
448
|
+
height: 26px;
|
|
449
|
+
min-width: 0;
|
|
450
|
+
width: 26px;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
/* -- what Map to cells does --------------------------------------------- */
|
|
454
|
+
|
|
455
|
+
/* A plugin's own dialog rather than core's `.requirements-modal`: that one is
|
|
456
|
+
core's element, rendered from any plugin's requirements, and styling it from
|
|
457
|
+
here would be this plugin reaching into core (tests/test_plugin_css_boundary.py).
|
|
458
|
+
The widths and the backdrop match it on purpose -- a user should not be able
|
|
459
|
+
to tell that two different parts of the app drew these. */
|
|
460
|
+
.roi-modal {
|
|
461
|
+
background: var(--surface-1);
|
|
462
|
+
border: 1px solid var(--border-strong);
|
|
463
|
+
border-radius: var(--radius-lg);
|
|
464
|
+
box-shadow: var(--shadow-lg);
|
|
465
|
+
color: var(--text-primary);
|
|
466
|
+
max-height: 86vh;
|
|
467
|
+
overflow: auto;
|
|
468
|
+
padding: 0;
|
|
469
|
+
width: min(560px, 92vw);
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
.roi-modal::backdrop {
|
|
473
|
+
background: rgba(0, 0, 0, 0.62);
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
.roi-modal-head {
|
|
477
|
+
align-items: center;
|
|
478
|
+
background: var(--surface-1);
|
|
479
|
+
border-bottom: 1px solid var(--border-subtle);
|
|
480
|
+
display: flex;
|
|
481
|
+
gap: var(--space-2);
|
|
482
|
+
justify-content: space-between;
|
|
483
|
+
padding: var(--space-4) var(--space-6);
|
|
484
|
+
/* The body is long enough to scroll, and a heading that scrolls away takes
|
|
485
|
+
with it the only control that closes the thing. */
|
|
486
|
+
position: sticky;
|
|
487
|
+
top: 0;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
.roi-modal-title {
|
|
491
|
+
font-size: 1.05rem;
|
|
492
|
+
font-weight: 600;
|
|
493
|
+
margin: 0;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
.roi-modal-body {
|
|
497
|
+
font-size: 12.5px;
|
|
498
|
+
line-height: 1.6;
|
|
499
|
+
padding: var(--space-4) var(--space-6) var(--space-6);
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
.roi-modal-body p {
|
|
503
|
+
color: var(--text-secondary);
|
|
504
|
+
margin: 0 0 var(--space-3);
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
.roi-modal-body ul {
|
|
508
|
+
color: var(--text-secondary);
|
|
509
|
+
margin: 0 0 var(--space-3);
|
|
510
|
+
padding-left: var(--space-4);
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
.roi-modal-body li {
|
|
514
|
+
margin-bottom: var(--space-1);
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
/* The last line, which is not about how the feature works but about which of
|
|
518
|
+
the two buttons a user wanted. Separated so it does not read as a sixth rule
|
|
519
|
+
of the mapping. */
|
|
520
|
+
.roi-modal-body .roi-modal-aside {
|
|
521
|
+
border-top: 1px solid var(--border-subtle);
|
|
522
|
+
margin-bottom: 0;
|
|
523
|
+
padding-top: var(--space-3);
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
.roi-modal-body code {
|
|
527
|
+
background: rgba(255, 255, 255, 0.08);
|
|
528
|
+
border-radius: 3px;
|
|
529
|
+
font-size: 11.5px;
|
|
530
|
+
padding: 1px 4px;
|
|
531
|
+
/* Column names run to `plexora_rois_category`; in a 560px dialog that is
|
|
532
|
+
fine, at 92vw on a phone it is what breaks the layout. */
|
|
533
|
+
overflow-wrap: anywhere;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
/* The only part of this dialog that is about THIS project rather than about
|
|
537
|
+
the feature: the names the two columns will actually get. Boxed so the eye
|
|
538
|
+
lands on it, and unbulleted because each line already opens with the column
|
|
539
|
+
name set in code -- a bullet in front of that is one marker too many. */
|
|
540
|
+
.roi-modal-body .roi-modal-note {
|
|
541
|
+
background: var(--surface-2);
|
|
542
|
+
border: 1px solid var(--border-subtle);
|
|
543
|
+
border-radius: var(--radius-sm);
|
|
544
|
+
color: var(--text-primary);
|
|
545
|
+
list-style: none;
|
|
546
|
+
padding: var(--space-2) var(--space-3);
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
/* -- status ------------------------------------------------------------- */
|
|
550
|
+
|
|
551
|
+
.roi-status {
|
|
552
|
+
align-items: center;
|
|
553
|
+
color: var(--text-muted);
|
|
554
|
+
display: flex;
|
|
555
|
+
font-size: 11px;
|
|
556
|
+
gap: var(--space-2);
|
|
557
|
+
margin-top: var(--space-3);
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
.roi-status-dot {
|
|
561
|
+
border-radius: 50%;
|
|
562
|
+
flex: 0 0 auto;
|
|
563
|
+
height: 7px;
|
|
564
|
+
width: 7px;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
.roi-status-saved { background: var(--accent-success); }
|
|
568
|
+
.roi-status-saving { background: var(--accent-channel); }
|
|
569
|
+
.roi-status-dirty { background: var(--accent-warning); }
|
|
570
|
+
.roi-status-failed { background: var(--accent-danger); }
|
|
571
|
+
.roi-status-conflict { background: var(--accent-warning); }
|
|
572
|
+
.roi-status-blocked { background: var(--accent-danger); }
|
|
573
|
+
|
|
574
|
+
.roi-message {
|
|
575
|
+
background: var(--surface-2);
|
|
576
|
+
border: 1px solid var(--border-subtle);
|
|
577
|
+
border-radius: var(--radius-sm);
|
|
578
|
+
color: var(--text-secondary);
|
|
579
|
+
font-size: 11px;
|
|
580
|
+
line-height: 1.45;
|
|
581
|
+
margin-top: var(--space-2);
|
|
582
|
+
padding: var(--space-2);
|
|
583
|
+
}
|