histomicsui 1.8.1.dev14__tar.gz → 1.8.1.dev28__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 (195) hide show
  1. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/PKG-INFO +1 -1
  2. histomicsui-1.8.1.dev28/docs/annotation_group_restrictions.rst +41 -0
  3. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/docs/config_options.rst +4 -0
  4. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/panels/DrawWidget.js +79 -2
  5. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/templates/panels/drawWidget.pug +1 -1
  6. histomicsui-1.8.1.dev28/histomicsui/web_client/utilities/allowedGroups.js +67 -0
  7. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/views/body/ImageView.js +5 -1
  8. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/views/popover/AnnotationContextMenu.js +42 -2
  9. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui.egg-info/PKG-INFO +1 -1
  10. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui.egg-info/SOURCES.txt +3 -0
  11. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui.egg-info/scm_file_list.json +32 -29
  12. histomicsui-1.8.1.dev28/histomicsui.egg-info/scm_version.json +8 -0
  13. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/tests/test_web_client.py +1 -0
  14. histomicsui-1.8.1.dev28/tests/web_client_specs/allowedGroupsSpec.js +371 -0
  15. histomicsui-1.8.1.dev14/histomicsui.egg-info/scm_version.json +0 -8
  16. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/.circleci/config.yml +0 -0
  17. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/.editorconfig +0 -0
  18. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/.git-blame-ignore-revs +0 -0
  19. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/.gitignore +0 -0
  20. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/.pre-commit-config.yaml +0 -0
  21. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/LICENSE +0 -0
  22. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/MANIFEST.in +0 -0
  23. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/NOTICE +0 -0
  24. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/README.rst +0 -0
  25. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/codecov.yml +0 -0
  26. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/docs/controls.rst +0 -0
  27. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/docs/images/cut.gif +0 -0
  28. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/docs/images/difference.gif +0 -0
  29. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/docs/images/intersect.gif +0 -0
  30. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/docs/images/union.gif +0 -0
  31. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/docs/images/xor.gif +0 -0
  32. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/docs/slicer_cli_plugins.rst +0 -0
  33. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/__init__.py +0 -0
  34. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/constants.py +0 -0
  35. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/handlers.py +0 -0
  36. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/models/__init__.py +0 -0
  37. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/models/aperio.py +0 -0
  38. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/models/case.py +0 -0
  39. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/models/cohort.py +0 -0
  40. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/models/image.py +0 -0
  41. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/models/meta.py +0 -0
  42. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/models/pathology.py +0 -0
  43. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/models/slide.py +0 -0
  44. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/rest/__init__.py +0 -0
  45. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/rest/aperio.py +0 -0
  46. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/rest/hui_resource.py +0 -0
  47. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/rest/image_browse_resource.py +0 -0
  48. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/rest/system.py +0 -0
  49. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/rest/tcga.py +0 -0
  50. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/app.js +0 -0
  51. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/collections/StyleCollection.js +0 -0
  52. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/collections/UserCollection.js +0 -0
  53. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/collections/index.js +0 -0
  54. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/dialogs/confirmDialog.js +0 -0
  55. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/dialogs/editElement.js +0 -0
  56. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/dialogs/editRegionOfInterest.js +0 -0
  57. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/dialogs/editStyleGroups.js +0 -0
  58. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/dialogs/index.js +0 -0
  59. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/dialogs/metadataPlot.js +0 -0
  60. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/dialogs/openAnnotatedImage.js +0 -0
  61. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/dialogs/openImage.js +0 -0
  62. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/dialogs/saveAnnotation.js +0 -0
  63. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/events.js +0 -0
  64. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/index.js +0 -0
  65. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/main.js +0 -0
  66. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/models/StyleModel.js +0 -0
  67. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/models/index.js +0 -0
  68. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/package.json +0 -0
  69. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/panels/AnnotationSelector.js +0 -0
  70. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/panels/FrameSelectorWidget.js +0 -0
  71. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/panels/MetadataPlot.js +0 -0
  72. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/panels/MetadataWidget.js +0 -0
  73. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/panels/OverviewWidget.js +0 -0
  74. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/panels/RegionSelector.js +0 -0
  75. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/panels/ZoomWidget.js +0 -0
  76. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/panels/index.js +0 -0
  77. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/router.js +0 -0
  78. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/routes.js +0 -0
  79. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/static/favicon.png +0 -0
  80. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/stylesheets/body/configView.styl +0 -0
  81. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/stylesheets/body/image.styl +0 -0
  82. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/stylesheets/dialogs/editStyleGroups.styl +0 -0
  83. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/stylesheets/dialogs/metadataPlot.styl +0 -0
  84. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/stylesheets/dialogs/openAnnotatedImage.styl +0 -0
  85. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/stylesheets/dialogs/saveAnnotation.styl +0 -0
  86. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/stylesheets/layout/header.styl +0 -0
  87. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/stylesheets/layout/headerAnalyses.styl +0 -0
  88. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/stylesheets/layout/headerImage.styl +0 -0
  89. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/stylesheets/layout/layout.styl +0 -0
  90. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/stylesheets/panels/annotationSelector.styl +0 -0
  91. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/stylesheets/panels/drawWidget.styl +0 -0
  92. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/stylesheets/panels/frameSelectorWidget.styl +0 -0
  93. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/stylesheets/panels/metadataPlot.styl +0 -0
  94. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/stylesheets/panels/metadataWidget.styl +0 -0
  95. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/stylesheets/panels/overviewWidget.styl +0 -0
  96. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/stylesheets/panels/regionSelector.styl +0 -0
  97. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/stylesheets/panels/zoomWidget.styl +0 -0
  98. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/stylesheets/popover/annotationContextMenu.styl +0 -0
  99. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/stylesheets/popover/annotationPopover.styl +0 -0
  100. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/stylesheets/views/itemList.styl +0 -0
  101. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/stylesheets/views/searchResultsView.styl +0 -0
  102. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/templates/body/configView.pug +0 -0
  103. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/templates/body/image.pug +0 -0
  104. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/templates/dialogs/annotatedImageList.pug +0 -0
  105. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/templates/dialogs/confirmDialog.pug +0 -0
  106. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/templates/dialogs/editElement.pug +0 -0
  107. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/templates/dialogs/editRegionOfInterest.pug +0 -0
  108. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/templates/dialogs/editStyleGroups.pug +0 -0
  109. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/templates/dialogs/metadataPlot.pug +0 -0
  110. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/templates/dialogs/openAnnotatedImage.pug +0 -0
  111. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/templates/dialogs/openImage.pug +0 -0
  112. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/templates/dialogs/saveAnnotation.pug +0 -0
  113. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/templates/elementProps.pug +0 -0
  114. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/templates/layout/header.pug +0 -0
  115. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/templates/layout/headerAnalyses.pug +0 -0
  116. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/templates/layout/headerImage.pug +0 -0
  117. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/templates/layout/headerUser.pug +0 -0
  118. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/templates/layout/layout.pug +0 -0
  119. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/templates/panels/annotationSelector.pug +0 -0
  120. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/templates/panels/drawWidgetElement.pug +0 -0
  121. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/templates/panels/frameSelectorWidget.pug +0 -0
  122. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/templates/panels/metadataPlot.pug +0 -0
  123. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/templates/panels/metadataWidgetPanel.pug +0 -0
  124. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/templates/panels/overviewWidget.pug +0 -0
  125. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/templates/panels/panel.pug +0 -0
  126. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/templates/panels/regionSelector.pug +0 -0
  127. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/templates/panels/zoomWidget.pug +0 -0
  128. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/templates/popover/annotationContextMenu.pug +0 -0
  129. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/templates/popover/annotationPopover.pug +0 -0
  130. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/templates/popover/annotationPopoverMetadata.pug +0 -0
  131. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/templates/popover/pixelmapContextMenu.pug +0 -0
  132. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/views/HierarchyWidget.js +0 -0
  133. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/views/JobDetailsWidget.js +0 -0
  134. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/views/View.js +0 -0
  135. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/views/body/ConfigView.js +0 -0
  136. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/views/body/index.js +0 -0
  137. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/views/index.js +0 -0
  138. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/views/itemList.js +0 -0
  139. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/views/itemPage.js +0 -0
  140. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/views/layout/HeaderAnalysesView.js +0 -0
  141. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/views/layout/HeaderImageView.js +0 -0
  142. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/views/layout/HeaderUserView.js +0 -0
  143. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/views/layout/HeaderView.js +0 -0
  144. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/views/layout/LoginView.js +0 -0
  145. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/views/layout/index.js +0 -0
  146. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/views/popover/AnnotationPopover.js +0 -0
  147. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/views/popover/PixelmapContextMenu.js +0 -0
  148. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/views/popover/index.js +0 -0
  149. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/views/searchResultsView.js +0 -0
  150. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/views/utils.js +0 -0
  151. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/vue/components/AnnotationHistoryBrowser.vue +0 -0
  152. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/vue/components/AnnotationHistoryBrowserContainer.vue +0 -0
  153. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/vue/components/AnnotationHistoryGroup.vue +0 -0
  154. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/vue/components/ColorPickerInput.vue +0 -0
  155. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/vue/components/EditHeatmapOrGridData.vue +0 -0
  156. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/vue/components/EditHeatmapOrGridDataContainer.vue +0 -0
  157. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/web_client/webpack.helper.js +0 -0
  158. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui/webroot.mako +0 -0
  159. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui.egg-info/dependency_links.txt +0 -0
  160. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui.egg-info/entry_points.txt +0 -0
  161. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui.egg-info/not-zip-safe +0 -0
  162. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui.egg-info/requires.txt +0 -0
  163. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/histomicsui.egg-info/top_level.txt +0 -0
  164. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/pyproject.toml +0 -0
  165. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/requirements-dev.txt +0 -0
  166. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/ruff.toml +0 -0
  167. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/setup.cfg +0 -0
  168. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/setup.py +0 -0
  169. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/tests/__init__.py +0 -0
  170. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/tests/datastore.py +0 -0
  171. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/tests/girder_utilities.py +0 -0
  172. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/tests/test_files/.histomicsui_config.yaml +0 -0
  173. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/tests/test_files/sample.anot +0 -0
  174. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/tests/test_files/sample.meta +0 -0
  175. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/tests/test_files/sample_girder_id.anot +0 -0
  176. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/tests/test_files/test_analysis_detection.xml +0 -0
  177. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/tests/test_files/test_analysis_features.xml +0 -0
  178. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/tests/test_handlers.py +0 -0
  179. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/tests/test_hui_rest.py +0 -0
  180. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/tests/test_image_browse_endpoints.py +0 -0
  181. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/tests/test_load.py +0 -0
  182. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/tests/test_tcga.py +0 -0
  183. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/tests/web_client_specs/.eslintrc +0 -0
  184. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/tests/web_client_specs/analysisSpec.js +0 -0
  185. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/tests/web_client_specs/annotationSpec.js +0 -0
  186. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/tests/web_client_specs/girderUISpec.js +0 -0
  187. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/tests/web_client_specs/huiSpec.js +0 -0
  188. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/tests/web_client_specs/huiTest.js +0 -0
  189. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/tests/web_client_specs/itemSpec.js +0 -0
  190. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/tests/web_client_specs/metadataPanelSpec.js +0 -0
  191. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/tests/web_client_specs/metadataPlotSpec.js +0 -0
  192. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/tests/web_client_specs/overviewPanelSpec.js +0 -0
  193. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/tests/web_client_specs/panelLayoutSpec.js +0 -0
  194. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/tests/web_client_specs/pixelmapCategorySpec.js +0 -0
  195. {histomicsui-1.8.1.dev14 → histomicsui-1.8.1.dev28}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: histomicsui
3
- Version: 1.8.1.dev14
3
+ Version: 1.8.1.dev28
4
4
  Summary: Organize, visualize, and analyze histology images.
5
5
  Home-page: https://github.com/DigitalSlideArchive/histomicsui
6
6
  Author: Kitware, Inc.
@@ -0,0 +1,41 @@
1
+ Restricting Annotations to Allowed Groups
2
+ ==========================================
3
+
4
+ An annotation document can restrict which style groups its elements may be assigned to by setting an ``allowed_groups`` key in the annotation's ``attributes``:
5
+
6
+ ::
7
+
8
+ {
9
+ "name": "restricted annotation",
10
+ "attributes": {
11
+ "allowed_groups": ["groupA", "groupB"]
12
+ },
13
+ "elements": [...]
14
+ }
15
+
16
+ ``allowed_groups`` may also be given as a JSON-stringified array for convenience when setting it through the UI metadata editor:
17
+
18
+ ::
19
+
20
+ {
21
+ "attributes": {
22
+ "allowed_groups": "[\"groupA\", \"groupB\"]"
23
+ }
24
+ }
25
+
26
+ When this restriction is present, the Draw panel and the annotation element context menu will only offer the listed groups instead of every style group that exists.
27
+
28
+ Validation
29
+ ----------
30
+
31
+ ``allowed_groups`` is only honored when it is a non-empty array of non-empty strings, or a string that parses as JSON into such an array. Any other value - a missing key, a non-array/non-JSON-array value, an unparseable string, an empty array, or an array containing no valid strings - is treated as *unrestricted*, and every existing style group is offered as usual. Duplicate entries are ignored.
32
+
33
+ Auto-creation of missing groups
34
+ --------------------------------
35
+
36
+ If ``allowed_groups`` names a style group that does not yet exist, it is automatically created the first time the restriction is encountered, by copying the style (fill color, line color, line width, pattern) of the default group. The newly created groups are persisted immediately. This can happen from either the Draw panel or the annotation context menu, whichever sees the restricted annotation first.
37
+
38
+ Effect on the current selection
39
+ --------------------------------
40
+
41
+ - **Draw panel**: If the currently active style group is not one of the annotation's allowed groups, the Draw panel automatically switches to the first allowed group that exists.
@@ -56,6 +56,10 @@ _________________
56
56
  fillColor: rgba(0, 128, 0, 0.25)
57
57
  lineColor: rgb(0, 128, 0)
58
58
  lineWidth: 2
59
+ # patterns can be none, circle, triangle, diamond, flower(number),
60
+ # star(number), jack(number), where number is from 1 to 16. Not
61
+ # specifying a pattern is the same as none.
62
+ pattern: star5
59
63
  -
60
64
  id: Blue
61
65
  fillColor: rgba(0, 0, 255, 0.25)
@@ -15,6 +15,7 @@ import StyleCollection from '../collections/StyleCollection';
15
15
  import StyleModel from '../models/StyleModel';
16
16
  import editElement from '../dialogs/editElement';
17
17
  import editStyleGroups from '../dialogs/editStyleGroups';
18
+ import getAllowedGroups, {ensureAllowedGroupsExist} from '../utilities/allowedGroups';
18
19
  import drawWidget from '../templates/panels/drawWidget.pug';
19
20
  import drawWidgetElement from '../templates/panels/drawWidgetElement.pug';
20
21
  import '../stylesheets/panels/drawWidget.styl';
@@ -64,9 +65,11 @@ var DrawWidget = Panel.extend({
64
65
  this._groups = new StyleCollection();
65
66
  this._style = new StyleModel({id: this.parentView._defaultGroup});
66
67
  this.listenTo(this._groups, 'add change', this._handleStyleGroupsUpdate);
67
- this.listenTo(this._groups, 'remove', this.render);
68
+ this.listenTo(this._groups, 'remove', this._handleStyleGroupsRemoved);
68
69
  this.listenTo(this.collection, 'add remove reset', this._recalculateGroupAggregation);
69
70
  this.listenTo(this.collection, 'change update reset', this.render);
71
+ // if the annotation's metadata is edited while it is active, react immediately
72
+ this.listenTo(this.annotation, 'change:annotation', this._handleAnnotationAttributesChange);
70
73
  this._groups.fetch().done(() => {
71
74
  // ensure the default style exists
72
75
  if (this._groups.has(this.parentView._defaultGroup)) {
@@ -75,9 +78,12 @@ var DrawWidget = Panel.extend({
75
78
  this._groups.add(this._style.toJSON());
76
79
  this._groups.get(this._style.id).save();
77
80
  }
81
+ this._ensureAllowedGroupsExist();
78
82
  if (this._editOptions.style && this._groups.get(this._editOptions.style)) {
79
83
  this._setStyleGroup(this._groups.get(this._editOptions.style).toJSON());
80
84
  }
85
+ this._restrictStyleToAllowedGroups();
86
+ this._debounceRender();
81
87
  });
82
88
  this.on('h:mouseon', (model) => {
83
89
  if (model && model.id) {
@@ -113,7 +119,7 @@ var DrawWidget = Panel.extend({
113
119
  this.$el.html(drawWidget({
114
120
  title: 'Draw',
115
121
  elements: this.collection.models,
116
- groups: this._groups,
122
+ groups: this._groupsForDisplay(),
117
123
  style: this._style.id,
118
124
  defaultGroup: this.parentView._defaultGroup,
119
125
  highlighted: this._highlighted,
@@ -1071,10 +1077,81 @@ var DrawWidget = Panel.extend({
1071
1077
  },
1072
1078
 
1073
1079
  _handleStyleGroupsUpdate() {
1080
+ this._restrictStyleToAllowedGroups();
1074
1081
  this._debounceRender();
1075
1082
  this.trigger('h:styleGroupsUpdated', this._groups);
1076
1083
  },
1077
1084
 
1085
+ _handleStyleGroupsRemoved() {
1086
+ this._restrictStyleToAllowedGroups();
1087
+ this.render();
1088
+ },
1089
+
1090
+ /**
1091
+ * Get the current annotation's `allowed_groups` metadata, if any.
1092
+ *
1093
+ * @returns {string[]|null} The list of allowed group names, or null if the current annotation
1094
+ * has no valid restriction.
1095
+ */
1096
+ _getAllowedGroups() {
1097
+ return getAllowedGroups(this.annotation);
1098
+ },
1099
+
1100
+ /**
1101
+ * Respond to the active annotation's metadata being edited, which may have changed its
1102
+ * `allowed_groups` restriction.
1103
+ */
1104
+ _handleAnnotationAttributesChange() {
1105
+ this._ensureAllowedGroupsExist();
1106
+ this._restrictStyleToAllowedGroups();
1107
+ this._debounceRender();
1108
+ },
1109
+
1110
+ /**
1111
+ * If the current annotation restricts its elements to a set of allowed_groups, create any of
1112
+ * those groups that don't already exist, copying the current default group's style.
1113
+ */
1114
+ _ensureAllowedGroupsExist() {
1115
+ const saves = ensureAllowedGroupsExist(
1116
+ this._groups, this._getAllowedGroups(), this.parentView._defaultGroup);
1117
+ if (!saves.length) {
1118
+ return;
1119
+ }
1120
+ // Let other views know new groups exist after they're persisted so that a page refresh is
1121
+ // not needed.
1122
+ $.when(...saves).done(() => {
1123
+ this.parentView.trigger('h:styleGroupsEdited', this._groups);
1124
+ });
1125
+ },
1126
+
1127
+ /**
1128
+ * Return the style groups that should be offered to the user given the current annotation's
1129
+ * `allowed_groups` restriction, if any, sorted alphabetically by id.
1130
+ *
1131
+ * @returns {object[]} A list of plain style group attribute objects.
1132
+ */
1133
+ _groupsForDisplay() {
1134
+ const allowed = this._getAllowedGroups();
1135
+ const groups = allowed ? this._groups.filter((group) => allowed.includes(group.id)) : this._groups.models;
1136
+ return _.sortBy(groups, 'id').map((group) => group.toJSON());
1137
+ },
1138
+
1139
+ /**
1140
+ * If the current annotation restricts its elements to a set of `allowed_groups` and the
1141
+ * currently selected style is not one of them, switch to the first allowed group that exists.
1142
+ */
1143
+ _restrictStyleToAllowedGroups() {
1144
+ const allowed = this._getAllowedGroups();
1145
+ if (!allowed || allowed.includes(this._style.id)) return;
1146
+
1147
+ const candidates = this._groups.filter((group) => allowed.includes(group.id))
1148
+ .map((group) => group.id)
1149
+ .sort();
1150
+ if (candidates.length) {
1151
+ this._setStyleGroup(this._groups.get(candidates[0]).toJSON());
1152
+ }
1153
+ },
1154
+
1078
1155
  _highlightElement(evt) {
1079
1156
  const id = $(evt.currentTarget).data('id');
1080
1157
  const annotType = this.collection._byId[id].get('type');
@@ -6,7 +6,7 @@ block title
6
6
  block content
7
7
  .input-group.input-group-sm.h-style-group-row
8
8
  select.form-control.h-style-group
9
- each group in groups.sortBy('id')
9
+ each group in groups
10
10
  option(value=group.id, selected=group.id === style)
11
11
  = group.id
12
12
  .input-group-btn
@@ -0,0 +1,67 @@
1
+ import _ from 'underscore';
2
+
3
+ /**
4
+ * Read and validate the `allowed_groups` metadata on an annotation.
5
+ *
6
+ * The value is expected to live at `annotation.get('annotation').attributes.allowed_groups`
7
+ * and be an array of strings. As a convenience for the UI metadata editor, a JSON-stringified
8
+ * array (e.g. `'["groupA", "groupB"]'`) is also accepted and parsed. Any other value (missing,
9
+ * not an array or JSON array string, empty array, unparseable string, etc.) is treated as
10
+ * "unrestricted" and returns `null`.
11
+ *
12
+ * @param {AnnotationModel} annotation The annotation to check.
13
+ * @returns {string[]|null} The list of allowed group names, or null if there are no restrictions.
14
+ */
15
+ function getAllowedGroups(annotation) {
16
+ if (!annotation) return null;
17
+
18
+ const attributes = (annotation.get('annotation') || {}).attributes || {};
19
+ let allowedGroups = attributes.allowed_groups;
20
+
21
+ if (_.isString(allowedGroups)) {
22
+ try {
23
+ allowedGroups = JSON.parse(allowedGroups);
24
+ } catch (err) {
25
+ return null;
26
+ }
27
+ }
28
+
29
+ if (!_.isArray(allowedGroups)) return null;
30
+
31
+ const filtered = _.uniq(allowedGroups.filter((group) => _.isString(group) && group.length));
32
+ return filtered.length ? filtered : null;
33
+ }
34
+
35
+ /**
36
+ * Ensure that every group in an `allowed_groups` restriction exists as a persisted style group.
37
+ * Create any that are missing by copying the style of the default group.
38
+ *
39
+ * Newly created groups are added to the collection synchronously and each is persisted
40
+ * asynchronously. The caller is responsible for reacting to the returned save promises.
41
+ *
42
+ * @param {StyleCollection} styles The style-group collection to populate.
43
+ * @param {string[]|null} allowed The validated `allowed_groups` restriction, or `null` for
44
+ * "unrestricted" (in which case nothing is created).
45
+ * @param {string} defaultGroupId The id of the default style group to copy.
46
+ * @returns {Array} The list of save promises for the newly created groups.
47
+ */
48
+ function ensureAllowedGroupsExist(styles, allowed, defaultGroupId) {
49
+ if (!allowed) {
50
+ return [];
51
+ }
52
+ const missing = allowed.filter((groupId) => !styles.get(groupId));
53
+ if (!missing.length) {
54
+ return [];
55
+ }
56
+ // we assume the default group always exists; if it somehow does not, new groups are created
57
+ // with no inherited style rather than failing
58
+ const defaultGroup = styles.get(defaultGroupId);
59
+ const baseAttributes = defaultGroup ? _.omit(defaultGroup.toJSON(), 'id', 'group') : {};
60
+ return missing.map((groupId) => {
61
+ styles.add(Object.assign({}, baseAttributes, {id: groupId}));
62
+ return styles.get(groupId).save();
63
+ });
64
+ }
65
+
66
+ export default getAllowedGroups;
67
+ export {ensureAllowedGroupsExist};
@@ -1553,8 +1553,12 @@ var ImageView = View.extend({
1553
1553
  return;
1554
1554
  }
1555
1555
 
1556
- var elementModel = this.selectedElements.add(element.attributes, options);
1556
+ // Assign `originalAnnotation` before the element enters the collection. Setting it after
1557
+ // `add` would leave that first render seeing an undefined reference and falling back to
1558
+ // the panel's active annotation instead of the clicked one.
1559
+ var elementModel = new this.selectedElements.model(element.attributes);
1557
1560
  elementModel.originalAnnotation = annotation;
1561
+ this.selectedElements.add(elementModel, options);
1558
1562
  this.viewerWidget.highlightAnnotation(this.selectedAnnotation.id);
1559
1563
  },
1560
1564
 
@@ -1,6 +1,7 @@
1
1
  import $ from 'jquery';
2
2
 
3
3
  import StyleCollection from '../../collections/StyleCollection';
4
+ import getAllowedGroups, {ensureAllowedGroupsExist} from '../../utilities/allowedGroups';
4
5
  import View from '../View';
5
6
 
6
7
  import template from '../../templates/popover/annotationContextMenu.pug';
@@ -19,6 +20,8 @@ const AnnotationContextMenu = View.extend({
19
20
  this.styles = new StyleCollection();
20
21
  this.styles.fetch().done(() => this.render());
21
22
  this.listenTo(this.collection, 'add remove reset', this.render);
23
+ // react immediately if any annotation's metadata is edited
24
+ this.listenTo(this.parentView.annotations, 'change:annotation', this.render);
22
25
  },
23
26
  render() {
24
27
  this.$el.html(template({
@@ -28,7 +31,16 @@ const AnnotationContextMenu = View.extend({
28
31
  return this;
29
32
  },
30
33
  refetchStyles() {
31
- this.styles.fetch().done(() => this.render());
34
+ // Prevent race conditions when multiple fetches happen in quick succession.
35
+ const requestId = (this._styleFetchRequestId = (this._styleFetchRequestId || 0) + 1);
36
+ this.styles.fetch({
37
+ success: (collection, resp, options) => {
38
+ if (requestId === this._styleFetchRequestId) {
39
+ collection.set(resp, options);
40
+ this.render();
41
+ }
42
+ }
43
+ });
32
44
  },
33
45
  setGroupCount(groupCount) {
34
46
  this._cachedGroupCount = groupCount;
@@ -67,6 +79,7 @@ const AnnotationContextMenu = View.extend({
67
79
  delete styleAttrs[k];
68
80
  }
69
81
  });
82
+ styleAttrs.pattern = styleAttrs.pattern || 'none';
70
83
  let refresh = false;
71
84
  if (this.parentView.drawWidget) {
72
85
  this.parentView.drawWidget._skipRenderHTML = 'skip';
@@ -95,7 +108,16 @@ const AnnotationContextMenu = View.extend({
95
108
  }
96
109
  },
97
110
  _getAnnotationGroups() {
98
- const groups = this.styles.map((style) => style.id);
111
+ // restrict to the allowed groups of the annotation that owns the selected/right-clicked
112
+ // element, not whichever annotation happens to be active in the Annotations panel
113
+ const referenceElement = this.collection.at(0);
114
+ const referenceAnnotation = (referenceElement && referenceElement.originalAnnotation) || this.parentView.activeAnnotation;
115
+ const allowed = getAllowedGroups(referenceAnnotation);
116
+ this._ensureAllowedGroupsExist(allowed);
117
+ let groups = this.styles.map((style) => style.id);
118
+ if (allowed) {
119
+ groups = groups.filter((groupId) => allowed.includes(groupId));
120
+ }
99
121
  groups.sort((a, b) => {
100
122
  const countA = this._cachedGroupCount[a] || 0;
101
123
  const countB = this._cachedGroupCount[b] || 0;
@@ -112,6 +134,24 @@ const AnnotationContextMenu = View.extend({
112
134
  });
113
135
  return groups;
114
136
  },
137
+ /**
138
+ * Create any style groups required by the given `allowed_groups` restriction that don't
139
+ * already exist. Once the new groups are persisted, notify the other views so their style
140
+ * collections stay in sync.
141
+ *
142
+ * @param {string[]|null} allowed The validated `allowed_groups` restriction, or `null` when
143
+ * unrestricted.
144
+ */
145
+ _ensureAllowedGroupsExist(allowed) {
146
+ const saves = ensureAllowedGroupsExist(
147
+ this.styles, allowed, this.parentView._defaultGroup);
148
+ if (!saves.length) {
149
+ return;
150
+ }
151
+ $.when(...saves).done(() => {
152
+ this.parentView.trigger('h:styleGroupsEdited', this.styles);
153
+ });
154
+ },
115
155
  _setGroup(evt) {
116
156
  evt.preventDefault();
117
157
  evt.stopPropagation();
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: histomicsui
3
- Version: 1.8.1.dev14
3
+ Version: 1.8.1.dev28
4
4
  Summary: Organize, visualize, and analyze histology images.
5
5
  Home-page: https://github.com/DigitalSlideArchive/histomicsui
6
6
  Author: Kitware, Inc.
@@ -14,6 +14,7 @@ setup.cfg
14
14
  setup.py
15
15
  tox.ini
16
16
  .circleci/config.yml
17
+ docs/annotation_group_restrictions.rst
17
18
  docs/config_options.rst
18
19
  docs/controls.rst
19
20
  docs/slicer_cli_plugins.rst
@@ -134,6 +135,7 @@ histomicsui/web_client/templates/popover/annotationContextMenu.pug
134
135
  histomicsui/web_client/templates/popover/annotationPopover.pug
135
136
  histomicsui/web_client/templates/popover/annotationPopoverMetadata.pug
136
137
  histomicsui/web_client/templates/popover/pixelmapContextMenu.pug
138
+ histomicsui/web_client/utilities/allowedGroups.js
137
139
  histomicsui/web_client/views/HierarchyWidget.js
138
140
  histomicsui/web_client/views/JobDetailsWidget.js
139
141
  histomicsui/web_client/views/View.js
@@ -177,6 +179,7 @@ tests/test_files/sample_girder_id.anot
177
179
  tests/test_files/test_analysis_detection.xml
178
180
  tests/test_files/test_analysis_features.xml
179
181
  tests/web_client_specs/.eslintrc
182
+ tests/web_client_specs/allowedGroupsSpec.js
180
183
  tests/web_client_specs/analysisSpec.js
181
184
  tests/web_client_specs/annotationSpec.js
182
185
  tests/web_client_specs/girderUISpec.js
@@ -1,5 +1,6 @@
1
1
  {
2
2
  "files": [
3
+ ".circleci/config.yml",
3
4
  ".editorconfig",
4
5
  ".git-blame-ignore-revs",
5
6
  ".gitignore",
@@ -9,25 +10,18 @@
9
10
  "NOTICE",
10
11
  "README.rst",
11
12
  "codecov.yml",
12
- "pyproject.toml",
13
- "requirements-dev.txt",
14
- "ruff.toml",
15
- "setup.cfg",
16
- "setup.py",
17
- "tox.ini",
18
- ".circleci/config.yml",
13
+ "docs/annotation_group_restrictions.rst",
19
14
  "docs/config_options.rst",
20
15
  "docs/controls.rst",
21
- "docs/slicer_cli_plugins.rst",
22
16
  "docs/images/cut.gif",
23
17
  "docs/images/difference.gif",
24
18
  "docs/images/intersect.gif",
25
19
  "docs/images/union.gif",
26
20
  "docs/images/xor.gif",
21
+ "docs/slicer_cli_plugins.rst",
27
22
  "histomicsui/__init__.py",
28
23
  "histomicsui/constants.py",
29
24
  "histomicsui/handlers.py",
30
- "histomicsui/webroot.mako",
31
25
  "histomicsui/models/__init__.py",
32
26
  "histomicsui/models/aperio.py",
33
27
  "histomicsui/models/case.py",
@@ -43,13 +37,6 @@
43
37
  "histomicsui/rest/system.py",
44
38
  "histomicsui/rest/tcga.py",
45
39
  "histomicsui/web_client/app.js",
46
- "histomicsui/web_client/events.js",
47
- "histomicsui/web_client/index.js",
48
- "histomicsui/web_client/main.js",
49
- "histomicsui/web_client/package.json",
50
- "histomicsui/web_client/router.js",
51
- "histomicsui/web_client/routes.js",
52
- "histomicsui/web_client/webpack.helper.js",
53
40
  "histomicsui/web_client/collections/StyleCollection.js",
54
41
  "histomicsui/web_client/collections/UserCollection.js",
55
42
  "histomicsui/web_client/collections/index.js",
@@ -62,8 +49,12 @@
62
49
  "histomicsui/web_client/dialogs/openAnnotatedImage.js",
63
50
  "histomicsui/web_client/dialogs/openImage.js",
64
51
  "histomicsui/web_client/dialogs/saveAnnotation.js",
52
+ "histomicsui/web_client/events.js",
53
+ "histomicsui/web_client/index.js",
54
+ "histomicsui/web_client/main.js",
65
55
  "histomicsui/web_client/models/StyleModel.js",
66
56
  "histomicsui/web_client/models/index.js",
57
+ "histomicsui/web_client/package.json",
67
58
  "histomicsui/web_client/panels/AnnotationSelector.js",
68
59
  "histomicsui/web_client/panels/DrawWidget.js",
69
60
  "histomicsui/web_client/panels/FrameSelectorWidget.js",
@@ -73,6 +64,8 @@
73
64
  "histomicsui/web_client/panels/RegionSelector.js",
74
65
  "histomicsui/web_client/panels/ZoomWidget.js",
75
66
  "histomicsui/web_client/panels/index.js",
67
+ "histomicsui/web_client/router.js",
68
+ "histomicsui/web_client/routes.js",
76
69
  "histomicsui/web_client/static/favicon.png",
77
70
  "histomicsui/web_client/stylesheets/body/configView.styl",
78
71
  "histomicsui/web_client/stylesheets/body/image.styl",
@@ -96,7 +89,6 @@
96
89
  "histomicsui/web_client/stylesheets/popover/annotationPopover.styl",
97
90
  "histomicsui/web_client/stylesheets/views/itemList.styl",
98
91
  "histomicsui/web_client/stylesheets/views/searchResultsView.styl",
99
- "histomicsui/web_client/templates/elementProps.pug",
100
92
  "histomicsui/web_client/templates/body/configView.pug",
101
93
  "histomicsui/web_client/templates/body/image.pug",
102
94
  "histomicsui/web_client/templates/dialogs/annotatedImageList.pug",
@@ -108,6 +100,7 @@
108
100
  "histomicsui/web_client/templates/dialogs/openAnnotatedImage.pug",
109
101
  "histomicsui/web_client/templates/dialogs/openImage.pug",
110
102
  "histomicsui/web_client/templates/dialogs/saveAnnotation.pug",
103
+ "histomicsui/web_client/templates/elementProps.pug",
111
104
  "histomicsui/web_client/templates/layout/header.pug",
112
105
  "histomicsui/web_client/templates/layout/headerAnalyses.pug",
113
106
  "histomicsui/web_client/templates/layout/headerImage.pug",
@@ -127,17 +120,16 @@
127
120
  "histomicsui/web_client/templates/popover/annotationPopover.pug",
128
121
  "histomicsui/web_client/templates/popover/annotationPopoverMetadata.pug",
129
122
  "histomicsui/web_client/templates/popover/pixelmapContextMenu.pug",
123
+ "histomicsui/web_client/utilities/allowedGroups.js",
130
124
  "histomicsui/web_client/views/HierarchyWidget.js",
131
125
  "histomicsui/web_client/views/JobDetailsWidget.js",
132
126
  "histomicsui/web_client/views/View.js",
133
- "histomicsui/web_client/views/index.js",
134
- "histomicsui/web_client/views/itemList.js",
135
- "histomicsui/web_client/views/itemPage.js",
136
- "histomicsui/web_client/views/searchResultsView.js",
137
- "histomicsui/web_client/views/utils.js",
138
127
  "histomicsui/web_client/views/body/ConfigView.js",
139
128
  "histomicsui/web_client/views/body/ImageView.js",
140
129
  "histomicsui/web_client/views/body/index.js",
130
+ "histomicsui/web_client/views/index.js",
131
+ "histomicsui/web_client/views/itemList.js",
132
+ "histomicsui/web_client/views/itemPage.js",
141
133
  "histomicsui/web_client/views/layout/HeaderAnalysesView.js",
142
134
  "histomicsui/web_client/views/layout/HeaderImageView.js",
143
135
  "histomicsui/web_client/views/layout/HeaderUserView.js",
@@ -148,28 +140,38 @@
148
140
  "histomicsui/web_client/views/popover/AnnotationPopover.js",
149
141
  "histomicsui/web_client/views/popover/PixelmapContextMenu.js",
150
142
  "histomicsui/web_client/views/popover/index.js",
143
+ "histomicsui/web_client/views/searchResultsView.js",
144
+ "histomicsui/web_client/views/utils.js",
151
145
  "histomicsui/web_client/vue/components/AnnotationHistoryBrowser.vue",
152
146
  "histomicsui/web_client/vue/components/AnnotationHistoryBrowserContainer.vue",
153
147
  "histomicsui/web_client/vue/components/AnnotationHistoryGroup.vue",
154
148
  "histomicsui/web_client/vue/components/ColorPickerInput.vue",
155
149
  "histomicsui/web_client/vue/components/EditHeatmapOrGridData.vue",
156
150
  "histomicsui/web_client/vue/components/EditHeatmapOrGridDataContainer.vue",
151
+ "histomicsui/web_client/webpack.helper.js",
152
+ "histomicsui/webroot.mako",
153
+ "pyproject.toml",
154
+ "requirements-dev.txt",
155
+ "ruff.toml",
156
+ "setup.cfg",
157
+ "setup.py",
157
158
  "tests/__init__.py",
158
159
  "tests/datastore.py",
159
160
  "tests/girder_utilities.py",
160
- "tests/test_handlers.py",
161
- "tests/test_hui_rest.py",
162
- "tests/test_image_browse_endpoints.py",
163
- "tests/test_load.py",
164
- "tests/test_tcga.py",
165
- "tests/test_web_client.py",
166
161
  "tests/test_files/.histomicsui_config.yaml",
167
162
  "tests/test_files/sample.anot",
168
163
  "tests/test_files/sample.meta",
169
164
  "tests/test_files/sample_girder_id.anot",
170
165
  "tests/test_files/test_analysis_detection.xml",
171
166
  "tests/test_files/test_analysis_features.xml",
167
+ "tests/test_handlers.py",
168
+ "tests/test_hui_rest.py",
169
+ "tests/test_image_browse_endpoints.py",
170
+ "tests/test_load.py",
171
+ "tests/test_tcga.py",
172
+ "tests/test_web_client.py",
172
173
  "tests/web_client_specs/.eslintrc",
174
+ "tests/web_client_specs/allowedGroupsSpec.js",
173
175
  "tests/web_client_specs/analysisSpec.js",
174
176
  "tests/web_client_specs/annotationSpec.js",
175
177
  "tests/web_client_specs/girderUISpec.js",
@@ -180,6 +182,7 @@
180
182
  "tests/web_client_specs/metadataPlotSpec.js",
181
183
  "tests/web_client_specs/overviewPanelSpec.js",
182
184
  "tests/web_client_specs/panelLayoutSpec.js",
183
- "tests/web_client_specs/pixelmapCategorySpec.js"
185
+ "tests/web_client_specs/pixelmapCategorySpec.js",
186
+ "tox.ini"
184
187
  ]
185
188
  }
@@ -0,0 +1,8 @@
1
+ {
2
+ "tag": "1.8.0",
3
+ "distance": 28,
4
+ "node": "g945f6df04ba86ce201aeff1cb5f34332ab186838",
5
+ "dirty": false,
6
+ "branch": "master",
7
+ "node_date": "2026-08-11"
8
+ }
@@ -133,6 +133,7 @@ class MockSlicerCLIWebResource(Resource):
133
133
 
134
134
  @pytest.mark.plugin('histomicsui')
135
135
  @pytest.mark.parametrize('spec', [
136
+ 'allowedGroupsSpec.js',
136
137
  'analysisSpec.js',
137
138
  'annotationSpec.js',
138
139
  'girderUISpec.js',