@ohif/app 3.8.0-beta.80 → 3.8.0-beta.81

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 (33) hide show
  1. package/dist/{121.bundle.787f5a848ed632a4d5fc.js → 121.bundle.47f05840a5b3cdf75543.js} +4 -1
  2. package/dist/{183.bundle.72bf18ad23ee6624986d.js → 183.bundle.a3e238998be71c4b2af8.js} +64 -48
  3. package/dist/{206.bundle.f957e0d1cdff66dbac69.js → 206.bundle.fcaa081a0d1f68095c31.js} +45 -20
  4. package/dist/{217.bundle.be1cc412f8e26be87d21.js → 217.bundle.d44bbaa50b6fa563fe15.js} +116 -69
  5. package/dist/{295.bundle.6f734abf8fa85b1a310d.js → 295.bundle.5ace95771ced62bdcab8.js} +4 -1
  6. package/dist/{325.bundle.84909a08305556e9f924.js → 325.bundle.fd8e0c18db4708d03a91.js} +4 -8
  7. package/dist/{335.bundle.c39d4aefe33aecab958f.js → 335.bundle.8400aa5a88697a6b9d53.js} +2 -2
  8. package/dist/{41.bundle.7c943bb857ed37831905.js → 41.bundle.0905b258a90a7c6437bb.js} +174 -104
  9. package/dist/{422.bundle.bd6529c536f59807fbee.js → 422.bundle.c6fd037b075dd54f1ba7.js} +9 -25
  10. package/dist/{433.bundle.4c77c1fe8fc90ac14218.js → 433.bundle.e0018820758f5a86fa7f.js} +61 -7
  11. package/dist/{448.bundle.deedeff5744e77510734.js → 448.bundle.5e6da31477887bf53016.js} +6 -12
  12. package/dist/{487.bundle.7890ca42826941ebcd60.js → 487.bundle.89d973049defb3ba6cb7.js} +3 -2
  13. package/dist/{530.bundle.7c94543955552475c56a.js → 530.bundle.207b38c15c4c01e4db0e.js} +14 -2
  14. package/dist/{574.bundle.be075ac52fb52b442a8b.js → 574.bundle.d648fea691d6709bf2b4.js} +14 -3
  15. package/dist/{633.bundle.c1658e76f104cbd14cab.js → 633.bundle.acab89baaa06a299d679.js} +48 -33
  16. package/dist/{540.bundle.079d43a6717e95c24392.js → 669.bundle.b17e8a621e38d92c653f.js} +95 -87
  17. package/dist/{699.bundle.4f01772e7ce6637de339.js → 699.bundle.9367d7ef9f7615b2e733.js} +41 -37
  18. package/dist/{724.bundle.e5794460c391ee9cba2c.js → 724.bundle.55f9f49816de931af91a.js} +1 -1
  19. package/dist/{862.bundle.c0ee6e1d4d97e1353213.js → 862.bundle.d32ab08e64806b2e964d.js} +4 -1
  20. package/dist/{94.bundle.c452d9b0645277c2cf4e.js → 94.bundle.f5f2479c214180d05d42.js} +7 -13
  21. package/dist/app.bundle.css +1 -1
  22. package/dist/{app.bundle.6c090a2d6d3ccc97a81d.js → app.bundle.ed937512f7d19d61c411.js} +188 -64
  23. package/dist/index.html +1 -1
  24. package/dist/{polySeg.bundle.63011312c3c79e717ea9.js → polySeg.bundle.f1a6ece1396dc1385155.js} +1 -1
  25. package/dist/sw.js +1 -1
  26. package/package.json +18 -18
  27. /package/dist/{164.bundle.d4598e491783753a8b6b.js → 164.bundle.fadc7c5d634402c73b5f.js} +0 -0
  28. /package/dist/{188.bundle.b80554ec7df7dcd435a5.js → 188.bundle.51dc4b37920f45594393.js} +0 -0
  29. /package/dist/{594.bundle.0b1165661dd638820082.js → 594.bundle.84076375b127b9c7f673.js} +0 -0
  30. /package/dist/{889.bundle.7858e4b7ca1a2b12b64f.js → 889.bundle.8ef8b723d0163d5d135c.js} +0 -0
  31. /package/dist/{905.bundle.170908fe660fc6b40649.js → 905.bundle.8a96e1a75b7cfe5ec093.js} +0 -0
  32. /package/dist/{907.bundle.dee4e30420caf07caea6.js → 907.bundle.5c88ed911bed18582da4.js} +0 -0
  33. /package/dist/{961.bundle.aaaaaba0ec015a3b85d8.js → 961.bundle.f4e52bc76d3044d05372.js} +0 -0
@@ -248,7 +248,10 @@ function OHIFCornerstoneSEGViewport(props) {
248
248
  orientation: viewportOptions.orientation,
249
249
  viewportId: viewportOptions.viewportId
250
250
  },
251
- onElementEnabled: onElementEnabled,
251
+ onElementEnabled: evt => {
252
+ props.onElementEnabled?.(evt);
253
+ onElementEnabled(evt);
254
+ },
252
255
  onElementDisabled: onElementDisabled
253
256
  }));
254
257
  }, [viewportId, segDisplaySet, toolGroupId]);
@@ -802,8 +802,8 @@ function promptSaveReport({
802
802
  });
803
803
  }
804
804
  /* harmony default export */ const TrackedMeasurementsContext_promptSaveReport = (promptSaveReport);
805
- // EXTERNAL MODULE: ../../../extensions/cornerstone-dicom-sr/src/index.tsx + 15 modules
806
- var cornerstone_dicom_sr_src = __webpack_require__(53540);
805
+ // EXTERNAL MODULE: ../../../extensions/cornerstone-dicom-sr/src/index.tsx + 14 modules
806
+ var cornerstone_dicom_sr_src = __webpack_require__(61669);
807
807
  ;// CONCATENATED MODULE: ../../../extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/promptHydrateStructuredReport.js
808
808
 
809
809
 
@@ -1854,14 +1854,10 @@ function _findTabAndStudyOfDisplaySet(displaySetInstanceUID, tabs) {
1854
1854
  function getImageSrcFromImageId(cornerstone, imageId) {
1855
1855
  return new Promise((resolve, reject) => {
1856
1856
  const canvas = document.createElement('canvas');
1857
- // Note: the default width and height of the canvas is 300x150
1858
- // but we need to set the width and height to the same number since
1859
- // the thumbnails are usually square and we want to maintain the aspect ratio
1860
- canvas.width = 128 / window.devicePixelRatio;
1861
- canvas.height = 128 / window.devicePixelRatio;
1862
1857
  cornerstone.utilities.loadImageToCanvas({
1863
1858
  canvas,
1864
- imageId
1859
+ imageId,
1860
+ thumbnail: true
1865
1861
  }).then(imageId => {
1866
1862
  resolve(canvas.toDataURL());
1867
1863
  }).catch(reject);
@@ -1026,8 +1026,8 @@ function PanelRoiThresholdSegmentation({
1026
1026
  const suvPeak = cachedStats?.['1']?.suvPeak?.suvPeak;
1027
1027
  if (Number.isNaN(suvPeak)) {
1028
1028
  uiNotificationService.show({
1029
- title: 'Unable to calculate SUV Peak',
1030
- message: 'The resulting threshold is not big enough.',
1029
+ title: 'SUV Peak',
1030
+ message: 'Segmented volume does not allow SUV Peak calculation',
1031
1031
  type: 'warning'
1032
1032
  });
1033
1033
  }
@@ -3974,8 +3974,8 @@ function initCineService(servicesManager) {
3974
3974
  const playClip = (element, playClipOptions) => {
3975
3975
  return dist_esm.utilities.cine.playClip(element, playClipOptions);
3976
3976
  };
3977
- const stopClip = element => {
3978
- return dist_esm.utilities.cine.stopClip(element);
3977
+ const stopClip = (element, stopClipOptions) => {
3978
+ return dist_esm.utilities.cine.stopClip(element, stopClipOptions);
3979
3979
  };
3980
3980
  cineService.setServiceImplementation({
3981
3981
  getSyncedViewports,
@@ -4097,20 +4097,28 @@ function interleaveCenterLoader({
4097
4097
  * listen to it and as the other viewports are created we can set the volumes for them
4098
4098
  * since volumes are already started loading.
4099
4099
  */
4100
- if (matchDetails.size !== viewportIdVolumeInputArrayMap.size) {
4101
- return;
4102
- }
4103
-
4104
- // Check if all the matched volumes are loaded
4105
- for (const [_, details] of displaySetsMatchDetails.entries()) {
4100
+ const uniqueViewportVolumeDisplaySetUIDs = new Set();
4101
+ viewportIdVolumeInputArrayMap.forEach((volumeInputArray, viewportId) => {
4102
+ volumeInputArray.forEach(volumeInput => {
4103
+ const {
4104
+ volumeId
4105
+ } = volumeInput;
4106
+ uniqueViewportVolumeDisplaySetUIDs.add(volumeId);
4107
+ });
4108
+ });
4109
+ const uniqueMatchedDisplaySetUIDs = new Set();
4110
+ matchDetails.forEach(matchDetail => {
4106
4111
  const {
4107
- SeriesInstanceUID
4108
- } = details;
4109
-
4110
- // HangingProtocol has matched, but don't have all the volumes created yet, so return
4111
- if (!Array.from(volumeIdMapsToLoad.values()).includes(SeriesInstanceUID)) {
4112
- return;
4113
- }
4112
+ displaySetsInfo
4113
+ } = matchDetail;
4114
+ displaySetsInfo.forEach(({
4115
+ displaySetInstanceUID
4116
+ }) => {
4117
+ uniqueMatchedDisplaySetUIDs.add(displaySetInstanceUID);
4118
+ });
4119
+ });
4120
+ if (uniqueViewportVolumeDisplaySetUIDs.size !== uniqueMatchedDisplaySetUIDs.size) {
4121
+ return;
4114
4122
  }
4115
4123
  const volumeIds = Array.from(volumeIdMapsToLoad.keys()).slice();
4116
4124
  // get volumes from cache
@@ -4413,21 +4421,28 @@ function interleaveTopToBottom({
4413
4421
  * listen to it and as the other viewports are created we can set the volumes for them
4414
4422
  * since volumes are already started loading.
4415
4423
  */
4416
- if (filteredMatchDetails.length !== interleaveTopToBottom_viewportIdVolumeInputArrayMap.size) {
4417
- return;
4418
- }
4419
-
4420
- // Check if all the matched volumes are loaded
4421
- for (const [_, details] of displaySetsMatchDetails.entries()) {
4424
+ const uniqueViewportVolumeDisplaySetUIDs = new Set();
4425
+ interleaveTopToBottom_viewportIdVolumeInputArrayMap.forEach((volumeInputArray, viewportId) => {
4426
+ volumeInputArray.forEach(volumeInput => {
4427
+ const {
4428
+ volumeId
4429
+ } = volumeInput;
4430
+ uniqueViewportVolumeDisplaySetUIDs.add(volumeId);
4431
+ });
4432
+ });
4433
+ const uniqueMatchedDisplaySetUIDs = new Set();
4434
+ matchDetails.forEach(matchDetail => {
4422
4435
  const {
4423
- SeriesInstanceUID,
4436
+ displaySetsInfo
4437
+ } = matchDetail;
4438
+ displaySetsInfo.forEach(({
4424
4439
  displaySetInstanceUID
4425
- } = details;
4426
-
4427
- // HangingProtocol has matched, but don't have all the volumes created yet, so return
4428
- if (displaySetsToLoad.has(displaySetInstanceUID) && !Array.from(interleaveTopToBottom_volumeIdMapsToLoad.values()).includes(SeriesInstanceUID)) {
4429
- return;
4430
- }
4440
+ }) => {
4441
+ uniqueMatchedDisplaySetUIDs.add(displaySetInstanceUID);
4442
+ });
4443
+ });
4444
+ if (uniqueViewportVolumeDisplaySetUIDs.size !== uniqueMatchedDisplaySetUIDs.size) {
4445
+ return;
4431
4446
  }
4432
4447
  const volumeIds = Array.from(interleaveTopToBottom_volumeIdMapsToLoad.keys()).slice();
4433
4448
  // get volumes from cache
@@ -4824,6 +4839,7 @@ const colormaps = [{
4824
4839
 
4825
4840
 
4826
4841
 
4842
+
4827
4843
  const {
4828
4844
  registerColormap
4829
4845
  } = esm.utilities.colormap;
@@ -5053,6 +5069,22 @@ async function init({
5053
5069
  esm.eventTarget.addEventListener(esm.EVENTS.ELEMENT_ENABLED, elementEnabledHandler.bind(null));
5054
5070
  esm.eventTarget.addEventListener(esm.EVENTS.ELEMENT_DISABLED, elementDisabledHandler.bind(null));
5055
5071
  colormaps.forEach(registerColormap);
5072
+
5073
+ // Create a debounced function that shows the notification
5074
+ const debouncedShowNotification = (0,lodash.debounce)(detail => {
5075
+ uiNotificationService.show({
5076
+ title: detail.type,
5077
+ message: detail.message,
5078
+ type: 'error'
5079
+ });
5080
+ }, 300);
5081
+
5082
+ // Event listener
5083
+ esm.eventTarget.addEventListener(esm.EVENTS.ERROR_EVENT, ({
5084
+ detail
5085
+ }) => {
5086
+ debouncedShowNotification(detail);
5087
+ });
5056
5088
  }
5057
5089
  function CPUModal() {
5058
5090
  return /*#__PURE__*/react.createElement("div", null, /*#__PURE__*/react.createElement("p", null, "Your computer does not have enough GPU power to support the default GPU rendering mode. OHIF has switched to CPU rendering mode. Please note that CPU rendering does not support all features such as Volume Rendering, Multiplanar Reconstruction, and Segmentation Overlays."));
@@ -5940,7 +5972,8 @@ const CornerstoneViewportDownloadForm = ({
5940
5972
  const activeViewportEnabledElement = (0,esm.getEnabledElement)(activeViewportElement);
5941
5973
  const {
5942
5974
  viewportId: activeViewportId,
5943
- renderingEngineId
5975
+ renderingEngineId,
5976
+ viewport: activeViewport
5944
5977
  } = activeViewportEnabledElement;
5945
5978
  const toolGroup = dist_esm.ToolGroupManager.getToolGroupForViewport(activeViewportId, renderingEngineId);
5946
5979
  const toolModeAndBindings = Object.keys(toolGroup.toolOptions).reduce((acc, toolName) => {
@@ -6012,7 +6045,7 @@ const CornerstoneViewportDownloadForm = ({
6012
6045
  renderingEngine.resize();
6013
6046
 
6014
6047
  // Trigger the render on the viewport to update the on screen
6015
- downloadViewport.resetCamera();
6048
+ // downloadViewport.resetCamera();
6016
6049
  downloadViewport.render();
6017
6050
  downloadViewportElement.addEventListener(esm.Enums.Events.IMAGE_RENDERED, function updateViewport(event) {
6018
6051
  const enabledElement = (0,esm.getEnabledElement)(event.target);
@@ -6038,6 +6071,12 @@ const CornerstoneViewportDownloadForm = ({
6038
6071
  height: newHeight
6039
6072
  });
6040
6073
  downloadViewportElement.removeEventListener(esm.Enums.Events.IMAGE_RENDERED, updateViewport);
6074
+
6075
+ // for some reason we need a reset camera here, and I don't know why
6076
+ downloadViewport.resetCamera();
6077
+ const presentation = activeViewport.getViewPresentation();
6078
+ downloadViewport.setView(activeViewport.getViewReference(), presentation);
6079
+ downloadViewport.render();
6041
6080
  });
6042
6081
  });
6043
6082
  const loadImage = (activeViewportElement, viewportElement, width, height) => new Promise(resolve => {
@@ -6074,7 +6113,6 @@ const CornerstoneViewportDownloadForm = ({
6074
6113
  actors.forEach(actor => {
6075
6114
  downloadViewport.addActor(actor);
6076
6115
  });
6077
- downloadViewport.setCamera(viewport.getCamera());
6078
6116
  downloadViewport.render();
6079
6117
  const newWidth = Math.min(width || image.width, MAX_TEXTURE_SIZE);
6080
6118
  const newHeight = Math.min(height || image.height, MAX_TEXTURE_SIZE);
@@ -6365,6 +6403,10 @@ function commandsModule({
6365
6403
  function _getActiveViewportEnabledElement() {
6366
6404
  return getActiveViewportEnabledElement(viewportGridService);
6367
6405
  }
6406
+ function _getActiveViewportToolGroupId() {
6407
+ const viewport = _getActiveViewportEnabledElement();
6408
+ return toolGroupService.getToolGroupForViewport(viewport.id);
6409
+ }
6368
6410
  const actions = {
6369
6411
  /**
6370
6412
  * Generates the selector props for the context menu, specific to
@@ -6641,47 +6683,45 @@ function commandsModule({
6641
6683
  toggleEnabledDisabledToolbar({
6642
6684
  value,
6643
6685
  itemId,
6644
- toolGroupIds = []
6686
+ toolGroupId
6645
6687
  }) {
6646
6688
  const toolName = itemId || value;
6647
- toolGroupIds = toolGroupIds.length ? toolGroupIds : toolGroupService.getToolGroupIds();
6648
- toolGroupIds.forEach(toolGroupId => {
6649
- const toolGroup = toolGroupService.getToolGroup(toolGroupId);
6650
- if (!toolGroup || !toolGroup.hasTool(toolName)) {
6651
- return;
6652
- }
6653
- const toolIsEnabled = toolGroup.getToolOptions(toolName).mode === dist_esm.Enums.ToolModes.Enabled;
6654
- toolIsEnabled ? toolGroup.setToolDisabled(toolName) : toolGroup.setToolEnabled(toolName);
6655
- });
6689
+ toolGroupId = toolGroupId ?? _getActiveViewportToolGroupId();
6690
+ const toolGroup = toolGroupService.getToolGroup(toolGroupId);
6691
+ if (!toolGroup || !toolGroup.hasTool(toolName)) {
6692
+ return;
6693
+ }
6694
+ const toolIsEnabled = toolGroup.getToolOptions(toolName).mode === dist_esm.Enums.ToolModes.Enabled;
6695
+ toolIsEnabled ? toolGroup.setToolDisabled(toolName) : toolGroup.setToolEnabled(toolName);
6656
6696
  },
6657
6697
  toggleActiveDisabledToolbar({
6658
6698
  value,
6659
6699
  itemId,
6660
- toolGroupIds = []
6700
+ toolGroupId
6661
6701
  }) {
6662
6702
  const toolName = itemId || value;
6663
- toolGroupIds = toolGroupIds.length ? toolGroupIds : toolGroupService.getToolGroupIds();
6664
- toolGroupIds.forEach(toolGroupId => {
6665
- const toolGroup = toolGroupService.getToolGroup(toolGroupId);
6666
- if (!toolGroup || !toolGroup.hasTool(toolName)) {
6667
- return;
6668
- }
6669
- const toolIsActive = toolGroup.getToolOptions(toolName).mode === dist_esm.Enums.ToolModes.Active;
6670
- toolIsActive ? toolGroup.setToolDisabled(toolName) : actions.setToolActive({
6671
- toolName,
6672
- toolGroupId
6673
- });
6703
+ toolGroupId = toolGroupId ?? _getActiveViewportToolGroupId();
6704
+ const toolGroup = toolGroupService.getToolGroup(toolGroupId);
6705
+ if (!toolGroup || !toolGroup.hasTool(toolName)) {
6706
+ return;
6707
+ }
6708
+ const toolIsActive = [dist_esm.Enums.ToolModes.Active, dist_esm.Enums.ToolModes.Enabled, dist_esm.Enums.ToolModes.Passive].includes(toolGroup.getToolOptions(toolName).mode);
6709
+ toolIsActive ? toolGroup.setToolDisabled(toolName) : actions.setToolActive({
6710
+ toolName,
6711
+ toolGroupId
6712
+ });
6674
6713
 
6675
- // we should set the previously active tool to active after we set the
6676
- // current tool disabled
6677
- if (toolIsActive) {
6678
- const prevToolName = toolGroup.getPrevActivePrimaryToolName();
6714
+ // we should set the previously active tool to active after we set the
6715
+ // current tool disabled
6716
+ if (toolIsActive) {
6717
+ const prevToolName = toolGroup.getPrevActivePrimaryToolName();
6718
+ if (prevToolName !== toolName) {
6679
6719
  actions.setToolActive({
6680
6720
  toolName: prevToolName,
6681
6721
  toolGroupId
6682
6722
  });
6683
6723
  }
6684
- });
6724
+ }
6685
6725
  },
6686
6726
  setToolActiveToolbar: ({
6687
6727
  value,
@@ -6793,15 +6833,13 @@ function commandsModule({
6793
6833
  const {
6794
6834
  viewport
6795
6835
  } = enabledElement;
6796
- if (viewport instanceof esm.StackViewport) {
6797
- const {
6798
- flipHorizontal
6799
- } = viewport.getCamera();
6800
- viewport.setCamera({
6801
- flipHorizontal: !flipHorizontal
6802
- });
6803
- viewport.render();
6804
- }
6836
+ const {
6837
+ flipHorizontal
6838
+ } = viewport.getCamera();
6839
+ viewport.setCamera({
6840
+ flipHorizontal: !flipHorizontal
6841
+ });
6842
+ viewport.render();
6805
6843
  },
6806
6844
  flipViewportVertical: () => {
6807
6845
  const enabledElement = _getActiveViewportEnabledElement();
@@ -6811,15 +6849,13 @@ function commandsModule({
6811
6849
  const {
6812
6850
  viewport
6813
6851
  } = enabledElement;
6814
- if (viewport instanceof esm.StackViewport) {
6815
- const {
6816
- flipVertical
6817
- } = viewport.getCamera();
6818
- viewport.setCamera({
6819
- flipVertical: !flipVertical
6820
- });
6821
- viewport.render();
6822
- }
6852
+ const {
6853
+ flipVertical
6854
+ } = viewport.getCamera();
6855
+ viewport.setCamera({
6856
+ flipVertical: !flipVertical
6857
+ });
6858
+ viewport.render();
6823
6859
  },
6824
6860
  invertViewport: ({
6825
6861
  element
@@ -7215,7 +7251,7 @@ function commandsModule({
7215
7251
  getCrosshairInstances(toolGroup.id);
7216
7252
  }
7217
7253
  crosshairInstances.forEach(ins => {
7218
- ins.resetCrosshairs();
7254
+ ins?.resetCrosshairs();
7219
7255
  });
7220
7256
  }
7221
7257
  };
@@ -8391,30 +8427,32 @@ function getToolbarModule({
8391
8427
  className: '!text-common-bright hover:!bg-primary-dark hover:text-primary-light'
8392
8428
  };
8393
8429
  }
8430
+ }, {
8431
+ name: 'evaluate.cornerstoneTool.toggle.ifStrictlyDisabled',
8432
+ evaluate: ({
8433
+ viewportId,
8434
+ button,
8435
+ disabledText
8436
+ }) => _evaluateToggle({
8437
+ viewportId,
8438
+ button,
8439
+ disabledText,
8440
+ offModes: [dist_esm.Enums.ToolModes.Disabled],
8441
+ toolGroupService
8442
+ })
8394
8443
  }, {
8395
8444
  name: 'evaluate.cornerstoneTool.toggle',
8396
8445
  evaluate: ({
8397
8446
  viewportId,
8398
8447
  button,
8399
8448
  disabledText
8400
- }) => {
8401
- const toolGroup = toolGroupService.getToolGroupForViewport(viewportId);
8402
- if (!toolGroup) {
8403
- return;
8404
- }
8405
- const toolName = getToolNameForButton(button);
8406
- if (!toolGroup || !toolGroup.hasTool(toolName)) {
8407
- return {
8408
- disabled: true,
8409
- className: '!text-common-bright ohif-disabled',
8410
- disabledText: disabledText ?? 'Not available on the current viewport'
8411
- };
8412
- }
8413
- const isOff = [dist_esm.Enums.ToolModes.Disabled, dist_esm.Enums.ToolModes.Passive].includes(toolGroup.getToolOptions(toolName).mode);
8414
- return {
8415
- className: getToggledClassName(!isOff)
8416
- };
8417
- }
8449
+ }) => _evaluateToggle({
8450
+ viewportId,
8451
+ button,
8452
+ disabledText,
8453
+ offModes: [dist_esm.Enums.ToolModes.Disabled, dist_esm.Enums.ToolModes.Passive],
8454
+ toolGroupService
8455
+ })
8418
8456
  }, {
8419
8457
  name: 'evaluate.cornerstone.synchronizer',
8420
8458
  evaluate: ({
@@ -8427,7 +8465,8 @@ function getToolbarModule({
8427
8465
  className: getToggledClassName(false)
8428
8466
  };
8429
8467
  }
8430
- const synchronizerType = button?.commands?.[0]?.commandOptions?.type;
8468
+ const isArray = Array.isArray(button.commands);
8469
+ const synchronizerType = isArray ? button.commands?.[0].commandOptions.type : button.commands?.commandOptions.type;
8431
8470
  synchronizers = syncGroupService.getSynchronizersOfType(synchronizerType);
8432
8471
  if (!synchronizers?.length) {
8433
8472
  return {
@@ -8536,6 +8575,32 @@ function getToolbarModule({
8536
8575
  }
8537
8576
  }];
8538
8577
  }
8578
+ function _evaluateToggle({
8579
+ viewportId,
8580
+ button,
8581
+ disabledText,
8582
+ offModes,
8583
+ toolGroupService
8584
+ }) {
8585
+ const toolGroup = toolGroupService.getToolGroupForViewport(viewportId);
8586
+ if (!toolGroup) {
8587
+ return;
8588
+ }
8589
+ const toolName = getToolNameForButton(button);
8590
+ if (!toolGroup.hasTool(toolName)) {
8591
+ return {
8592
+ disabled: true,
8593
+ className: '!text-common-bright ohif-disabled',
8594
+ disabledText: disabledText ?? 'Not available on the current viewport'
8595
+ };
8596
+ }
8597
+ const isOff = offModes.includes(toolGroup.getToolOptions(toolName).mode);
8598
+ return {
8599
+ className: getToggledClassName(!isOff)
8600
+ };
8601
+ }
8602
+
8603
+ // Todo: this is duplicate, we should move it to a shared location
8539
8604
  function getToolNameForButton(button) {
8540
8605
  const {
8541
8606
  props
@@ -8543,11 +8608,7 @@ function getToolNameForButton(button) {
8543
8608
  const commands = props?.commands || button.commands;
8544
8609
  const commandsArray = Array.isArray(commands) ? commands : [commands];
8545
8610
  const firstCommand = commandsArray[0];
8546
- if (typeof firstCommand === 'string') {
8547
- // likely not a cornerstone tool
8548
- return null;
8549
- }
8550
- if ('commandOptions' in firstCommand) {
8611
+ if (firstCommand?.commandOptions) {
8551
8612
  return firstCommand.commandOptions.toolName ?? props?.id ?? button.id;
8552
8613
  }
8553
8614
 
@@ -10677,7 +10738,10 @@ class CornerstoneCacheService {
10677
10738
  // as a reference volume, if so, we should hang a volume viewport
10678
10739
  // instead of a stack viewport
10679
10740
  if (this._shouldRenderSegmentation(displaySets)) {
10680
- viewportType = 'volume';
10741
+ // if the viewport type is volume 3D, we should let it be as it is
10742
+ // Todo: in future here we should kick start the conversion of the
10743
+ // segmentation to closed surface
10744
+ viewportType = viewportType === esm.Enums.ViewportType.VOLUME_3D ? esm.Enums.ViewportType.VOLUME_3D : 'volume';
10681
10745
 
10682
10746
  // update viewportOptions to reflect the new viewport type
10683
10747
  viewportOptions.viewportType = viewportType;
@@ -11228,7 +11292,7 @@ class CornerstoneViewportService extends src/* PubSubService */.Rc {
11228
11292
  const {
11229
11293
  presentation
11230
11294
  } = lutPresentation;
11231
- if (viewport instanceof esm.VolumeViewport) {
11295
+ if (viewport instanceof esm.BaseVolumeViewport) {
11232
11296
  if (presentation instanceof Map) {
11233
11297
  presentation.forEach((properties, volumeId) => {
11234
11298
  viewport.setProperties(properties, volumeId);
@@ -12939,13 +13003,19 @@ const cornerstoneExtension = {
12939
13003
  * Only required property. Should be a unique value across all extensions.
12940
13004
  */
12941
13005
  id: id,
12942
- onModeExit: () => {
13006
+ onModeExit: ({
13007
+ servicesManager
13008
+ }) => {
13009
+ const {
13010
+ cineService
13011
+ } = servicesManager.services;
12943
13012
  // Empty out the image load and retrieval pools to prevent memory leaks
12944
13013
  // on the mode exits
12945
13014
  Object.values(esm.Enums.RequestType).forEach(type => {
12946
13015
  esm.imageLoadPoolManager.clearRequestStack(type);
12947
13016
  esm.imageRetrievalPoolManager.clearRequestStack(type);
12948
13017
  });
13018
+ cineService.setIsCineEnabled(false);
12949
13019
  (0,state/* reset */.cL)();
12950
13020
  },
12951
13021
  /**
@@ -101,11 +101,6 @@ function initDefaultToolGroup(extensionManager, toolGroupService, commandsManage
101
101
  toolName: toolNames.SegmentationDisplay
102
102
  }, {
103
103
  toolName: toolNames.CalibrationLine
104
- }, {
105
- toolName: toolNames.AdvancedMagnify,
106
- configuration: {
107
- disableOnPassive: true
108
- }
109
104
  }, {
110
105
  toolName: toolNames.UltrasoundDirectional
111
106
  }, {
@@ -115,11 +110,13 @@ function initDefaultToolGroup(extensionManager, toolGroupService, commandsManage
115
110
  }, {
116
111
  toolName: toolNames.LivewireContour
117
112
  }],
118
- // enabled
119
113
  enabled: [{
120
114
  toolName: toolNames.ImageOverlayViewer
121
115
  }, {
122
116
  toolName: toolNames.ReferenceLines
117
+ }],
118
+ disabled: [{
119
+ toolName: toolNames.AdvancedMagnify
123
120
  }]
124
121
  };
125
122
  toolGroupService.createToolGroupAndAddTools(toolGroupId, tools);
@@ -265,12 +262,11 @@ function initMPRToolGroup(extensionManager, toolGroupService, commandsManager, m
265
262
  panSize: 10
266
263
  }
267
264
  }
265
+ }, {
266
+ toolName: toolNames.AdvancedMagnify
268
267
  }, {
269
268
  toolName: toolNames.ReferenceLines
270
269
  }]
271
-
272
- // enabled
273
- // disabled
274
270
  };
275
271
  toolGroupService.createToolGroupAndAddTools('mpr', tools);
276
272
  }
@@ -499,18 +495,6 @@ const ReferenceLinesListeners = [{
499
495
  commandName: 'setSourceViewportForReferenceLinesTool',
500
496
  context: 'CORNERSTONE'
501
497
  }];
502
- const toggleEnabledDisabledToolbar = {
503
- commandName: 'toggleEnabledDisabledToolbar',
504
- commandOptions: {
505
- toolGroupIds: ['default', 'mpr', 'SRToolGroup', 'volume3d']
506
- }
507
- };
508
- const toggleActiveDisabledToolbar = {
509
- commandName: 'toggleActiveDisabledToolbar',
510
- commandOptions: {
511
- toolGroupIds: ['default', 'mpr', 'SRToolGroup']
512
- }
513
- };
514
498
  const moreTools = [{
515
499
  id: 'MoreTools',
516
500
  uiType: 'ohif.splitButton',
@@ -576,7 +560,7 @@ const moreTools = [{
576
560
  icon: 'tool-referenceLines',
577
561
  label: 'Reference Lines',
578
562
  tooltip: 'Show Reference Lines',
579
- commands: toggleEnabledDisabledToolbar,
563
+ commands: 'toggleEnabledDisabledToolbar',
580
564
  listeners: {
581
565
  [src/* ViewportGridService */.sI.EVENTS.ACTIVE_VIEWPORT_ID_CHANGED]: ReferenceLinesListeners,
582
566
  [src/* ViewportGridService */.sI.EVENTS.VIEWPORTS_READY]: ReferenceLinesListeners
@@ -587,7 +571,7 @@ const moreTools = [{
587
571
  icon: 'toggle-dicom-overlay',
588
572
  label: 'Image Overlay',
589
573
  tooltip: 'Toggle Image Overlay',
590
- commands: toggleEnabledDisabledToolbar,
574
+ commands: 'toggleEnabledDisabledToolbar',
591
575
  evaluate: 'evaluate.cornerstoneTool.toggle'
592
576
  }), moreTools_createButton({
593
577
  id: 'StackScroll',
@@ -649,8 +633,8 @@ const moreTools = [{
649
633
  icon: 'icon-tool-loupe',
650
634
  label: 'Loupe',
651
635
  tooltip: 'Loupe',
652
- commands: toggleActiveDisabledToolbar,
653
- evaluate: 'evaluate.cornerstoneTool.toggle'
636
+ commands: 'toggleActiveDisabledToolbar',
637
+ evaluate: 'evaluate.cornerstoneTool.toggle.ifStrictlyDisabled'
654
638
  }), moreTools_createButton({
655
639
  id: 'UltrasoundDirectionalTool',
656
640
  icon: 'icon-tool-ultrasound-bidirectional',