plexora 0.0.20__tar.gz → 0.0.22__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.
Files changed (572) hide show
  1. {plexora-0.0.20/plexora.egg-info → plexora-0.0.22}/PKG-INFO +20 -1
  2. {plexora-0.0.20 → plexora-0.0.22}/README.md +19 -0
  3. {plexora-0.0.20 → plexora-0.0.22}/plexora/cli.py +52 -5
  4. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/dist/vendor_bundle.js +1 -1
  5. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/css/main.css +431 -65
  6. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/css/viewer.css +82 -10
  7. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/main.js +6 -14
  8. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/pluginRegistry.js +14 -0
  9. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/services/connectionModal.js +7 -3
  10. plexora-0.0.22/plexora/client/src/js/services/failureMessage.js +139 -0
  11. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/services/keyboardShortcuts.js +3 -1
  12. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/services/remoteGlobe.js +7 -1
  13. plexora-0.0.22/plexora/client/src/js/services/renderClipboard.js +212 -0
  14. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/services/resourceStatus.js +110 -1
  15. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/confirmDialog.js +10 -4
  16. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/datasetNav.js +31 -6
  17. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/importHelp.js +15 -0
  18. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/importSample.js +589 -162
  19. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/layerManager.js +202 -0
  20. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/layerStack.js +40 -3
  21. plexora-0.0.22/plexora/client/src/js/views/pluginHelp.js +116 -0
  22. plexora-0.0.22/plexora/client/src/js/views/popoverMenu.js +129 -0
  23. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/segmentationWait.js +27 -13
  24. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/settingsPage.js +6 -1
  25. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/toolLoader.js +35 -1
  26. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/viewerManager.js +46 -4
  27. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/viewerSidebar.js +41 -3
  28. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/templates/base.html +20 -14
  29. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/templates/index.html +6 -4
  30. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/templates/settings.html +365 -365
  31. {plexora-0.0.20 → plexora-0.0.22}/plexora/connect.py +23 -2
  32. {plexora-0.0.20 → plexora-0.0.22}/plexora/datasets.py +504 -65
  33. {plexora-0.0.20 → plexora-0.0.22}/plexora/datasource.py +2 -0
  34. {plexora-0.0.20 → plexora-0.0.22}/plexora/nodes.py +18 -2
  35. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/cell_explorer/__init__.py +1 -1
  36. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/cell_explorer/static/cell_explorer.css +8 -8
  37. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/templates/figure_builder/workspace.html +1 -1
  38. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/gating/__init__.py +1 -1
  39. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/gating/server/tableops.py +11 -13
  40. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/gating/static/csvGatingList.js +17 -0
  41. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/gating/static/gating.css +27 -1
  42. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/gating/static/gatingSidebarController.js +107 -2
  43. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/roi/__init__.py +1 -1
  44. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/roi/static/roi.css +6 -10
  45. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/transcripts/__init__.py +1 -1
  46. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/transcripts/static/transcripts.css +7 -4
  47. plexora-0.0.22/plexora/plugins/visium_hd/__init__.py +56 -0
  48. plexora-0.0.22/plexora/plugins/visium_hd/server/__init__.py +8 -0
  49. plexora-0.0.22/plexora/plugins/visium_hd/server/routes.py +238 -0
  50. plexora-0.0.22/plexora/plugins/visium_hd/server/tenx.py +132 -0
  51. plexora-0.0.22/plexora/plugins/visium_hd/static/binLayer.js +557 -0
  52. plexora-0.0.22/plexora/plugins/visium_hd/static/visiumHdApi.js +97 -0
  53. plexora-0.0.22/plexora/plugins/visium_hd/static/visiumHdSidebarController.js +840 -0
  54. plexora-0.0.22/plexora/plugins/visium_hd/static/visium_hd.css +360 -0
  55. plexora-0.0.22/plexora/plugins/visium_hd/templates/visium_hd/panel.html +115 -0
  56. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/models/adapters/anndata_adapter.py +184 -1
  57. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/models/adapters/base.py +6 -0
  58. plexora-0.0.22/plexora/server/models/bin_tiles.py +905 -0
  59. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/models/centroid_tiles.py +15 -1
  60. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/models/data_model.py +102 -13
  61. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/models/import_proposal.py +638 -57
  62. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/models/import_sample.py +70 -11
  63. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/models/layer_jobs.py +92 -0
  64. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/models/layer_sources.py +59 -3
  65. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/models/project.py +10 -0
  66. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/node/api.py +39 -3
  67. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/node/app.py +98 -15
  68. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/node/resources.py +16 -0
  69. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/providers/http.py +7 -0
  70. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/providers/local.py +29 -5
  71. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/providers/memory.py +3 -2
  72. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/routes/data_routes.py +191 -13
  73. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/routes/import_routes.py +70 -90
  74. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/utils/boundary_mask.py +134 -0
  75. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/utils/segmentation_pyramid.py +18 -6
  76. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/utils/spatial_scene.py +285 -0
  77. plexora-0.0.22/plexora/server/utils/tenx_matrix.py +640 -0
  78. {plexora-0.0.20 → plexora-0.0.22/plexora.egg-info}/PKG-INFO +20 -1
  79. {plexora-0.0.20 → plexora-0.0.22}/plexora.egg-info/SOURCES.txt +27 -0
  80. {plexora-0.0.20 → plexora-0.0.22}/pyproject.toml +1 -1
  81. plexora-0.0.22/tests/test_bin_tiles.py +278 -0
  82. {plexora-0.0.20 → plexora-0.0.22}/tests/test_cli.py +193 -0
  83. {plexora-0.0.20 → plexora-0.0.22}/tests/test_connect.py +34 -0
  84. {plexora-0.0.20 → plexora-0.0.22}/tests/test_dataset_nav.py +6 -0
  85. {plexora-0.0.20 → plexora-0.0.22}/tests/test_datasets_api.py +7 -2
  86. plexora-0.0.22/tests/test_datasets_api_on_a_node.py +351 -0
  87. plexora-0.0.22/tests/test_import_dialog.py +188 -0
  88. {plexora-0.0.20 → plexora-0.0.22}/tests/test_import_from_a_node.py +44 -0
  89. {plexora-0.0.20 → plexora-0.0.22}/tests/test_import_help.py +9 -2
  90. {plexora-0.0.20 → plexora-0.0.22}/tests/test_import_proposal.py +221 -0
  91. {plexora-0.0.20 → plexora-0.0.22}/tests/test_import_sample_routes.py +93 -0
  92. plexora-0.0.22/tests/test_label_region.py +59 -0
  93. {plexora-0.0.20 → plexora-0.0.22}/tests/test_launch_state.py +14 -0
  94. plexora-0.0.22/tests/test_layer_manager.py +40 -0
  95. {plexora-0.0.20 → plexora-0.0.22}/tests/test_layer_transform.py +20 -0
  96. {plexora-0.0.20 → plexora-0.0.22}/tests/test_node_dynamic.py +200 -10
  97. {plexora-0.0.20 → plexora-0.0.22}/tests/test_node_image_type.py +5 -4
  98. plexora-0.0.22/tests/test_node_mask_status.py +116 -0
  99. {plexora-0.0.20 → plexora-0.0.22}/tests/test_node_table.py +3 -2
  100. {plexora-0.0.20 → plexora-0.0.22}/tests/test_plugin_boundary.py +32 -1
  101. plexora-0.0.22/tests/test_popover_menu.py +55 -0
  102. {plexora-0.0.20 → plexora-0.0.22}/tests/test_popover_portal.py +1 -0
  103. plexora-0.0.22/tests/test_rename_channels_json.py +93 -0
  104. plexora-0.0.22/tests/test_render_clipboard.py +61 -0
  105. plexora-0.0.22/tests/test_tenx_matrix.py +165 -0
  106. plexora-0.0.22/tests/test_visium_hd_import.py +293 -0
  107. plexora-0.0.22/tests/test_wide_features.py +134 -0
  108. {plexora-0.0.20 → plexora-0.0.22}/LICENSE +0 -0
  109. {plexora-0.0.20 → plexora-0.0.22}/MANIFEST.in +0 -0
  110. {plexora-0.0.20 → plexora-0.0.22}/plexora/__init__.py +0 -0
  111. {plexora-0.0.20 → plexora-0.0.22}/plexora/__main__.py +0 -0
  112. {plexora-0.0.20 → plexora-0.0.22}/plexora/_resources.py +0 -0
  113. {plexora-0.0.20 → plexora-0.0.22}/plexora/_transient_locks.py +0 -0
  114. {plexora-0.0.20 → plexora-0.0.22}/plexora/_url.py +0 -0
  115. {plexora-0.0.20 → plexora-0.0.22}/plexora/api/__init__.py +0 -0
  116. {plexora-0.0.20 → plexora-0.0.22}/plexora/api/dataset.py +0 -0
  117. {plexora-0.0.20 → plexora-0.0.22}/plexora/api/http.py +0 -0
  118. {plexora-0.0.20 → plexora-0.0.22}/plexora/api/plugin.py +0 -0
  119. {plexora-0.0.20 → plexora-0.0.22}/plexora/api/store.py +0 -0
  120. {plexora-0.0.20 → plexora-0.0.22}/plexora/askpass.py +0 -0
  121. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/dist/354_bundle.js +0 -0
  122. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/dist/354_bundle.js.LICENSE.txt +0 -0
  123. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/dist/418_bundle.js +0 -0
  124. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/dist/418_bundle.js.LICENSE.txt +0 -0
  125. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/dist/693b935cb1f907814be9c6199a68c217.svg +0 -0
  126. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/dist/713c134ff47cd328a5b711526f151082.svg +0 -0
  127. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/dist/770_bundle.js +0 -0
  128. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/dist/ff743f408972e0e96ca9153ed5ae4c83.svg +0 -0
  129. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/dist/vendor_bundle.js.LICENSE.txt +0 -0
  130. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/dist/vendors-node_modules_canvg_lib_index_es_js_bundle.js +0 -0
  131. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/dist/vendors-node_modules_dompurify_dist_purify_es_mjs_bundle.js +0 -0
  132. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/dist/vendors-node_modules_html2canvas_dist_html2canvas_js_bundle.js +0 -0
  133. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/LICENSE.txt +0 -0
  134. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/canvas-overlay-hd.js +0 -0
  135. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/changelog.txt +0 -0
  136. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/.gitattributes +0 -0
  137. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/LICENSE.txt +0 -0
  138. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/Toolbar.png +0 -0
  139. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/fullpage.psd +0 -0
  140. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/home.psd +0 -0
  141. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/next.psd +0 -0
  142. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/previous.psd +0 -0
  143. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/rotateleft.psd +0 -0
  144. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/rotateright.psd +0 -0
  145. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/zoom.psd +0 -0
  146. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/README.md +0 -0
  147. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/fullpage_grouphover.png +0 -0
  148. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/fullpage_hover.png +0 -0
  149. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/fullpage_pressed.png +0 -0
  150. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/fullpage_rest.png +0 -0
  151. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/home_grouphover.png +0 -0
  152. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/home_hover.png +0 -0
  153. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/home_pressed.png +0 -0
  154. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/home_rest.png +0 -0
  155. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/next_grouphover.png +0 -0
  156. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/next_hover.png +0 -0
  157. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/next_pressed.png +0 -0
  158. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/next_rest.png +0 -0
  159. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/previous_grouphover.png +0 -0
  160. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/previous_hover.png +0 -0
  161. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/previous_pressed.png +0 -0
  162. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/previous_rest.png +0 -0
  163. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateleft_grouphover.png +0 -0
  164. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateleft_hover.png +0 -0
  165. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateleft_pressed.png +0 -0
  166. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateleft_rest.png +0 -0
  167. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateright_grouphover.png +0 -0
  168. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateright_hover.png +0 -0
  169. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateright_pressed.png +0 -0
  170. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateright_rest.png +0 -0
  171. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomin_grouphover.png +0 -0
  172. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomin_hover.png +0 -0
  173. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomin_pressed.png +0 -0
  174. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomin_rest.png +0 -0
  175. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomout_grouphover.png +0 -0
  176. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomout_hover.png +0 -0
  177. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomout_pressed.png +0 -0
  178. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomout_rest.png +0 -0
  179. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-scalebar.js +0 -0
  180. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/css/import.css +0 -0
  181. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/css/openProject.css +0 -0
  182. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/css/quickView.css +0 -0
  183. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/css/settings.css +0 -0
  184. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/css/tokens.css +0 -0
  185. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/img/apple-touch-icon.png +0 -0
  186. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/img/favicon.ico +0 -0
  187. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/img/logo.ai +0 -0
  188. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/img/logo.svg +0 -0
  189. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/img/logo_with_text.ai +0 -0
  190. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/img/logo_with_text.svg +0 -0
  191. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/services/appRouter.js +0 -0
  192. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/services/appStatus.js +0 -0
  193. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/services/browsePicker.js +0 -0
  194. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/services/carryOver.js +0 -0
  195. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/services/dataLayer.js +0 -0
  196. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/services/dataLocation.js +0 -0
  197. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/services/datasetContext.js +0 -0
  198. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/services/fileLocation.js +0 -0
  199. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/services/glRenderer.js +0 -0
  200. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/services/logTerminal.js +0 -0
  201. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/services/numericData.js +0 -0
  202. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/services/pageBoot.js +0 -0
  203. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/services/passVariablesToFrontend.js +0 -0
  204. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/services/pathPicker.js +0 -0
  205. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/services/placePicker.js +0 -0
  206. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/services/remoteState.js +0 -0
  207. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/services/resourceRouting.js +0 -0
  208. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/services/sessionExpiry.js +0 -0
  209. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/services/simpleEventHandler.js +0 -0
  210. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/services/toast.js +0 -0
  211. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/services/viewerLoader.js +0 -0
  212. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/vendor.js +0 -0
  213. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/brightfieldAdjust.js +0 -0
  214. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/cardList.js +0 -0
  215. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/channelList.js +0 -0
  216. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/channelNamesUpload.js +0 -0
  217. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/colorSwatchPicker.js +0 -0
  218. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/columnClassifier.js +0 -0
  219. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/coordinateField.js +0 -0
  220. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/dataSourceField.js +0 -0
  221. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/datasetPicker.js +0 -0
  222. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/fileSourceRow.js +0 -0
  223. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/glInit.js +0 -0
  224. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/gradientRange.js +0 -0
  225. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/imageViewer.js +0 -0
  226. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/jobProgress.js +0 -0
  227. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/labelTile.js +0 -0
  228. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/layerChannelPanel.js +0 -0
  229. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/layerSections.js +0 -0
  230. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/miniMap.js +0 -0
  231. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/navbarControls.js +0 -0
  232. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/openProjectPage.js +0 -0
  233. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/panCursor.js +0 -0
  234. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/popoverPortal.js +0 -0
  235. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/projectEdit.js +0 -0
  236. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/quickViewLanding.js +0 -0
  237. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/rainbow.js +0 -0
  238. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/requirementsModal.js +0 -0
  239. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/rgbImageViewer.js +0 -0
  240. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/scaleCalibration.js +0 -0
  241. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/searchableSelect.js +0 -0
  242. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/slider.js +0 -0
  243. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/tableProgress.js +0 -0
  244. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/tileColorize.js +0 -0
  245. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/tileDecode.js +0 -0
  246. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/viewerControls.js +0 -0
  247. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/views/viewerErrorState.js +0 -0
  248. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/js/workers/tileDecoder.js +0 -0
  249. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/shaders/frag.glsl +0 -0
  250. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/src/shaders/vert.glsl +0 -0
  251. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/templates/_fragment.html +0 -0
  252. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/templates/_scale_calibration.html +0 -0
  253. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/templates/_scale_calibration_float.html +0 -0
  254. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/templates/open_project.html +0 -0
  255. {plexora-0.0.20 → plexora-0.0.22}/plexora/client/templates/project_edit.html +0 -0
  256. {plexora-0.0.20 → plexora-0.0.22}/plexora/gcloud.py +0 -0
  257. {plexora-0.0.20 → plexora-0.0.22}/plexora/jupyter.py +0 -0
  258. {plexora-0.0.20 → plexora-0.0.22}/plexora/memory.py +0 -0
  259. {plexora-0.0.20 → plexora-0.0.22}/plexora/notebook_env.py +0 -0
  260. {plexora-0.0.20 → plexora-0.0.22}/plexora/paths.py +0 -0
  261. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/__init__.py +0 -0
  262. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/cell_explorer/server/__init__.py +0 -0
  263. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/cell_explorer/server/routes.py +0 -0
  264. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/cell_explorer/server/state.py +0 -0
  265. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/cell_explorer/server/values.py +0 -0
  266. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/cell_explorer/server/variables.py +0 -0
  267. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/cell_explorer/static/cellExplorerApi.js +0 -0
  268. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/cell_explorer/static/cellExplorerColors.js +0 -0
  269. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/cell_explorer/static/cellExplorerContinuous.js +0 -0
  270. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/cell_explorer/static/cellExplorerFigureBridge.js +0 -0
  271. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/cell_explorer/static/cellExplorerLegend.js +0 -0
  272. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/cell_explorer/static/cellExplorerRoiBridge.js +0 -0
  273. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/cell_explorer/static/cellExplorerSidebarController.js +0 -0
  274. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/cell_explorer/static/cellExplorerState.js +0 -0
  275. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/cell_explorer/templates/cell_explorer/panel.html +0 -0
  276. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/__init__.py +0 -0
  277. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/server/__init__.py +0 -0
  278. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/server/captures.py +0 -0
  279. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/server/compose.py +0 -0
  280. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/server/export.py +0 -0
  281. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/server/export_jobs.py +0 -0
  282. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/server/operations.py +0 -0
  283. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/server/pixels.py +0 -0
  284. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/server/provenance.py +0 -0
  285. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/server/render.py +0 -0
  286. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/server/repository.py +0 -0
  287. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/server/routes.py +0 -0
  288. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/server/schema.py +0 -0
  289. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/server/shapegeom.py +0 -0
  290. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/server/sources.py +0 -0
  291. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/server/strokegeom.py +0 -0
  292. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/server/textmetrics.py +0 -0
  293. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figureActions.js +0 -0
  294. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figureBuilderApi.js +0 -0
  295. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figureCanvas.js +0 -0
  296. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figureCaptureBin.js +0 -0
  297. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figureCaptureBinGrid.js +0 -0
  298. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figureCaptureBoxes.js +0 -0
  299. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figureCaptureDock.js +0 -0
  300. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figureCaptureTool.js +0 -0
  301. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figureChoiceField.js +0 -0
  302. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figureColorField.js +0 -0
  303. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figureConfirm.js +0 -0
  304. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figureContextBar.js +0 -0
  305. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figureContextMenu.js +0 -0
  306. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figureDestinationPicker.js +0 -0
  307. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figureDocumentState.js +0 -0
  308. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figureExportUi.js +0 -0
  309. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figureImagePanel.js +0 -0
  310. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figureLibrary.js +0 -0
  311. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figureLineDefs.js +0 -0
  312. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figureLinePanel.js +0 -0
  313. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figurePanelCompositor.js +0 -0
  314. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figurePointEditor.js +0 -0
  315. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figureQuickEdit.js +0 -0
  316. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figureRichText.js +0 -0
  317. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figureSceneSnapshot.js +0 -0
  318. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figureSchema.js +0 -0
  319. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figureShapeDefs.js +0 -0
  320. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figureShapeDrawing.js +0 -0
  321. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figureShapeGeometry.js +0 -0
  322. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figureShapePanel.js +0 -0
  323. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figureSidebarController.js +0 -0
  324. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figureStrokeGeometry.js +0 -0
  325. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figureTextEditor.js +0 -0
  326. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figureTextPanel.js +0 -0
  327. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figureThumbnail.js +0 -0
  328. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figureViewOptions.js +0 -0
  329. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figureWorkspace.js +0 -0
  330. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/static/figure_builder.css +0 -0
  331. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/templates/figure_builder/captures.html +0 -0
  332. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/templates/figure_builder/library.html +0 -0
  333. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/figure_builder/templates/figure_builder/workspace_body.html +0 -0
  334. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/gating/server/__init__.py +0 -0
  335. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/gating/server/anndata_gates.py +0 -0
  336. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/gating/server/database.py +0 -0
  337. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/gating/server/model.py +0 -0
  338. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/gating/server/routes.py +0 -0
  339. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/gating/static/gatingApi.js +0 -0
  340. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/gating/templates/gating/legacy.html +0 -0
  341. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/gating/templates/gating/panel.html +0 -0
  342. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/roi/server/__init__.py +0 -0
  343. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/roi/server/adapters.py +0 -0
  344. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/roi/server/geojson.py +0 -0
  345. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/roi/server/geometry.py +0 -0
  346. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/roi/server/mapping.py +0 -0
  347. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/roi/server/operations.py +0 -0
  348. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/roi/server/repository.py +0 -0
  349. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/roi/server/routes.py +0 -0
  350. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/roi/server/schema.py +0 -0
  351. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/roi/server/tableops.py +0 -0
  352. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/roi/static/roiApi.js +0 -0
  353. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/roi/static/roiFigureBridge.js +0 -0
  354. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/roi/static/roiGeometry.js +0 -0
  355. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/roi/static/roiRenderer.js +0 -0
  356. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/roi/static/roiSidebarController.js +0 -0
  357. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/roi/static/roiState.js +0 -0
  358. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/roi/static/roiTools.js +0 -0
  359. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/roi/static/roiTree.js +0 -0
  360. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/roi/templates/roi/panel.html +0 -0
  361. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/transcripts/server/__init__.py +0 -0
  362. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/transcripts/server/routes.py +0 -0
  363. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/transcripts/server/xenium.py +0 -0
  364. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/transcripts/static/transcriptGroupModal.js +0 -0
  365. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/transcripts/static/transcriptLayer.js +0 -0
  366. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/transcripts/static/transcriptPoints.js +0 -0
  367. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/transcripts/static/transcriptsApi.js +0 -0
  368. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/transcripts/static/transcriptsSidebarController.js +0 -0
  369. {plexora-0.0.20 → plexora-0.0.22}/plexora/plugins/transcripts/templates/transcripts/panel.html +0 -0
  370. {plexora-0.0.20 → plexora-0.0.22}/plexora/proxy.py +0 -0
  371. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/models/adapters/__init__.py +0 -0
  372. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/models/adapters/classify.py +0 -0
  373. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/models/adapters/csv_adapter.py +0 -0
  374. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/models/adapters/flat_table.py +0 -0
  375. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/models/adapters/inspection.py +0 -0
  376. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/models/adapters/memory_adapter.py +0 -0
  377. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/models/adapters/spatialdata_adapter.py +0 -0
  378. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/models/consistency.py +0 -0
  379. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/models/data_migration.py +0 -0
  380. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/models/database_model.py +0 -0
  381. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/models/datasets.py +0 -0
  382. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/models/manifest.py +0 -0
  383. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/models/nodes.py +0 -0
  384. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/models/recipes.py +0 -0
  385. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/models/remote_sessions.py +0 -0
  386. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/models/remotes.py +0 -0
  387. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/models/secret_store.py +0 -0
  388. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/models/transcript_tiles.py +0 -0
  389. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/plugins.py +0 -0
  390. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/providers/__init__.py +0 -0
  391. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/providers/base.py +0 -0
  392. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/providers/node.py +0 -0
  393. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/providers/operations.py +0 -0
  394. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/providers/wire.py +0 -0
  395. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/routes/browse_routes.py +0 -0
  396. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/routes/dataset_routes.py +0 -0
  397. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/routes/gcloud_routes.py +0 -0
  398. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/routes/page_routes.py +0 -0
  399. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/routes/project_routes.py +0 -0
  400. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/routes/settings_routes.py +0 -0
  401. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/routes/system_routes.py +0 -0
  402. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/routes/tool_routes.py +0 -0
  403. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/routes/transfer_routes.py +0 -0
  404. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/utils/addHEColumns.py +0 -0
  405. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/utils/brightfield.py +0 -0
  406. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/utils/channel_file.py +0 -0
  407. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/utils/colormaps.py +0 -0
  408. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/utils/dicom_wsi.py +0 -0
  409. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/utils/dir_listing.py +0 -0
  410. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/utils/fast_png.py +0 -0
  411. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/utils/file_transfer.py +0 -0
  412. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/utils/fullConversion.py +0 -0
  413. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/utils/memory_pyramid.py +0 -0
  414. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/utils/native_dialog.py +0 -0
  415. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/utils/ngff_transform.py +0 -0
  416. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/utils/ome_zarr.py +0 -0
  417. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/utils/pre_normalization.py +0 -0
  418. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/utils/smallestenclosingcircle.py +0 -0
  419. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/utils/tiff_series.py +0 -0
  420. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/utils/tiffsurgeon.py +0 -0
  421. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/utils/xenium_cells.py +0 -0
  422. {plexora-0.0.20 → plexora-0.0.22}/plexora/server/utils/xenium_focus.py +0 -0
  423. {plexora-0.0.20 → plexora-0.0.22}/plexora/server_cli.py +0 -0
  424. {plexora-0.0.20 → plexora-0.0.22}/plexora/test.py +0 -0
  425. {plexora-0.0.20 → plexora-0.0.22}/plexora.egg-info/dependency_links.txt +0 -0
  426. {plexora-0.0.20 → plexora-0.0.22}/plexora.egg-info/entry_points.txt +0 -0
  427. {plexora-0.0.20 → plexora-0.0.22}/plexora.egg-info/requires.txt +0 -0
  428. {plexora-0.0.20 → plexora-0.0.22}/plexora.egg-info/top_level.txt +0 -0
  429. {plexora-0.0.20 → plexora-0.0.22}/setup.cfg +0 -0
  430. {plexora-0.0.20 → plexora-0.0.22}/tests/test_anndata_adapter.py +0 -0
  431. {plexora-0.0.20 → plexora-0.0.22}/tests/test_api_dataset.py +0 -0
  432. {plexora-0.0.20 → plexora-0.0.22}/tests/test_api_store.py +0 -0
  433. {plexora-0.0.20 → plexora-0.0.22}/tests/test_app_router.py +0 -0
  434. {plexora-0.0.20 → plexora-0.0.22}/tests/test_app_shell.py +0 -0
  435. {plexora-0.0.20 → plexora-0.0.22}/tests/test_auth_token.py +0 -0
  436. {plexora-0.0.20 → plexora-0.0.22}/tests/test_blank_frame.py +0 -0
  437. {plexora-0.0.20 → plexora-0.0.22}/tests/test_boundary_mask.py +0 -0
  438. {plexora-0.0.20 → plexora-0.0.22}/tests/test_brightfield_detection.py +0 -0
  439. {plexora-0.0.20 → plexora-0.0.22}/tests/test_brightfield_pipeline.py +0 -0
  440. {plexora-0.0.20 → plexora-0.0.22}/tests/test_brightfield_reader.py +0 -0
  441. {plexora-0.0.20 → plexora-0.0.22}/tests/test_brightfield_routes.py +0 -0
  442. {plexora-0.0.20 → plexora-0.0.22}/tests/test_browse_routes.py +0 -0
  443. {plexora-0.0.20 → plexora-0.0.22}/tests/test_carry_over.py +0 -0
  444. {plexora-0.0.20 → plexora-0.0.22}/tests/test_cell_color_layer.py +0 -0
  445. {plexora-0.0.20 → plexora-0.0.22}/tests/test_cell_mode_control.py +0 -0
  446. {plexora-0.0.20 → plexora-0.0.22}/tests/test_centroid_tiles.py +0 -0
  447. {plexora-0.0.20 → plexora-0.0.22}/tests/test_channel_auto_revert.py +0 -0
  448. {plexora-0.0.20 → plexora-0.0.22}/tests/test_channel_names_modal.py +0 -0
  449. {plexora-0.0.20 → plexora-0.0.22}/tests/test_channel_names_sidecar.py +0 -0
  450. {plexora-0.0.20 → plexora-0.0.22}/tests/test_channel_names_upload.py +0 -0
  451. {plexora-0.0.20 → plexora-0.0.22}/tests/test_channel_overview.py +0 -0
  452. {plexora-0.0.20 → plexora-0.0.22}/tests/test_channel_rename_state.py +0 -0
  453. {plexora-0.0.20 → plexora-0.0.22}/tests/test_classify_columns.py +0 -0
  454. {plexora-0.0.20 → plexora-0.0.22}/tests/test_colormaps.py +0 -0
  455. {plexora-0.0.20 → plexora-0.0.22}/tests/test_column_classifier_css.py +0 -0
  456. {plexora-0.0.20 → plexora-0.0.22}/tests/test_config_store.py +0 -0
  457. {plexora-0.0.20 → plexora-0.0.22}/tests/test_connection_modal.py +0 -0
  458. {plexora-0.0.20 → plexora-0.0.22}/tests/test_consistency.py +0 -0
  459. {plexora-0.0.20 → plexora-0.0.22}/tests/test_csv_adapter.py +0 -0
  460. {plexora-0.0.20 → plexora-0.0.22}/tests/test_data_location.py +0 -0
  461. {plexora-0.0.20 → plexora-0.0.22}/tests/test_database_model.py +0 -0
  462. {plexora-0.0.20 → plexora-0.0.22}/tests/test_datalayer_requests.py +0 -0
  463. {plexora-0.0.20 → plexora-0.0.22}/tests/test_dataset_routes.py +0 -0
  464. {plexora-0.0.20 → plexora-0.0.22}/tests/test_datasets_registry.py +0 -0
  465. {plexora-0.0.20 → plexora-0.0.22}/tests/test_derive_anndata_channel_names.py +0 -0
  466. {plexora-0.0.20 → plexora-0.0.22}/tests/test_detect_data_type.py +0 -0
  467. {plexora-0.0.20 → plexora-0.0.22}/tests/test_dicom_assembly.py +0 -0
  468. {plexora-0.0.20 → plexora-0.0.22}/tests/test_dicom_detection.py +0 -0
  469. {plexora-0.0.20 → plexora-0.0.22}/tests/test_dicom_pyramid.py +0 -0
  470. {plexora-0.0.20 → plexora-0.0.22}/tests/test_dicom_registration.py +0 -0
  471. {plexora-0.0.20 → plexora-0.0.22}/tests/test_dicom_routes.py +0 -0
  472. {plexora-0.0.20 → plexora-0.0.22}/tests/test_file_location.py +0 -0
  473. {plexora-0.0.20 → plexora-0.0.22}/tests/test_file_transfer_node.py +0 -0
  474. {plexora-0.0.20 → plexora-0.0.22}/tests/test_gcloud.py +0 -0
  475. {plexora-0.0.20 → plexora-0.0.22}/tests/test_hd_slider_domain.py +0 -0
  476. {plexora-0.0.20 → plexora-0.0.22}/tests/test_home_landing.py +0 -0
  477. {plexora-0.0.20 → plexora-0.0.22}/tests/test_icon_names.py +0 -0
  478. {plexora-0.0.20 → plexora-0.0.22}/tests/test_image_status.py +0 -0
  479. {plexora-0.0.20 → plexora-0.0.22}/tests/test_import_costs_nothing.py +0 -0
  480. {plexora-0.0.20 → plexora-0.0.22}/tests/test_import_entry_points.py +0 -0
  481. {plexora-0.0.20 → plexora-0.0.22}/tests/test_jupyter_viewer.py +0 -0
  482. {plexora-0.0.20 → plexora-0.0.22}/tests/test_label_outlines.py +0 -0
  483. {plexora-0.0.20 → plexora-0.0.22}/tests/test_label_tile_lifecycle.py +0 -0
  484. {plexora-0.0.20 → plexora-0.0.22}/tests/test_layer_channel_panel.py +0 -0
  485. {plexora-0.0.20 → plexora-0.0.22}/tests/test_layer_draw.py +0 -0
  486. {plexora-0.0.20 → plexora-0.0.22}/tests/test_layer_jobs.py +0 -0
  487. {plexora-0.0.20 → plexora-0.0.22}/tests/test_layer_sources.py +0 -0
  488. {plexora-0.0.20 → plexora-0.0.22}/tests/test_layer_spec.py +0 -0
  489. {plexora-0.0.20 → plexora-0.0.22}/tests/test_layer_state.py +0 -0
  490. {plexora-0.0.20 → plexora-0.0.22}/tests/test_layer_visibility.py +0 -0
  491. {plexora-0.0.20 → plexora-0.0.22}/tests/test_manifest.py +0 -0
  492. {plexora-0.0.20 → plexora-0.0.22}/tests/test_marker_split.py +0 -0
  493. {plexora-0.0.20 → plexora-0.0.22}/tests/test_mask_without_table.py +0 -0
  494. {plexora-0.0.20 → plexora-0.0.22}/tests/test_memory_adapter.py +0 -0
  495. {plexora-0.0.20 → plexora-0.0.22}/tests/test_memory_datasource.py +0 -0
  496. {plexora-0.0.20 → plexora-0.0.22}/tests/test_memory_pyramid.py +0 -0
  497. {plexora-0.0.20 → plexora-0.0.22}/tests/test_metadata_columns.py +0 -0
  498. {plexora-0.0.20 → plexora-0.0.22}/tests/test_mini_map.py +0 -0
  499. {plexora-0.0.20 → plexora-0.0.22}/tests/test_nav_shortcuts.py +0 -0
  500. {plexora-0.0.20 → plexora-0.0.22}/tests/test_node_direct_routing.py +0 -0
  501. {plexora-0.0.20 → plexora-0.0.22}/tests/test_node_disconnect.py +0 -0
  502. {plexora-0.0.20 → plexora-0.0.22}/tests/test_node_image.py +0 -0
  503. {plexora-0.0.20 → plexora-0.0.22}/tests/test_node_reconnect.py +0 -0
  504. {plexora-0.0.20 → plexora-0.0.22}/tests/test_node_routes.py +0 -0
  505. {plexora-0.0.20 → plexora-0.0.22}/tests/test_node_warm_and_cache.py +0 -0
  506. {plexora-0.0.20 → plexora-0.0.22}/tests/test_notebook_env.py +0 -0
  507. {plexora-0.0.20 → plexora-0.0.22}/tests/test_notebook_mode.py +0 -0
  508. {plexora-0.0.20 → plexora-0.0.22}/tests/test_ome_zarr_reader.py +0 -0
  509. {plexora-0.0.20 → plexora-0.0.22}/tests/test_open_project.py +0 -0
  510. {plexora-0.0.20 → plexora-0.0.22}/tests/test_optional_segmentation.py +0 -0
  511. {plexora-0.0.20 → plexora-0.0.22}/tests/test_page_assets.py +0 -0
  512. {plexora-0.0.20 → plexora-0.0.22}/tests/test_page_routes.py +0 -0
  513. {plexora-0.0.20 → plexora-0.0.22}/tests/test_parquet_tables.py +0 -0
  514. {plexora-0.0.20 → plexora-0.0.22}/tests/test_path_picker.py +0 -0
  515. {plexora-0.0.20 → plexora-0.0.22}/tests/test_paths.py +0 -0
  516. {plexora-0.0.20 → plexora-0.0.22}/tests/test_pixel_size.py +0 -0
  517. {plexora-0.0.20 → plexora-0.0.22}/tests/test_plugin_css_boundary.py +0 -0
  518. {plexora-0.0.20 → plexora-0.0.22}/tests/test_plugin_layers.py +0 -0
  519. {plexora-0.0.20 → plexora-0.0.22}/tests/test_plugins.py +0 -0
  520. {plexora-0.0.20 → plexora-0.0.22}/tests/test_prime_hot_code.py +0 -0
  521. {plexora-0.0.20 → plexora-0.0.22}/tests/test_project_edit_routes.py +0 -0
  522. {plexora-0.0.20 → plexora-0.0.22}/tests/test_project_layer_routes.py +0 -0
  523. {plexora-0.0.20 → plexora-0.0.22}/tests/test_project_record.py +0 -0
  524. {plexora-0.0.20 → plexora-0.0.22}/tests/test_recipes.py +0 -0
  525. {plexora-0.0.20 → plexora-0.0.22}/tests/test_reconnect.py +0 -0
  526. {plexora-0.0.20 → plexora-0.0.22}/tests/test_refresh_dataset.py +0 -0
  527. {plexora-0.0.20 → plexora-0.0.22}/tests/test_register_anndata_datasource.py +0 -0
  528. {plexora-0.0.20 → plexora-0.0.22}/tests/test_register_image_datasource.py +0 -0
  529. {plexora-0.0.20 → plexora-0.0.22}/tests/test_register_zarr_image_datasource.py +0 -0
  530. {plexora-0.0.20 → plexora-0.0.22}/tests/test_remote_connect.py +0 -0
  531. {plexora-0.0.20 → plexora-0.0.22}/tests/test_remote_globe.py +0 -0
  532. {plexora-0.0.20 → plexora-0.0.22}/tests/test_remote_health.py +0 -0
  533. {plexora-0.0.20 → plexora-0.0.22}/tests/test_remote_state.py +0 -0
  534. {plexora-0.0.20 → plexora-0.0.22}/tests/test_rename_channels.py +0 -0
  535. {plexora-0.0.20 → plexora-0.0.22}/tests/test_requirements_routes.py +0 -0
  536. {plexora-0.0.20 → plexora-0.0.22}/tests/test_resource_status_banner.py +0 -0
  537. {plexora-0.0.20 → plexora-0.0.22}/tests/test_segmentation_mapping.py +0 -0
  538. {plexora-0.0.20 → plexora-0.0.22}/tests/test_segmentation_mode_routes.py +0 -0
  539. {plexora-0.0.20 → plexora-0.0.22}/tests/test_segmentation_pyramid.py +0 -0
  540. {plexora-0.0.20 → plexora-0.0.22}/tests/test_segmentation_wait.py +0 -0
  541. {plexora-0.0.20 → plexora-0.0.22}/tests/test_session_expiry.py +0 -0
  542. {plexora-0.0.20 → plexora-0.0.22}/tests/test_session_walltime.py +0 -0
  543. {plexora-0.0.20 → plexora-0.0.22}/tests/test_settings_page.py +0 -0
  544. {plexora-0.0.20 → plexora-0.0.22}/tests/test_settings_remotes_page.py +0 -0
  545. {plexora-0.0.20 → plexora-0.0.22}/tests/test_shared_roots.py +0 -0
  546. {plexora-0.0.20 → plexora-0.0.22}/tests/test_sidebar_scoping.py +0 -0
  547. {plexora-0.0.20 → plexora-0.0.22}/tests/test_single_image_import.py +0 -0
  548. {plexora-0.0.20 → plexora-0.0.22}/tests/test_slider.py +0 -0
  549. {plexora-0.0.20 → plexora-0.0.22}/tests/test_slider_css.py +0 -0
  550. {plexora-0.0.20 → plexora-0.0.22}/tests/test_spatial_scene.py +0 -0
  551. {plexora-0.0.20 → plexora-0.0.22}/tests/test_spatialdata_adapter.py +0 -0
  552. {plexora-0.0.20 → plexora-0.0.22}/tests/test_spatialdata_image_import.py +0 -0
  553. {plexora-0.0.20 → plexora-0.0.22}/tests/test_staged_progress.py +0 -0
  554. {plexora-0.0.20 → plexora-0.0.22}/tests/test_table_progress.py +0 -0
  555. {plexora-0.0.20 → plexora-0.0.22}/tests/test_tiff_hyperstack.py +0 -0
  556. {plexora-0.0.20 → plexora-0.0.22}/tests/test_tile_colorize.py +0 -0
  557. {plexora-0.0.20 → plexora-0.0.22}/tests/test_tile_url.py +0 -0
  558. {plexora-0.0.20 → plexora-0.0.22}/tests/test_toast.py +0 -0
  559. {plexora-0.0.20 → plexora-0.0.22}/tests/test_tool_assets.py +0 -0
  560. {plexora-0.0.20 → plexora-0.0.22}/tests/test_tool_cards.py +0 -0
  561. {plexora-0.0.20 → plexora-0.0.22}/tests/test_tool_coexistence.py +0 -0
  562. {plexora-0.0.20 → plexora-0.0.22}/tests/test_tool_switching.py +0 -0
  563. {plexora-0.0.20 → plexora-0.0.22}/tests/test_transcript_tiles.py +0 -0
  564. {plexora-0.0.20 → plexora-0.0.22}/tests/test_transfer_routes.py +0 -0
  565. {plexora-0.0.20 → plexora-0.0.22}/tests/test_unreachable_node.py +0 -0
  566. {plexora-0.0.20 → plexora-0.0.22}/tests/test_url_helpers.py +0 -0
  567. {plexora-0.0.20 → plexora-0.0.22}/tests/test_view_menu.py +0 -0
  568. {plexora-0.0.20 → plexora-0.0.22}/tests/test_viewer_error_state.py +0 -0
  569. {plexora-0.0.20 → plexora-0.0.22}/tests/test_viewer_loader.py +0 -0
  570. {plexora-0.0.20 → plexora-0.0.22}/tests/test_xenium_cells.py +0 -0
  571. {plexora-0.0.20 → plexora-0.0.22}/tests/test_xenium_focus.py +0 -0
  572. {plexora-0.0.20 → plexora-0.0.22}/tests/test_zarr_write_retry.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plexora
3
- Version: 0.0.20
3
+ Version: 0.0.22
4
4
  Summary: OpenSeadragon-based cellular image viewing and analysis tool.
5
5
  License-Expression: LicenseRef-Plexora-Academic-1.0
6
6
  Requires-Python: <3.14,>=3.12
@@ -191,12 +191,31 @@ plexora.configure_project("sample2", data="sample2.csv", cell_id="CellID")
191
191
  plexora.project_manifest("sample2") # what it has, and what is still open
192
192
  ```
193
193
 
194
+ Files do not all have to be on the same machine. `node` names a data node you
195
+ are connected to, and any field can say otherwise for itself -- so a cohort
196
+ whose slides sit on a cluster and whose quantification sits on your laptop is
197
+ one document:
198
+
199
+ ```python
200
+ plexora.create_dataset("Melanoma Cohort", node="hms-o2", projects=[
201
+ {"image": "/n/scratch/reg/sample1.ome.tif",
202
+ "segmentation": "/n/scratch/seg/sample1.tif",
203
+ "data": {"path": "C:/quant/sample1.csv", "node": None}},
204
+ {"image": "/n/scratch/reg/sample2.ome.tif"},
205
+ ])
206
+ ```
207
+
208
+ The projects are registered here, so they appear in the Samples page like any
209
+ other; the bytes stay where they are and are read through the node.
210
+
194
211
  The same options exist as flags:
195
212
 
196
213
  ```bash
197
214
  plexora project create slide.ome.tif --data cells.csv --cell-id CellID \
198
215
  --markers CD3 CD8 --dataset melanoma_cohort
199
216
  plexora project show slide # every question, and whether it is answered
217
+
218
+ plexora dataset create "Melanoma Cohort" --from projects.json --node hms-o2
200
219
  ```
201
220
 
202
221
  ### Shared projects
@@ -140,12 +140,31 @@ plexora.configure_project("sample2", data="sample2.csv", cell_id="CellID")
140
140
  plexora.project_manifest("sample2") # what it has, and what is still open
141
141
  ```
142
142
 
143
+ Files do not all have to be on the same machine. `node` names a data node you
144
+ are connected to, and any field can say otherwise for itself -- so a cohort
145
+ whose slides sit on a cluster and whose quantification sits on your laptop is
146
+ one document:
147
+
148
+ ```python
149
+ plexora.create_dataset("Melanoma Cohort", node="hms-o2", projects=[
150
+ {"image": "/n/scratch/reg/sample1.ome.tif",
151
+ "segmentation": "/n/scratch/seg/sample1.tif",
152
+ "data": {"path": "C:/quant/sample1.csv", "node": None}},
153
+ {"image": "/n/scratch/reg/sample2.ome.tif"},
154
+ ])
155
+ ```
156
+
157
+ The projects are registered here, so they appear in the Samples page like any
158
+ other; the bytes stay where they are and are read through the node.
159
+
143
160
  The same options exist as flags:
144
161
 
145
162
  ```bash
146
163
  plexora project create slide.ome.tif --data cells.csv --cell-id CellID \
147
164
  --markers CD3 CD8 --dataset melanoma_cohort
148
165
  plexora project show slide # every question, and whether it is answered
166
+
167
+ plexora dataset create "Melanoma Cohort" --from projects.json --node hms-o2
149
168
  ```
150
169
 
151
170
  ### Shared projects
@@ -719,6 +719,11 @@ _PROJECT_OPTIONS = (
719
719
  "help": "Override how the image is read."}),
720
720
  ("--copy", {"action": "store_true",
721
721
  "help": "Copy the files into the project directory."}),
722
+ ("--node", {"metavar": "NAME",
723
+ "help": "The data node the files are on, for any path that "
724
+ "does not say for itself. In a spec file, "
725
+ '{"path": ..., "node": null} keeps one file on this '
726
+ "machine."}),
722
727
  )
723
728
 
724
729
 
@@ -751,6 +756,11 @@ def _build_dataset_parser():
751
756
  "or a bare list of project specs. Command-line "
752
757
  "arguments win over what is in it.")
753
758
  create.add_argument("--description", default="")
759
+ create.add_argument("--node", metavar="NAME",
760
+ help="The data node these files are on. Every path "
761
+ "that does not say otherwise is a path over "
762
+ "there, and the projects address it rather than "
763
+ "copying anything here.")
754
764
  create.add_argument("--exist-ok", action="store_true",
755
765
  help="Add to the dataset if it already exists.")
756
766
  create.add_argument("--json", action="store_true",
@@ -1549,6 +1559,7 @@ def _run_dataset(args):
1549
1559
  images=images or None,
1550
1560
  projects=projects or None if not images else None,
1551
1561
  description=args.description or document.get("description", ""),
1562
+ node=args.node,
1552
1563
  exist_ok=args.exist_ok,
1553
1564
  )
1554
1565
  if args.json:
@@ -1558,6 +1569,7 @@ def _run_dataset(args):
1558
1569
  f"{len(dataset)} project{'' if len(dataset) == 1 else 's'}")
1559
1570
  for name in dataset.projects:
1560
1571
  print(f" {name}")
1572
+ _say_what_is_converting(api, dataset.projects)
1561
1573
  return _said_where(args, mutating=True)
1562
1574
 
1563
1575
  if command == "list":
@@ -1656,12 +1668,15 @@ def _run_project(args):
1656
1668
 
1657
1669
  try:
1658
1670
  if command == "create":
1659
- paths = list(args.paths)
1660
- if _wants_detection(paths, args):
1661
- name = api.import_sample(*paths, name=args.name,
1662
- dataset=args.dataset)
1671
+ # `given`, not `paths`: the module imported above answers
1672
+ # `paths.DataRootError` in the handler below, and rebinding the
1673
+ # name here made that an AttributeError on this one path.
1674
+ given = list(args.paths)
1675
+ if _wants_detection(given, args):
1676
+ name = api.import_sample(*given, name=args.name,
1677
+ dataset=args.dataset, node=args.node)
1663
1678
  else:
1664
- spec = _spec_from_args(args, image=paths[0], name=args.name)
1679
+ spec = _spec_from_args(args, image=given[0], name=args.name)
1665
1680
  if args.spec_file:
1666
1681
  spec = {**_load_spec_file(args.spec_file), **spec}
1667
1682
  spec["exist_ok"] = args.exist_ok
@@ -1671,6 +1686,7 @@ def _run_project(args):
1671
1686
  else:
1672
1687
  print(name)
1673
1688
  _print_manifest(api.project_manifest(name))
1689
+ _say_what_is_converting(api, [name])
1674
1690
  return _said_where(args, mutating=True)
1675
1691
 
1676
1692
  if command == "show":
@@ -1714,6 +1730,37 @@ def _message(exc):
1714
1730
  return str(exc.args[0]) if exc.args else str(exc)
1715
1731
 
1716
1732
 
1733
+ def _say_what_is_converting(api, names):
1734
+ """Name anything a node is still preparing for these projects.
1735
+
1736
+ A mask on a node has to be turned into a label pyramid before a tile can
1737
+ be served, and that happens after registration returns -- the project is
1738
+ valid and openable while it runs. Said here because a command line has no
1739
+ progress bar: the viewer shows one, and somebody who was not told to look
1740
+ sees an empty layer and assumes the import failed.
1741
+
1742
+ Human output only. The JSON is a payload other programs parse, and a line
1743
+ about work in flight is not part of what was registered.
1744
+
1745
+ A conversion that has already FAILED is said too, with the node's reason.
1746
+ The project is registered either way, but its mask cannot be drawn until
1747
+ whatever the node names is fixed -- and silence here is how a mask in a
1748
+ directory this account could not write went unnoticed until it drew wrong.
1749
+ """
1750
+ for row in api.pending_conversions(names):
1751
+ count = row["count"]
1752
+ what = row["kind"] + ("" if count == 1 else "s")
1753
+ print(f"{count} {what} {'is' if count == 1 else 'are'} converting on "
1754
+ f"{row['node']}; the viewer shows progress.")
1755
+ for row in api.failed_conversions(names):
1756
+ print(f"Could not prepare {row['kind']} {row['id']!r} on {row['node']}: "
1757
+ f"{row['error']}")
1758
+ print(" Opening the project in the viewer tries again; until then "
1759
+ "the unconverted mask is drawn, more slowly.")
1760
+ for row in api.conversion_warnings(names):
1761
+ print(f"Note: {row['warning']}")
1762
+
1763
+
1717
1764
  def _print_manifest(record):
1718
1765
  """One line per question: what it is, where it stands, and the answer.
1719
1766