@ohif/app 3.8.0-beta.72 → 3.8.0-beta.74

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 (46) hide show
  1. package/dist/{121.bundle.21827fec690c01ee9ab3.js → 121.bundle.bd8acf52b6a7047ae832.js} +2 -2
  2. package/dist/141.bundle.556b4c1e4cab770417ac.js +8620 -0
  3. package/dist/{191.bundle.c0ea2d031ffddeca32c9.js → 183.bundle.25293de927ef032a6695.js} +195 -122
  4. package/dist/{188.bundle.c23415079424cb48aa70.js → 188.bundle.f1b3909e55be12d37c4a.js} +2 -2
  5. package/dist/{987.bundle.e19408decfd59aadd118.js → 217.bundle.9631d914f170f8d7ef63.js} +31558 -39396
  6. package/dist/{295.bundle.3a0d5062d65296c4bf5d.js → 295.bundle.688b6bbff493cd904ae7.js} +2 -2
  7. package/dist/{155.bundle.bebcbc0ca715c7163f18.js → 325.bundle.3d260b1a7f80cfc892a0.js} +43 -58
  8. package/dist/{425.bundle.fa277d2575477589ff4a.js → 335.bundle.ec53cc58116ef1dc5fa3.js} +132 -518
  9. package/dist/{342.bundle.521c0217f82380c0c2ad.js → 342.bundle.c6165579c4ac3ef0d6a8.js} +2 -2
  10. package/dist/{41.bundle.9db45ce95f2fd889447d.js → 41.bundle.3c9bb4e3800dcea2c043.js} +28 -29
  11. package/dist/{433.bundle.6f2308ab10593784778c.js → 433.bundle.1474591f213852cffcba.js} +188 -172
  12. package/dist/{290.bundle.952de53057f98e2c5ef0.js → 445.bundle.38c6d2af64e41cd7c614.js} +1 -1049
  13. package/dist/{448.bundle.2f5b66d084f92c556edd.js → 448.bundle.e6af6868af55a353b12b.js} +16 -22
  14. package/dist/487.bundle.de932b440ffc809978b5.js +1875 -0
  15. package/dist/{530.bundle.f4b7966fb33eafb8cd5d.js → 530.bundle.7c94543955552475c56a.js} +9 -9
  16. package/dist/{540.bundle.792745c8d390c3fc83cf.js → 540.bundle.31780163f7065fd4d325.js} +15 -15
  17. package/dist/{544.bundle.1110b24e96863d719a95.js → 544.bundle.fcb790bae53294b49b05.js} +8 -8
  18. package/dist/{574.bundle.2b3369042aad5d553463.js → 574.bundle.b4eb8773d7741868e84b.js} +166 -45
  19. package/dist/{594.bundle.2af345e8ec58d538a9ae.js → 594.bundle.6c0b915507752363e82a.js} +4 -4
  20. package/dist/{2.bundle.a423ca428b035655c6eb.js → 633.bundle.7f782a390a22d9c7ec1d.js} +35 -43
  21. package/dist/{699.bundle.3783f122f84be6a5eb30.js → 699.bundle.7642c1505c1685f63897.js} +18 -35
  22. package/dist/702.bundle.963481fbf871984b646f.js +8426 -0
  23. package/dist/722.bundle.afab1fe6bfcd569130ac.js +1083 -0
  24. package/dist/{724.bundle.abdadacc4d7497aa7431.js → 724.bundle.ad52afcbec7501305d25.js} +20 -11
  25. package/dist/{90.bundle.3c0e23243f8ad444dcb5.js → 83.bundle.ff7db010621303a71a50.js} +419 -137
  26. package/dist/{862.bundle.47305c27f0fb939c2f97.js → 862.bundle.f49a379497bb3b43a942.js} +3 -3
  27. package/dist/{889.bundle.9ca0963a74448c6b0366.js → 889.bundle.67ca151a5e2d653b0021.js} +8 -8
  28. package/dist/{595.bundle.d9e4c2a6311ce8ed929b.js → 896.bundle.ba0b4c73e2331281159f.js} +686 -57
  29. package/dist/{905.bundle.aa96c1209ab1b78fdf2b.js → 905.bundle.e67fd55073b8ff735ed5.js} +4 -4
  30. package/dist/{907.bundle.f8db9076d882586ac6e6.js → 907.bundle.0167da9471dcfa5c862e.js} +2 -2
  31. package/dist/94.bundle.ccec301dfb972a375ecc.js +784 -0
  32. package/dist/{961.bundle.0114ec1cc534b2b7739f.js → 961.bundle.711da9767a4e31ea5aef.js} +2 -2
  33. package/dist/{app.bundle.8aa9dfeaad37206d66e3.js → app.bundle.c0c40b901a1bf1043f08.js} +98584 -89435
  34. package/dist/app.bundle.css +5 -4
  35. package/dist/cornerstoneDICOMImageLoader.min.js +1 -1
  36. package/dist/cornerstoneDICOMImageLoader.min.js.map +1 -1
  37. package/dist/histogram-worker.bundle.829e14ec12c2b41a4323.js +359 -0
  38. package/dist/index.html +1 -1
  39. package/dist/{polySeg.bundle.fe47718e6a8414f175b1.js → polySeg.bundle.c503e9460cef894737cd.js} +3 -6
  40. package/dist/sw.js +1 -1
  41. package/package.json +20 -19
  42. package/dist/425.css +0 -2
  43. /package/dist/{164.bundle.403c8665844596f8a320.js → 164.bundle.55df0a2c8b3569d8e1f9.js} +0 -0
  44. /package/dist/{155.css → 325.css} +0 -0
  45. /package/dist/{2.css → 633.css} +0 -0
  46. /package/dist/{595.css → 896.css} +0 -0
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- (globalThis["webpackChunk"] = globalThis["webpackChunk"] || []).push([[595],{
2
+ (globalThis["webpackChunk"] = globalThis["webpackChunk"] || []).push([[896],{
3
3
 
4
4
  /***/ 76255:
5
5
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
@@ -12,7 +12,7 @@
12
12
  /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(41766);
13
13
  /* harmony import */ var prop_types__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11374);
14
14
  /* harmony import */ var prop_types__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(prop_types__WEBPACK_IMPORTED_MODULE_1__);
15
- /* harmony import */ var _ohif_ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(48804);
15
+ /* harmony import */ var _ohif_ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5085);
16
16
  /* harmony import */ var _services_ViewportActionCornersService_ViewportActionCornersService__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(77954);
17
17
 
18
18
 
@@ -141,7 +141,7 @@ const useViewportActionCornersContext = () => (0,react__WEBPACK_IMPORTED_MODULE_
141
141
 
142
142
  /***/ }),
143
143
 
144
- /***/ 92595:
144
+ /***/ 72896:
145
145
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
146
146
 
147
147
  // ESM COMPAT FLAG
@@ -175,14 +175,14 @@ __webpack_require__.r(types_namespaceObject);
175
175
 
176
176
  // EXTERNAL MODULE: ../../../node_modules/react/index.js
177
177
  var react = __webpack_require__(41766);
178
- // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/core/dist/esm/index.js + 383 modules
179
- var esm = __webpack_require__(50719);
180
- // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/index.js + 16 modules
181
- var dist_esm = __webpack_require__(20767);
182
- // EXTERNAL MODULE: ../../core/src/index.ts + 68 modules
183
- var src = __webpack_require__(85073);
178
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/core/dist/esm/index.js + 327 modules
179
+ var esm = __webpack_require__(44656);
180
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/index.js + 18 modules
181
+ var dist_esm = __webpack_require__(24542);
184
182
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/streaming-image-volume-loader/dist/esm/index.js + 13 modules
185
183
  var streaming_image_volume_loader_dist_esm = __webpack_require__(23722);
184
+ // EXTERNAL MODULE: ../../core/src/index.ts + 70 modules
185
+ var src = __webpack_require__(55411);
186
186
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/dicom-image-loader/dist/dynamic-import/cornerstoneDICOMImageLoader.min.js
187
187
  var cornerstoneDICOMImageLoader_min = __webpack_require__(54578);
188
188
  var cornerstoneDICOMImageLoader_min_default = /*#__PURE__*/__webpack_require__.n(cornerstoneDICOMImageLoader_min);
@@ -221,6 +221,7 @@ function initWADOImageLoader(userAuthenticationService, appConfig, extensionMana
221
221
  (cornerstoneDICOMImageLoader_min_default()).external.cornerstone = esm;
222
222
  (cornerstoneDICOMImageLoader_min_default()).external.dicomParser = (dicomParser_min_default());
223
223
  registerVolumeLoader('cornerstoneStreamingImageVolume', streaming_image_volume_loader_dist_esm/* cornerstoneStreamingImageVolumeLoader */.FC);
224
+ registerVolumeLoader('cornerstoneStreamingDynamicImageVolume', streaming_image_volume_loader_dist_esm/* cornerstoneStreamingDynamicImageVolumeLoader */.Mr);
224
225
  cornerstoneDICOMImageLoader_min_default().configure({
225
226
  decodeConfig: {
226
227
  // !! IMPORTANT !!
@@ -259,8 +260,8 @@ function destroy() {
259
260
  }
260
261
  webWorkers.length = 0;
261
262
  }
262
- // EXTERNAL MODULE: ../../ui/src/index.js + 542 modules
263
- var ui_src = __webpack_require__(48804);
263
+ // EXTERNAL MODULE: ../../ui/src/index.js + 785 modules
264
+ var ui_src = __webpack_require__(5085);
264
265
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/callInputDialog.tsx
265
266
 
266
267
 
@@ -836,6 +837,7 @@ function initCornerstoneTools(configuration = {}) {
836
837
  (0,dist_esm.addTool)(dist_esm.MIPJumpToClickTool);
837
838
  (0,dist_esm.addTool)(dist_esm.LengthTool);
838
839
  (0,dist_esm.addTool)(dist_esm.RectangleROITool);
840
+ (0,dist_esm.addTool)(dist_esm.RectangleROIThresholdTool);
839
841
  (0,dist_esm.addTool)(dist_esm.EllipticalROITool);
840
842
  (0,dist_esm.addTool)(dist_esm.CircleROITool);
841
843
  (0,dist_esm.addTool)(dist_esm.BidirectionalTool);
@@ -846,12 +848,14 @@ function initCornerstoneTools(configuration = {}) {
846
848
  (0,dist_esm.addTool)(dist_esm.MagnifyTool);
847
849
  (0,dist_esm.addTool)(dist_esm.CrosshairsTool);
848
850
  (0,dist_esm.addTool)(dist_esm.SegmentationDisplayTool);
851
+ (0,dist_esm.addTool)(dist_esm.RectangleScissorsTool);
852
+ (0,dist_esm.addTool)(dist_esm.SphereScissorsTool);
853
+ (0,dist_esm.addTool)(dist_esm.CircleScissorsTool);
854
+ (0,dist_esm.addTool)(dist_esm.BrushTool);
855
+ (0,dist_esm.addTool)(dist_esm.PaintFillTool);
849
856
  (0,dist_esm.addTool)(dist_esm.ReferenceLinesTool);
850
857
  (0,dist_esm.addTool)(tools_CalibrationLineTool);
851
858
  (0,dist_esm.addTool)(dist_esm.TrackballRotateTool);
852
- (0,dist_esm.addTool)(dist_esm.CircleScissorsTool);
853
- (0,dist_esm.addTool)(dist_esm.RectangleScissorsTool);
854
- (0,dist_esm.addTool)(dist_esm.SphereScissorsTool);
855
859
  (0,dist_esm.addTool)(tools_ImageOverlayViewerTool);
856
860
  (0,dist_esm.addTool)(dist_esm.AdvancedMagnifyTool);
857
861
  (0,dist_esm.addTool)(dist_esm.UltrasoundDirectionalTool);
@@ -885,6 +889,7 @@ const toolNames = {
885
889
  DragProbe: dist_esm.DragProbeTool.toolName,
886
890
  Probe: dist_esm.ProbeTool.toolName,
887
891
  RectangleROI: dist_esm.RectangleROITool.toolName,
892
+ RectangleROIThreshold: dist_esm.RectangleROIThresholdTool.toolName,
888
893
  EllipticalROI: dist_esm.EllipticalROITool.toolName,
889
894
  CircleROI: dist_esm.CircleROITool.toolName,
890
895
  Bidirectional: dist_esm.BidirectionalTool.toolName,
@@ -893,6 +898,8 @@ const toolNames = {
893
898
  Magnify: dist_esm.MagnifyTool.toolName,
894
899
  Crosshairs: dist_esm.CrosshairsTool.toolName,
895
900
  SegmentationDisplay: dist_esm.SegmentationDisplayTool.toolName,
901
+ Brush: dist_esm.BrushTool.toolName,
902
+ PaintFill: dist_esm.PaintFillTool.toolName,
896
903
  ReferenceLines: dist_esm.ReferenceLinesTool.toolName,
897
904
  CalibrationLine: tools_CalibrationLineTool.toolName,
898
905
  TrackballRotateTool: dist_esm.TrackballRotateTool.toolName,
@@ -2841,6 +2848,13 @@ const initMeasurementService = (measurementService, displaySetService, cornersto
2841
2848
 
2842
2849
  /* Mappings */
2843
2850
  measurementService.addMapping(csTools3DVer1MeasurementSource, 'Length', Length.matchingCriteria, Length.toAnnotation, Length.toMeasurement);
2851
+ measurementService.addMapping(csTools3DVer1MeasurementSource, 'Crosshairs', Length.matchingCriteria, () => {
2852
+ console.warn('Crosshairs mapping not implemented.');
2853
+ return {};
2854
+ }, () => {
2855
+ console.warn('Crosshairs mapping not implemented.');
2856
+ return {};
2857
+ });
2844
2858
  measurementService.addMapping(csTools3DVer1MeasurementSource, 'Bidirectional', Bidirectional.matchingCriteria, Bidirectional.toAnnotation, Bidirectional.toMeasurement);
2845
2859
  measurementService.addMapping(csTools3DVer1MeasurementSource, 'EllipticalROI', EllipticalROI.matchingCriteria, EllipticalROI.toAnnotation, EllipticalROI.toMeasurement);
2846
2860
  measurementService.addMapping(csTools3DVer1MeasurementSource, 'CircleROI', CircleROI.matchingCriteria, CircleROI.toAnnotation, CircleROI.toMeasurement);
@@ -3124,7 +3138,61 @@ const connectMeasurementServiceToTools = (measurementService, cornerstoneViewpor
3124
3138
 
3125
3139
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/initCineService.ts
3126
3140
 
3127
- function initCineService(cineService) {
3141
+
3142
+ function _getVolumesFromViewport(viewport) {
3143
+ return viewport ? viewport.getActors().map(actor => esm.cache.getVolume(actor.uid)) : [];
3144
+ }
3145
+ function _getVolumeFromViewport(viewport) {
3146
+ const volumes = _getVolumesFromViewport(viewport);
3147
+ const dynamicVolume = volumes.find(volume => volume.isDynamicVolume());
3148
+ return dynamicVolume ?? volumes[0];
3149
+ }
3150
+
3151
+ /**
3152
+ * Return all viewports that needs to be synchronized with the source
3153
+ * viewport passed as parameter when cine is updated.
3154
+ * @param servicesManager ServiceManager
3155
+ * @param srcViewportIndex Source viewport index
3156
+ * @returns array with viewport information.
3157
+ */
3158
+ function _getSyncedViewports(servicesManager, srcViewportId) {
3159
+ const {
3160
+ viewportGridService,
3161
+ cornerstoneViewportService
3162
+ } = servicesManager.services;
3163
+ const {
3164
+ viewports: viewportsStates
3165
+ } = viewportGridService.getState();
3166
+ const srcViewportState = viewportsStates.get(srcViewportId);
3167
+ if (srcViewportState?.viewportOptions?.viewportType !== 'volume') {
3168
+ return [];
3169
+ }
3170
+ const srcViewport = cornerstoneViewportService.getCornerstoneViewport(srcViewportId);
3171
+ const srcVolume = srcViewport ? _getVolumeFromViewport(srcViewport) : null;
3172
+ if (!srcVolume?.isDynamicVolume()) {
3173
+ return [];
3174
+ }
3175
+ const {
3176
+ volumeId: srcVolumeId
3177
+ } = srcVolume;
3178
+ return Array.from(viewportsStates.values()).filter(({
3179
+ viewportId
3180
+ }) => {
3181
+ const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
3182
+ return viewportId !== srcViewportId && viewport?.hasVolumeId(srcVolumeId);
3183
+ }).map(({
3184
+ viewportId
3185
+ }) => ({
3186
+ viewportId
3187
+ }));
3188
+ }
3189
+ function initCineService(servicesManager) {
3190
+ const {
3191
+ cineService
3192
+ } = servicesManager.services;
3193
+ const getSyncedViewports = viewportId => {
3194
+ return _getSyncedViewports(servicesManager, viewportId);
3195
+ };
3128
3196
  const playClip = (element, playClipOptions) => {
3129
3197
  return dist_esm.utilities.cine.playClip(element, playClipOptions);
3130
3198
  };
@@ -3132,6 +3200,7 @@ function initCineService(cineService) {
3132
3200
  return dist_esm.utilities.cine.stopClip(element);
3133
3201
  };
3134
3202
  cineService.setServiceImplementation({
3203
+ getSyncedViewports,
3135
3204
  playClip,
3136
3205
  stopClip
3137
3206
  });
@@ -3525,6 +3594,33 @@ function interleaveTopToBottom({
3525
3594
  interleaveTopToBottom_volumeIdMapsToLoad.set(volumeId, metadata.SeriesInstanceUID);
3526
3595
  }
3527
3596
  }
3597
+ const filteredMatchDetails = [];
3598
+ const displaySetsToLoad = new Set();
3599
+
3600
+ // Check all viewports that have a displaySet to be loaded. In some cases
3601
+ // (eg: line chart viewports which is not a Cornerstone viewport) the
3602
+ // displaySet is created on the client and there are no instances to be
3603
+ // downloaded. For those viewports the displaySet may have the `skipLoading`
3604
+ // option set to true otherwise it may block the download of all other
3605
+ // instances resulting in blank viewports.
3606
+ Array.from(matchDetails.values()).forEach(curMatchDetails => {
3607
+ const {
3608
+ displaySetsInfo
3609
+ } = curMatchDetails;
3610
+ let numDisplaySetsToLoad = 0;
3611
+ displaySetsInfo.forEach(({
3612
+ displaySetInstanceUID,
3613
+ displaySetOptions
3614
+ }) => {
3615
+ if (!displaySetOptions?.options?.skipLoading) {
3616
+ numDisplaySetsToLoad++;
3617
+ displaySetsToLoad.add(displaySetInstanceUID);
3618
+ }
3619
+ });
3620
+ if (numDisplaySetsToLoad) {
3621
+ filteredMatchDetails.push(curMatchDetails);
3622
+ }
3623
+ });
3528
3624
 
3529
3625
  /**
3530
3626
  * The following is checking if all the viewports that were matched in the HP has been
@@ -3539,18 +3635,19 @@ function interleaveTopToBottom({
3539
3635
  * listen to it and as the other viewports are created we can set the volumes for them
3540
3636
  * since volumes are already started loading.
3541
3637
  */
3542
- if (matchDetails.size !== interleaveTopToBottom_viewportIdVolumeInputArrayMap.size) {
3638
+ if (filteredMatchDetails.length !== interleaveTopToBottom_viewportIdVolumeInputArrayMap.size) {
3543
3639
  return;
3544
3640
  }
3545
3641
 
3546
3642
  // Check if all the matched volumes are loaded
3547
3643
  for (const [_, details] of displaySetsMatchDetails.entries()) {
3548
3644
  const {
3549
- SeriesInstanceUID
3645
+ SeriesInstanceUID,
3646
+ displaySetInstanceUID
3550
3647
  } = details;
3551
3648
 
3552
3649
  // HangingProtocol has matched, but don't have all the volumes created yet, so return
3553
- if (!Array.from(interleaveTopToBottom_volumeIdMapsToLoad.values()).includes(SeriesInstanceUID)) {
3650
+ if (displaySetsToLoad.has(displaySetInstanceUID) && !Array.from(interleaveTopToBottom_volumeIdMapsToLoad.values()).includes(SeriesInstanceUID)) {
3554
3651
  return;
3555
3652
  }
3556
3653
  }
@@ -3949,7 +4046,6 @@ const colormaps = [{
3949
4046
 
3950
4047
 
3951
4048
 
3952
-
3953
4049
  const {
3954
4050
  registerColormap
3955
4051
  } = esm.utilities.colormap;
@@ -4009,7 +4105,6 @@ async function init({
4009
4105
  customizationService,
4010
4106
  uiModalService,
4011
4107
  uiNotificationService,
4012
- cineService,
4013
4108
  cornerstoneViewportService,
4014
4109
  hangingProtocolService,
4015
4110
  toolbarService,
@@ -4065,6 +4160,7 @@ async function init({
4065
4160
  });
4066
4161
  const metadataProvider = src/* default.classes */.Ay.classes.MetadataProvider;
4067
4162
  esm.volumeLoader.registerVolumeLoader('cornerstoneStreamingImageVolume', streaming_image_volume_loader_dist_esm/* cornerstoneStreamingImageVolumeLoader */.FC);
4163
+ esm.volumeLoader.registerVolumeLoader('cornerstoneStreamingDynamicImageVolume', streaming_image_volume_loader_dist_esm/* cornerstoneStreamingDynamicImageVolumeLoader */.Mr);
4068
4164
  hangingProtocolService.registerImageLoadStrategy('interleaveCenter', interleaveCenterLoader);
4069
4165
  hangingProtocolService.registerImageLoadStrategy('interleaveTopToBottom', interleaveTopToBottom);
4070
4166
  hangingProtocolService.registerImageLoadStrategy('nth', interleaveNthLoader);
@@ -4081,7 +4177,7 @@ async function init({
4081
4177
 
4082
4178
  /* Measurement Service */
4083
4179
  this.measurementServiceSource = connectToolsToMeasurementService(servicesManager);
4084
- src_initCineService(cineService);
4180
+ src_initCineService(servicesManager);
4085
4181
 
4086
4182
  // When a custom image load is performed, update the relevant viewports
4087
4183
  hangingProtocolService.subscribe(hangingProtocolService.EVENTS.CUSTOM_IMAGE_LOAD_PERFORMED, volumeInputArrayMap => {
@@ -4928,8 +5024,8 @@ function getCustomizationModule() {
4928
5024
  }];
4929
5025
  }
4930
5026
  /* harmony default export */ const src_getCustomizationModule = (getCustomizationModule);
4931
- // EXTERNAL MODULE: ../../../node_modules/gl-matrix/esm/index.js + 10 modules
4932
- var gl_matrix_esm = __webpack_require__(83636);
5027
+ // EXTERNAL MODULE: ../../../node_modules/gl-matrix/esm/index.js + 1 modules
5028
+ var gl_matrix_esm = __webpack_require__(44753);
4933
5029
  // EXTERNAL MODULE: ../../../node_modules/html2canvas/dist/html2canvas.esm.js
4934
5030
  var html2canvas_esm = __webpack_require__(90445);
4935
5031
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/CornerstoneViewportDownloadForm.tsx
@@ -5457,8 +5553,6 @@ function commandsModule({
5457
5553
  };
5458
5554
  return nearbyToolData?.metadata?.toolName && isAnnotation(nearbyToolData.metadata.toolName) ? nearbyToolData : null;
5459
5555
  },
5460
- // Measurement tool commands:
5461
-
5462
5556
  /** Delete the given measurement */
5463
5557
  deleteMeasurement: ({
5464
5558
  uid
@@ -5651,6 +5745,51 @@ function commandsModule({
5651
5745
  const renderingEngine = cornerstoneViewportService.getRenderingEngine();
5652
5746
  renderingEngine.render();
5653
5747
  },
5748
+ toggleEnabledDisabledToolbar({
5749
+ value,
5750
+ itemId,
5751
+ toolGroupIds = []
5752
+ }) {
5753
+ const toolName = itemId || value;
5754
+ toolGroupIds = toolGroupIds.length ? toolGroupIds : toolGroupService.getToolGroupIds();
5755
+ toolGroupIds.forEach(toolGroupId => {
5756
+ const toolGroup = toolGroupService.getToolGroup(toolGroupId);
5757
+ if (!toolGroup || !toolGroup.hasTool(toolName)) {
5758
+ return;
5759
+ }
5760
+ const toolIsEnabled = toolGroup.getToolOptions(toolName).mode === dist_esm.Enums.ToolModes.Enabled;
5761
+ toolIsEnabled ? toolGroup.setToolDisabled(toolName) : toolGroup.setToolEnabled(toolName);
5762
+ });
5763
+ },
5764
+ toggleActiveDisabledToolbar({
5765
+ value,
5766
+ itemId,
5767
+ toolGroupIds = []
5768
+ }) {
5769
+ const toolName = itemId || value;
5770
+ toolGroupIds = toolGroupIds.length ? toolGroupIds : toolGroupService.getToolGroupIds();
5771
+ toolGroupIds.forEach(toolGroupId => {
5772
+ const toolGroup = toolGroupService.getToolGroup(toolGroupId);
5773
+ if (!toolGroup || !toolGroup.hasTool(toolName)) {
5774
+ return;
5775
+ }
5776
+ const toolIsActive = toolGroup.getToolOptions(toolName).mode === dist_esm.Enums.ToolModes.Active;
5777
+ toolIsActive ? toolGroup.setToolDisabled(toolName) : actions.setToolActive({
5778
+ toolName,
5779
+ toolGroupId
5780
+ });
5781
+
5782
+ // we should set the previously active tool to active after we set the
5783
+ // current tool disabled
5784
+ if (toolIsActive) {
5785
+ const prevToolName = toolGroup.getPrevActivePrimaryToolName();
5786
+ actions.setToolActive({
5787
+ toolName: prevToolName,
5788
+ toolGroupId
5789
+ });
5790
+ }
5791
+ });
5792
+ },
5654
5793
  setToolActiveToolbar: ({
5655
5794
  value,
5656
5795
  itemId,
@@ -6026,6 +6165,21 @@ function commandsModule({
6026
6165
  viewportId
6027
6166
  });
6028
6167
  },
6168
+ updateVolumeData: ({
6169
+ volume
6170
+ }) => {
6171
+ // update vtkOpenGLTexture and imageData of computed volume
6172
+ const {
6173
+ imageData,
6174
+ vtkOpenGLTexture
6175
+ } = volume;
6176
+ const numSlices = imageData.getDimensions()[2];
6177
+ const slicesToUpdate = [...Array(numSlices).keys()];
6178
+ slicesToUpdate.forEach(i => {
6179
+ vtkOpenGLTexture.setUpdatedFrame(i);
6180
+ });
6181
+ imageData.modified();
6182
+ },
6029
6183
  attachProtocolViewportDataListener: ({
6030
6184
  protocol,
6031
6185
  stageIndex
@@ -6338,6 +6492,15 @@ function commandsModule({
6338
6492
  },
6339
6493
  toggleSynchronizer: {
6340
6494
  commandFn: actions.toggleSynchronizer
6495
+ },
6496
+ updateVolumeData: {
6497
+ commandFn: actions.updateVolumeData
6498
+ },
6499
+ toggleEnabledDisabledToolbar: {
6500
+ commandFn: actions.toggleEnabledDisabledToolbar
6501
+ },
6502
+ toggleActiveDisabledToolbar: {
6503
+ commandFn: actions.toggleActiveDisabledToolbar
6341
6504
  }
6342
6505
  };
6343
6506
  return {
@@ -7398,7 +7561,7 @@ function getToolbarModule({
7398
7561
  return;
7399
7562
  }
7400
7563
  const displaySets = displaySetUIDs.map(displaySetService.getDisplaySetByUID);
7401
- const isUS = displaySets.some(displaySet => displaySet.Modality === 'US');
7564
+ const isUS = displaySets.some(displaySet => displaySet?.Modality === 'US');
7402
7565
  if (!isUS) {
7403
7566
  return {
7404
7567
  disabled: true,
@@ -7483,13 +7646,16 @@ function getToolNameForButton(button) {
7483
7646
  return props?.id ?? button.id;
7484
7647
  }
7485
7648
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/services/ToolGroupService/ToolGroupService.ts
7486
- var _class;
7649
+ var _ToolGroupService;
7650
+
7487
7651
 
7488
7652
 
7489
7653
 
7490
7654
  const ToolGroupService_EVENTS = {
7491
7655
  VIEWPORT_ADDED: 'event::cornerstone::toolgroupservice:viewportadded',
7492
- TOOLGROUP_CREATED: 'event::cornerstone::toolgroupservice:toolgroupcreated'
7656
+ TOOLGROUP_CREATED: 'event::cornerstone::toolgroupservice:toolgroupcreated',
7657
+ TOOL_ACTIVATED: 'event::cornerstone::toolgroupservice:toolactivated',
7658
+ PRIMARY_TOOL_ACTIVATED: 'event::cornerstone::toolgroupservice:primarytoolactivated'
7493
7659
  };
7494
7660
  class ToolGroupService {
7495
7661
  constructor(serviceManager) {
@@ -7500,19 +7666,42 @@ class ToolGroupService {
7500
7666
  */
7501
7667
  this.listeners = void 0;
7502
7668
  this.EVENTS = void 0;
7669
+ this._onToolActivated = evt => {
7670
+ const {
7671
+ toolGroupId,
7672
+ toolName,
7673
+ toolBindingsOptions
7674
+ } = evt.detail;
7675
+ const isPrimaryTool = toolBindingsOptions.bindings?.some(binding => binding.mouseButton === dist_esm.Enums.MouseBindings.Primary);
7676
+ const callbackProps = {
7677
+ toolGroupId,
7678
+ toolName,
7679
+ toolBindingsOptions
7680
+ };
7681
+ this._broadcastEvent(ToolGroupService_EVENTS.TOOL_ACTIVATED, callbackProps);
7682
+ if (isPrimaryTool) {
7683
+ this._broadcastEvent(ToolGroupService_EVENTS.PRIMARY_TOOL_ACTIVATED, callbackProps);
7684
+ }
7685
+ };
7503
7686
  const {
7504
7687
  cornerstoneViewportService,
7505
- viewportGridService
7688
+ viewportGridService,
7689
+ uiNotificationService
7506
7690
  } = serviceManager.services;
7507
7691
  this.cornerstoneViewportService = cornerstoneViewportService;
7508
7692
  this.viewportGridService = viewportGridService;
7693
+ this.uiNotificationService = uiNotificationService;
7509
7694
  this.listeners = {};
7510
7695
  this.EVENTS = ToolGroupService_EVENTS;
7511
7696
  Object.assign(this, src/* pubSubServiceInterface */.Ml);
7697
+ this._init();
7512
7698
  }
7513
7699
  onModeExit() {
7514
7700
  this.destroy();
7515
7701
  }
7702
+ _init() {
7703
+ esm.eventTarget.addEventListener(dist_esm.Enums.Events.TOOL_ACTIVATED, this._onToolActivated);
7704
+ }
7516
7705
 
7517
7706
  /**
7518
7707
  * Retrieves a tool group from the ToolGroupManager by tool group ID.
@@ -7559,6 +7748,7 @@ class ToolGroupService {
7559
7748
  destroy() {
7560
7749
  dist_esm.ToolGroupManager.destroy();
7561
7750
  this.toolGroupIds = new Set();
7751
+ esm.eventTarget.removeEventListener(dist_esm.Enums.Events.TOOL_ACTIVATED, this._onToolActivated);
7562
7752
  }
7563
7753
  destroyToolGroup(toolGroupId) {
7564
7754
  dist_esm.ToolGroupManager.destroyToolGroup(toolGroupId);
@@ -7648,6 +7838,9 @@ class ToolGroupService {
7648
7838
  const toolInstance = toolGroup.getToolInstance(toolName);
7649
7839
  toolInstance.configuration = config;
7650
7840
  }
7841
+ getActivePrimaryMouseButtonTool(toolGroupId) {
7842
+ return this.getToolGroup(toolGroupId)?.getActivePrimaryMouseButtonTool();
7843
+ }
7651
7844
  _setToolsMode(toolGroup, tools) {
7652
7845
  const {
7653
7846
  active,
@@ -7719,21 +7912,21 @@ class ToolGroupService {
7719
7912
  }
7720
7913
  }
7721
7914
  }
7722
- _class = ToolGroupService;
7915
+ _ToolGroupService = ToolGroupService;
7723
7916
  ToolGroupService.REGISTRATION = {
7724
7917
  name: 'toolGroupService',
7725
7918
  altName: 'ToolGroupService',
7726
7919
  create: ({
7727
7920
  servicesManager
7728
7921
  }) => {
7729
- return new _class(servicesManager);
7922
+ return new _ToolGroupService(servicesManager);
7730
7923
  }
7731
7924
  };
7732
7925
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/services/ToolGroupService/index.js
7733
7926
 
7734
7927
  /* harmony default export */ const services_ToolGroupService = (ToolGroupService);
7735
7928
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/services/SyncGroupService/SyncGroupService.ts
7736
- var SyncGroupService_class;
7929
+ var _SyncGroupService;
7737
7930
 
7738
7931
 
7739
7932
 
@@ -7881,14 +8074,14 @@ class SyncGroupService {
7881
8074
  });
7882
8075
  }
7883
8076
  }
7884
- SyncGroupService_class = SyncGroupService;
8077
+ _SyncGroupService = SyncGroupService;
7885
8078
  SyncGroupService.REGISTRATION = {
7886
8079
  name: 'syncGroupService',
7887
8080
  altName: 'SyncGroupService',
7888
8081
  create: ({
7889
8082
  servicesManager
7890
8083
  }) => {
7891
- return new SyncGroupService_class(servicesManager);
8084
+ return new _SyncGroupService(servicesManager);
7892
8085
  }
7893
8086
  };
7894
8087
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/services/SyncGroupService/index.js
@@ -7978,7 +8171,7 @@ function mapROIContoursToRTStructData(structureSet, rtDisplaySetUID) {
7978
8171
  });
7979
8172
  }
7980
8173
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/services/SegmentationService/SegmentationService.ts
7981
- var SegmentationService_class;
8174
+ var _SegmentationService;
7982
8175
 
7983
8176
 
7984
8177
 
@@ -9195,7 +9388,9 @@ class SegmentationService extends src/* PubSubService */.Rc {
9195
9388
  const {
9196
9389
  colorLUTIndex
9197
9390
  } = segmentation;
9198
- this._removeSegmentationFromCornerstone(segmentationId);
9391
+ const {
9392
+ updatedToolGroupIds
9393
+ } = this._removeSegmentationFromCornerstone(segmentationId);
9199
9394
 
9200
9395
  // Delete associated colormap
9201
9396
  // Todo: bring this back
@@ -9211,7 +9406,9 @@ class SegmentationService extends src/* PubSubService */.Rc {
9211
9406
  const {
9212
9407
  id
9213
9408
  } = remainingHydratedSegmentations[0];
9214
- this._setActiveSegmentationForToolGroup(id, this._getApplicableToolGroupId(), false);
9409
+ updatedToolGroupIds.forEach(toolGroupId => {
9410
+ this._setActiveSegmentationForToolGroup(id, toolGroupId, false);
9411
+ });
9215
9412
  }
9216
9413
  }
9217
9414
  this._setDisplaySetIsHydrated(segmentationId, false);
@@ -9438,6 +9635,7 @@ class SegmentationService extends src/* PubSubService */.Rc {
9438
9635
  const removeFromCache = true;
9439
9636
  const segmentationState = dist_esm.segmentation.state;
9440
9637
  const sourceSegState = segmentationState.getSegmentation(segmentationId);
9638
+ const updatedToolGroupIds = new Set();
9441
9639
  if (!sourceSegState) {
9442
9640
  return;
9443
9641
  }
@@ -9448,6 +9646,7 @@ class SegmentationService extends src/* PubSubService */.Rc {
9448
9646
  segmentationRepresentations.forEach(representation => {
9449
9647
  if (representation.segmentationId === segmentationId) {
9450
9648
  UIDsToRemove.push(representation.segmentationRepresentationUID);
9649
+ updatedToolGroupIds.add(toolGroupId);
9451
9650
  }
9452
9651
  });
9453
9652
 
@@ -9461,6 +9660,9 @@ class SegmentationService extends src/* PubSubService */.Rc {
9461
9660
  if (removeFromCache && esm.cache.getVolumeLoadObject(segmentationId)) {
9462
9661
  esm.cache.removeVolumeLoadObject(segmentationId);
9463
9662
  }
9663
+ return {
9664
+ updatedToolGroupIds: Array.from(updatedToolGroupIds)
9665
+ };
9464
9666
  }
9465
9667
  _updateCornerstoneSegmentations({
9466
9668
  segmentationId,
@@ -9503,14 +9705,14 @@ class SegmentationService extends src/* PubSubService */.Rc {
9503
9705
  }
9504
9706
  }
9505
9707
  }
9506
- SegmentationService_class = SegmentationService;
9708
+ _SegmentationService = SegmentationService;
9507
9709
  SegmentationService.REGISTRATION = {
9508
9710
  name: 'segmentationService',
9509
9711
  altName: 'SegmentationService',
9510
9712
  create: ({
9511
9713
  servicesManager
9512
9714
  }) => {
9513
- return new SegmentationService_class({
9715
+ return new _SegmentationService({
9514
9716
  servicesManager
9515
9717
  });
9516
9718
  }
@@ -9540,7 +9742,7 @@ function getCornerstoneViewportType(viewportType) {
9540
9742
  throw new Error(`Invalid viewport type: ${viewportType}. Valid types are: stack, volume`);
9541
9743
  }
9542
9744
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/services/CornerstoneCacheService/CornerstoneCacheService.ts
9543
- var CornerstoneCacheService_class;
9745
+ var _CornerstoneCacheService;
9544
9746
 
9545
9747
 
9546
9748
  const CornerstoneCacheService_VOLUME_LOADER_SCHEME = 'cornerstoneStreamingImageVolume';
@@ -9670,7 +9872,8 @@ class CornerstoneCacheService {
9670
9872
  displaySetInstanceUID: displaySet.displaySetInstanceUID,
9671
9873
  volume,
9672
9874
  volumeId,
9673
- imageIds: volumeImageIds
9875
+ imageIds: volumeImageIds,
9876
+ isDynamicVolume: displaySet.isDynamicVolume
9674
9877
  });
9675
9878
  }
9676
9879
  return {
@@ -9694,7 +9897,7 @@ class CornerstoneCacheService {
9694
9897
  const segDisplaySetInstanceUID = segmentation.displaySetInstanceUID;
9695
9898
  const segDisplaySet = displaySetService.getDisplaySetByUID(segDisplaySetInstanceUID);
9696
9899
  const instance = segDisplaySet.instances?.[0] || segDisplaySet.instance;
9697
- const shouldDisplaySeg = segmentationService.shouldRenderSegmentation(viewportDisplaySetInstanceUIDs, instance.FrameOfReferenceUID);
9900
+ const shouldDisplaySeg = segmentationService.shouldRenderSegmentation(viewportDisplaySetInstanceUIDs, instance?.FrameOfReferenceUID || segDisplaySet.FrameOfReferenceUID);
9698
9901
  if (shouldDisplaySeg) {
9699
9902
  return true;
9700
9903
  }
@@ -9708,14 +9911,14 @@ class CornerstoneCacheService {
9708
9911
  return stackImageIds;
9709
9912
  }
9710
9913
  }
9711
- CornerstoneCacheService_class = CornerstoneCacheService;
9914
+ _CornerstoneCacheService = CornerstoneCacheService;
9712
9915
  CornerstoneCacheService.REGISTRATION = {
9713
9916
  name: 'cornerstoneCacheService',
9714
9917
  altName: 'CornerstoneCacheService',
9715
9918
  create: ({
9716
9919
  servicesManager
9717
9920
  }) => {
9718
- return new CornerstoneCacheService_class(servicesManager);
9921
+ return new _CornerstoneCacheService(servicesManager);
9719
9922
  }
9720
9923
  };
9721
9924
  /* harmony default export */ const CornerstoneCacheService_CornerstoneCacheService = (CornerstoneCacheService);
@@ -9965,7 +10168,7 @@ var JumpPresets = /*#__PURE__*/function (JumpPresets) {
9965
10168
  }(JumpPresets || {});
9966
10169
  /* harmony default export */ const utils_JumpPresets = (JumpPresets);
9967
10170
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/services/ViewportService/CornerstoneViewportService.ts
9968
- var CornerstoneViewportService_class;
10171
+ var _CornerstoneViewportService;
9969
10172
 
9970
10173
 
9971
10174
 
@@ -9973,7 +10176,8 @@ var CornerstoneViewportService_class;
9973
10176
 
9974
10177
 
9975
10178
  const CornerstoneViewportService_EVENTS = {
9976
- VIEWPORT_DATA_CHANGED: 'event::cornerstoneViewportService:viewportDataChanged'
10179
+ VIEWPORT_DATA_CHANGED: 'event::cornerstoneViewportService:viewportDataChanged',
10180
+ VIEWPORT_VOLUMES_CHANGED: 'event::cornerstoneViewportService:viewportVolumesChanged'
9977
10181
  };
9978
10182
 
9979
10183
  /**
@@ -10672,6 +10876,9 @@ class CornerstoneViewportService extends src/* PubSubService */.Rc {
10672
10876
  });
10673
10877
  }
10674
10878
  viewport.render();
10879
+ this._broadcastEvent(this.EVENTS.VIEWPORT_VOLUMES_CHANGED, {
10880
+ viewportInfo
10881
+ });
10675
10882
  }
10676
10883
  _addSegmentationRepresentationToToolGroupIfNecessary(displaySetInstanceUIDs, viewport) {
10677
10884
  const {
@@ -10889,14 +11096,14 @@ class CornerstoneViewportService extends src/* PubSubService */.Rc {
10889
11096
  }, this.gridResizeDelay);
10890
11097
  }
10891
11098
  }
10892
- CornerstoneViewportService_class = CornerstoneViewportService;
11099
+ _CornerstoneViewportService = CornerstoneViewportService;
10893
11100
  CornerstoneViewportService.REGISTRATION = {
10894
11101
  name: 'cornerstoneViewportService',
10895
11102
  altName: 'CornerstoneViewportService',
10896
11103
  create: ({
10897
11104
  servicesManager
10898
11105
  }) => {
10899
- return new CornerstoneViewportService_class(servicesManager);
11106
+ return new _CornerstoneViewportService(servicesManager);
10900
11107
  }
10901
11108
  };
10902
11109
  /* harmony default export */ const ViewportService_CornerstoneViewportService = (CornerstoneViewportService);
@@ -10908,7 +11115,7 @@ let ChangeTypes = /*#__PURE__*/function (ChangeTypes) {
10908
11115
  return ChangeTypes;
10909
11116
  }({});
10910
11117
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/services/ColorbarService/ColorbarService.ts
10911
- var ColorbarService_class;
11118
+ var _ColorbarService;
10912
11119
 
10913
11120
 
10914
11121
 
@@ -11137,7 +11344,7 @@ class ColorbarService extends src/* PubSubService */.Rc {
11137
11344
  return containers;
11138
11345
  }
11139
11346
  }
11140
- ColorbarService_class = ColorbarService;
11347
+ _ColorbarService = ColorbarService;
11141
11348
  ColorbarService.EVENTS = {
11142
11349
  STATE_CHANGED: 'event::ColorbarService:stateChanged'
11143
11350
  };
@@ -11175,7 +11382,7 @@ ColorbarService.defaultTickStyles = {
11175
11382
  ColorbarService.REGISTRATION = {
11176
11383
  name: 'colorbarService',
11177
11384
  create: () => {
11178
- return new ColorbarService_class();
11385
+ return new _ColorbarService();
11179
11386
  }
11180
11387
  };
11181
11388
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/services/ColorbarService/index.ts
@@ -11368,6 +11575,403 @@ const id = package_namespaceObject.UU;
11368
11575
  var ViewportActionCornersService = __webpack_require__(77954);
11369
11576
  // EXTERNAL MODULE: ../../../extensions/cornerstone/src/contextProviders/ViewportActionCornersProvider.tsx
11370
11577
  var ViewportActionCornersProvider = __webpack_require__(76255);
11578
+ // EXTERNAL MODULE: ../../../node_modules/lodash.debounce/index.js
11579
+ var lodash_debounce = __webpack_require__(14771);
11580
+ var lodash_debounce_default = /*#__PURE__*/__webpack_require__.n(lodash_debounce);
11581
+ // EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/Rendering/Core/ColorTransferFunction/ColorMaps.js + 1 modules
11582
+ var ColorMaps = __webpack_require__(12882);
11583
+ ;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/ViewportWindowLevel/getViewportVolumeHistogram.ts
11584
+
11585
+ const workerManager = (0,esm.getWebWorkerManager)();
11586
+ const options = {
11587
+ // maxWorkerInstances: 1,
11588
+ // overwrite: false
11589
+ autoTerminationOnIdle: 1000
11590
+ };
11591
+
11592
+ // Register the task
11593
+ const workerFn = () => {
11594
+ return new Worker(new URL(/* worker import */ __webpack_require__.p + __webpack_require__.u(54), __webpack_require__.b), {
11595
+ name: 'histogram-worker' // name used by the browser to name the worker
11596
+ });
11597
+ };
11598
+ workerManager.registerWorker('histogram-worker', workerFn, options);
11599
+ const getViewportVolumeHistogram = async (viewport, volume, options) => {
11600
+ if (!volume?.loadStatus.loaded) {
11601
+ return undefined;
11602
+ }
11603
+ const volumeImageData = viewport.getImageData(volume.volumeId);
11604
+ if (!volumeImageData) {
11605
+ return undefined;
11606
+ }
11607
+ let scalarData = volume.scalarData;
11608
+ let prevTimePoint;
11609
+ if (volume.numTimePoints > 1) {
11610
+ prevTimePoint = volume.timePointIndex;
11611
+ const middleTimePoint = Math.round(volume.numTimePoints / 2);
11612
+ volume.timePointIndex = middleTimePoint;
11613
+ scalarData = volume.getScalarData(middleTimePoint);
11614
+ }
11615
+ const {
11616
+ dimensions,
11617
+ origin,
11618
+ direction,
11619
+ spacing
11620
+ } = volume;
11621
+ const range = await workerManager.executeTask('histogram-worker', 'getRange', {
11622
+ dimensions,
11623
+ origin,
11624
+ direction,
11625
+ spacing,
11626
+ scalarData
11627
+ });
11628
+
11629
+ // after we calculate the range let's reset the timePointIndex
11630
+ if (volume.numTimePoints > 1) {
11631
+ volume.timePointIndex = prevTimePoint;
11632
+ }
11633
+ const {
11634
+ minimum: min,
11635
+ maximum: max
11636
+ } = range;
11637
+ const calcHistOptions = {
11638
+ numBins: 256,
11639
+ min: Math.max(min, options?.min ?? min),
11640
+ max: Math.min(max, options?.max ?? max)
11641
+ };
11642
+ const histogram = await workerManager.executeTask('histogram-worker', 'calcHistogram', {
11643
+ data: scalarData,
11644
+ options: calcHistOptions
11645
+ });
11646
+ return histogram;
11647
+ };
11648
+
11649
+ ;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/ViewportWindowLevel/ViewportWindowLevel.tsx
11650
+
11651
+
11652
+
11653
+
11654
+
11655
+
11656
+
11657
+
11658
+ const {
11659
+ Events
11660
+ } = esm.Enums;
11661
+ const ViewportWindowLevel = ({
11662
+ servicesManager,
11663
+ viewportId
11664
+ }) => {
11665
+ const {
11666
+ cornerstoneViewportService
11667
+ } = servicesManager.services;
11668
+ const [windowLevels, setWindowLevels] = (0,react.useState)([]);
11669
+ const [cachedHistograms, setCachedHistograms] = (0,react.useState)({});
11670
+
11671
+ /**
11672
+ * Looks for all viewports that has exactly all volumeIds passed as parameter.
11673
+ */
11674
+ const getViewportsWithVolumeIds = (0,react.useCallback)(volumeIds => {
11675
+ const renderingEngine = cornerstoneViewportService.getRenderingEngine();
11676
+ const viewports = renderingEngine.getVolumeViewports();
11677
+ return viewports.filter(vp => {
11678
+ const viewportVolumeIds = vp.getActors().map(actor => actor.uid);
11679
+ return volumeIds.length === viewportVolumeIds.length && volumeIds.every(volumeId => viewportVolumeIds.includes(volumeId));
11680
+ });
11681
+ }, [cornerstoneViewportService]);
11682
+ const getNodeOpacity = (volumeActor, nodeIndex) => {
11683
+ const volumeOpacity = volumeActor.getProperty().getScalarOpacity(0);
11684
+ const nodeValue = [];
11685
+ volumeOpacity.getNodeValue(nodeIndex, nodeValue);
11686
+ return nodeValue[1];
11687
+ };
11688
+
11689
+ /**
11690
+ * Checks if the opacity applied to the PET volume is something like
11691
+ * [{x: 0, y: 0}, {x: 0.1, y: [C]}, {x: [ANY], y: [C]}] where C is a
11692
+ * constant opacity value for all x's greater than 0.1
11693
+ */
11694
+ const isPetVolumeWithDefaultOpacity = (volumeId, volumeActor) => {
11695
+ const volume = esm.cache.getVolume(volumeId);
11696
+ if (!volume) {
11697
+ return false;
11698
+ }
11699
+ const modality = volume.metadata.Modality;
11700
+ if (modality !== 'PT') {
11701
+ return false;
11702
+ }
11703
+ const volumeOpacity = volumeActor.getProperty().getScalarOpacity(0);
11704
+
11705
+ // It must have at least two points (0 and 0.1)
11706
+ if (volumeOpacity.getSize() < 2) {
11707
+ return false;
11708
+ }
11709
+ const node1Value = [];
11710
+ const node2Value = [];
11711
+ volumeOpacity.getNodeValue(0, node1Value);
11712
+ volumeOpacity.getNodeValue(1, node2Value);
11713
+
11714
+ // First node must be (x:0, y:0} and the second one {x:0.1, y:any}
11715
+ if (node1Value[0] !== 0 || node1Value[1] !== 0 || node2Value[0] !== 0.1) {
11716
+ return false;
11717
+ }
11718
+ const expectedOpacity = node2Value[1];
11719
+ const opacitySize = volumeOpacity.getSize();
11720
+ const currentNodeValue = [];
11721
+
11722
+ // Any point after 0.1 must have the same opacity
11723
+ for (let i = 2; i < opacitySize; i++) {
11724
+ volumeOpacity.getNodeValue(i, currentNodeValue);
11725
+ if (currentNodeValue[1] !== expectedOpacity) {
11726
+ return false;
11727
+ }
11728
+ }
11729
+ return true;
11730
+ };
11731
+
11732
+ /**
11733
+ * Checks if the opacity function has a constance opacity value for all x's
11734
+ */
11735
+ const isVolumeWithConstantOpacity = volumeActor => {
11736
+ const volumeOpacity = volumeActor.getProperty().getScalarOpacity(0);
11737
+ const opacitySize = volumeOpacity.getSize();
11738
+ const firstNodeValue = [];
11739
+ volumeOpacity.getNodeValue(0, firstNodeValue);
11740
+ const firstNodeOpacity = firstNodeValue[1];
11741
+ for (let i = 0; i < opacitySize; i++) {
11742
+ const currentNodeValue = [];
11743
+ volumeOpacity.getNodeValue(0, currentNodeValue);
11744
+ if (currentNodeValue[1] !== firstNodeOpacity) {
11745
+ return false;
11746
+ }
11747
+ }
11748
+ return true;
11749
+ };
11750
+ const getVolumeOpacity = (0,react.useCallback)((viewport, volumeId) => {
11751
+ const volumeActor = viewport.getActor(volumeId).actor;
11752
+ if (isPetVolumeWithDefaultOpacity(volumeId, volumeActor)) {
11753
+ // Get the opacity from the second node at 0.1
11754
+ return getNodeOpacity(volumeActor, 1);
11755
+ } else if (isVolumeWithConstantOpacity(volumeActor)) {
11756
+ return getNodeOpacity(volumeActor, 0);
11757
+ }
11758
+ return undefined;
11759
+ }, []);
11760
+ const getWindowLevelsData = (0,react.useCallback)(async viewportId => {
11761
+ const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
11762
+ if (!viewport) {
11763
+ return [];
11764
+ }
11765
+ const viewportInfo = cornerstoneViewportService.getViewportInfo(viewportId);
11766
+ const volumeIds = viewport.getActors().map(actor => actor.uid);
11767
+ const viewportProperties = viewport.getProperties();
11768
+ const {
11769
+ voiRange
11770
+ } = viewportProperties;
11771
+ const viewportVoi = voiRange ? {
11772
+ windowWidth: voiRange.upper - voiRange.lower,
11773
+ windowCenter: voiRange.lower + (voiRange.upper - voiRange.lower) / 2
11774
+ } : undefined;
11775
+ const windowLevels = await Promise.all(volumeIds.map(async (volumeId, volumeIndex) => {
11776
+ const volume = esm.cache.getVolume(volumeId);
11777
+ if (!volume) {
11778
+ return null;
11779
+ }
11780
+ const opacity = getVolumeOpacity(viewport, volumeId);
11781
+ const {
11782
+ metadata,
11783
+ scaling
11784
+ } = volume;
11785
+ const modality = metadata.Modality;
11786
+
11787
+ // TODO: find a proper way to fix the histogram
11788
+ const options = {
11789
+ min: modality === 'PT' ? 0.1 : -999,
11790
+ max: modality === 'PT' ? 5 : 10000
11791
+ };
11792
+ const histogram = cachedHistograms[volumeId] ?? (await getViewportVolumeHistogram(viewport, volume, options));
11793
+ const {
11794
+ voi: displaySetVOI,
11795
+ colormap: displaySetColormap
11796
+ } = viewportInfo.displaySetOptions[volumeIndex];
11797
+ let colormap;
11798
+ if (displaySetColormap) {
11799
+ colormap = esm.utilities.colormap.getColormap(displaySetColormap.name) ?? ColorMaps/* default */.A.getPresetByName(displaySetColormap.name);
11800
+ }
11801
+ const voi = !volumeIndex ? viewportVoi ?? displaySetVOI : displaySetVOI;
11802
+ return {
11803
+ viewportId,
11804
+ modality,
11805
+ volumeId,
11806
+ volumeIndex,
11807
+ voi,
11808
+ histogram,
11809
+ colormap,
11810
+ step: scaling?.PT ? 0.05 : 1,
11811
+ opacity,
11812
+ showOpacitySlider: volumeIndex === 1 && opacity !== undefined
11813
+ };
11814
+ }));
11815
+ const data = windowLevels.filter(Boolean);
11816
+ return data;
11817
+ }, [cachedHistograms, cornerstoneViewportService, getVolumeOpacity]);
11818
+ const updateViewportHistograms = (0,react.useCallback)(() => {
11819
+ getWindowLevelsData(viewportId).then(windowLevels => {
11820
+ setWindowLevels(windowLevels);
11821
+ });
11822
+ }, [viewportId, getWindowLevelsData]);
11823
+ const handleCornerstoneVOIModified = (0,react.useCallback)(e => {
11824
+ const {
11825
+ detail
11826
+ } = e;
11827
+ const {
11828
+ volumeId,
11829
+ range
11830
+ } = detail;
11831
+ const oldWindowLevel = windowLevels.find(wl => wl.volumeId === volumeId);
11832
+ if (!oldWindowLevel) {
11833
+ return;
11834
+ }
11835
+ const oldVOI = oldWindowLevel.voi;
11836
+ const windowWidth = range.upper - range.lower;
11837
+ const windowCenter = range.lower + windowWidth / 2;
11838
+ if (windowWidth === oldVOI.windowWidth && windowCenter === oldVOI.windowCenter) {
11839
+ return;
11840
+ }
11841
+ const newWindowLevel = {
11842
+ ...oldWindowLevel,
11843
+ voi: {
11844
+ windowWidth,
11845
+ windowCenter
11846
+ }
11847
+ };
11848
+ setWindowLevels(windowLevels.map(windowLevel => windowLevel === oldWindowLevel ? newWindowLevel : windowLevel));
11849
+ }, [windowLevels]);
11850
+ const debouncedHandleCornerstoneVOIModified = (0,react.useCallback)(lodash_debounce_default()(handleCornerstoneVOIModified, 100), [handleCornerstoneVOIModified]);
11851
+ const handleVOIChange = (0,react.useCallback)((volumeId, voi) => {
11852
+ const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
11853
+ const newRange = {
11854
+ lower: voi.windowCenter - voi.windowWidth / 2,
11855
+ upper: voi.windowCenter + voi.windowWidth / 2
11856
+ };
11857
+ viewport.setProperties({
11858
+ voiRange: newRange
11859
+ }, volumeId);
11860
+ viewport.render();
11861
+ }, [cornerstoneViewportService, viewportId]);
11862
+ const handleOpacityChange = (0,react.useCallback)((viewportId, _volumeIndex, volumeId, opacity) => {
11863
+ const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
11864
+ if (!viewport) {
11865
+ return;
11866
+ }
11867
+ const viewportVolumeIds = viewport.getActors().map(actor => actor.uid);
11868
+ const viewports = getViewportsWithVolumeIds(viewportVolumeIds);
11869
+ viewports.forEach(vp => {
11870
+ vp.setProperties({
11871
+ colormap: {
11872
+ opacity
11873
+ }
11874
+ }, volumeId);
11875
+ vp.render();
11876
+ });
11877
+ }, [getViewportsWithVolumeIds, cornerstoneViewportService]);
11878
+
11879
+ // Listen to windowLevels changes and caches all the new ones
11880
+ (0,react.useEffect)(() => {
11881
+ const newVolumeHistograms = windowLevels.filter(windowLevel => !cachedHistograms[windowLevel.volumeId] && windowLevel.histogram).reduce((volumeHistograms, windowLevel) => {
11882
+ // If the histogram exists, add it to the volumeHistograms object
11883
+ if (windowLevel?.histogram) {
11884
+ volumeHistograms[windowLevel.volumeId] = windowLevel.histogram;
11885
+ }
11886
+ return volumeHistograms;
11887
+ }, {});
11888
+ if (Object.keys(newVolumeHistograms).length) {
11889
+ setCachedHistograms(prev => ({
11890
+ ...prev,
11891
+ ...newVolumeHistograms
11892
+ }));
11893
+ }
11894
+ }, [windowLevels, cachedHistograms]);
11895
+
11896
+ // Updates the histogram when the viewport index prop has changed
11897
+ (0,react.useEffect)(() => updateViewportHistograms(), [viewportId, updateViewportHistograms]);
11898
+
11899
+ // Listen to cornerstone events on "eventTarget" and at the document level
11900
+ (0,react.useEffect)(() => {
11901
+ esm.eventTarget.addEventListener(Events.IMAGE_VOLUME_LOADING_COMPLETED, updateViewportHistograms);
11902
+ document.addEventListener(Events.VOI_MODIFIED, debouncedHandleCornerstoneVOIModified, true);
11903
+ return () => {
11904
+ esm.eventTarget.removeEventListener(Events.IMAGE_VOLUME_LOADING_COMPLETED, updateViewportHistograms);
11905
+ document.removeEventListener(Events.VOI_MODIFIED, debouncedHandleCornerstoneVOIModified, true);
11906
+ };
11907
+ }, [updateViewportHistograms, debouncedHandleCornerstoneVOIModified]);
11908
+
11909
+ // Updates the viewport when the context of the viewport has changed. This is
11910
+ // necessary when moving across different stages because the viewport index
11911
+ // may not change but the volumes loaded on it may change.
11912
+ (0,react.useEffect)(() => {
11913
+ const {
11914
+ unsubscribe
11915
+ } = cornerstoneViewportService.subscribe(cornerstoneViewportService.EVENTS.VIEWPORT_VOLUMES_CHANGED, ({
11916
+ viewportInfo
11917
+ }) => {
11918
+ if (viewportInfo.viewportId === viewportId) {
11919
+ updateViewportHistograms();
11920
+ }
11921
+ });
11922
+ return () => {
11923
+ unsubscribe();
11924
+ };
11925
+ }, [viewportId, cornerstoneViewportService, updateViewportHistograms]);
11926
+ return /*#__PURE__*/react.createElement(ui_src/* PanelSection */.aU, {
11927
+ title: "Window Level"
11928
+ }, windowLevels.map((windowLevel, i) => {
11929
+ if (!windowLevel.histogram) {
11930
+ return null;
11931
+ }
11932
+ return /*#__PURE__*/react.createElement(ui_src/* WindowLevel */.bL, {
11933
+ key: windowLevel.volumeId,
11934
+ title: `${windowLevel.modality}`,
11935
+ histogram: windowLevel.histogram,
11936
+ voi: windowLevel.voi,
11937
+ step: windowLevel.step,
11938
+ showOpacitySlider: windowLevel.showOpacitySlider,
11939
+ colormap: windowLevel.colormap,
11940
+ onVOIChange: voi => handleVOIChange(windowLevel.volumeId, voi),
11941
+ opacity: windowLevel.opacity,
11942
+ onOpacityChange: opacity => handleOpacityChange(windowLevel.viewportId, i, windowLevel.volumeId, opacity)
11943
+ });
11944
+ }));
11945
+ };
11946
+ ViewportWindowLevel.propTypes = {
11947
+ servicesManager: prop_types_default().instanceOf(src/* ServicesManager */.CS),
11948
+ viewportId: (prop_types_default()).string.isRequired
11949
+ };
11950
+ /* harmony default export */ const ViewportWindowLevel_ViewportWindowLevel = (ViewportWindowLevel);
11951
+ ;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/ActiveViewportWindowLevel/ActiveViewportWindowLevel.tsx
11952
+
11953
+
11954
+
11955
+
11956
+
11957
+ const ActiveViewportWindowLevel = ({
11958
+ servicesManager
11959
+ }) => {
11960
+ const [viewportGrid] = (0,ui_src/* useViewportGrid */.ih)();
11961
+ const {
11962
+ activeViewportId
11963
+ } = viewportGrid;
11964
+ return /*#__PURE__*/react.createElement(react.Fragment, null, activeViewportId && /*#__PURE__*/react.createElement(ViewportWindowLevel_ViewportWindowLevel, {
11965
+ servicesManager: servicesManager,
11966
+ viewportId: activeViewportId
11967
+ }));
11968
+ };
11969
+ ActiveViewportWindowLevel.propTypes = {
11970
+ servicesManager: prop_types_default().instanceOf(src/* ServicesManager */.CS)
11971
+ };
11972
+ /* harmony default export */ const ActiveViewportWindowLevel_ActiveViewportWindowLevel = (ActiveViewportWindowLevel);
11973
+ ;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/components/ActiveViewportWindowLevel/index.js
11974
+
11371
11975
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/index.tsx
11372
11976
  function src_extends() { src_extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return src_extends.apply(this, arguments); }
11373
11977
 
@@ -11397,6 +12001,14 @@ function src_extends() { src_extends = Object.assign ? Object.assign.bind() : fu
11397
12001
 
11398
12002
 
11399
12003
 
12004
+
12005
+
12006
+ const {
12007
+ helpers: volumeLoaderHelpers
12008
+ } = streaming_image_volume_loader_dist_esm;
12009
+ const {
12010
+ getDynamicVolumeInfo
12011
+ } = volumeLoaderHelpers ?? {};
11400
12012
  const Component = /*#__PURE__*/react.lazy(() => {
11401
12013
  return __webpack_require__.e(/* import() */ 574).then(__webpack_require__.bind(__webpack_require__, 71574));
11402
12014
  });
@@ -11444,6 +12056,18 @@ const cornerstoneExtension = {
11444
12056
  return init.call(this, props);
11445
12057
  },
11446
12058
  getToolbarModule: getToolbarModule,
12059
+ getPanelModule({
12060
+ servicesManager
12061
+ }) {
12062
+ return [{
12063
+ name: 'activeViewportWindowLevel',
12064
+ component: () => {
12065
+ return /*#__PURE__*/react.createElement(ActiveViewportWindowLevel_ActiveViewportWindowLevel, {
12066
+ servicesManager: servicesManager
12067
+ });
12068
+ }
12069
+ }];
12070
+ },
11447
12071
  getHangingProtocolModule: src_getHangingProtocolModule,
11448
12072
  getViewportModule({
11449
12073
  servicesManager,
@@ -11496,6 +12120,11 @@ const cornerstoneExtension = {
11496
12120
  toolNames: toolNames,
11497
12121
  Enums: dist_esm.Enums
11498
12122
  }
12123
+ }, {
12124
+ name: 'volumeLoader',
12125
+ exports: {
12126
+ getDynamicVolumeInfo
12127
+ }
11499
12128
  }];
11500
12129
  }
11501
12130
  };
@@ -11510,9 +12139,9 @@ const cornerstoneExtension = {
11510
12139
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
11511
12140
  /* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)
11512
12141
  /* harmony export */ });
11513
- /* harmony import */ var _ohif_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(85073);
11514
- /* harmony import */ var _ohif_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(48804);
11515
- var _class;
12142
+ /* harmony import */ var _ohif_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(55411);
12143
+ /* harmony import */ var _ohif_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5085);
12144
+ var _ViewportActionCornersService;
11516
12145
 
11517
12146
 
11518
12147
  class ViewportActionCornersService extends _ohif_core__WEBPACK_IMPORTED_MODULE_0__/* .PubSubService */ .Rc {
@@ -11554,7 +12183,7 @@ class ViewportActionCornersService extends _ohif_core__WEBPACK_IMPORTED_MODULE_0
11554
12183
  this.serviceImplementation._clear(viewportId);
11555
12184
  }
11556
12185
  }
11557
- _class = ViewportActionCornersService;
12186
+ _ViewportActionCornersService = ViewportActionCornersService;
11558
12187
  ViewportActionCornersService.EVENTS = {};
11559
12188
  ViewportActionCornersService.LOCATIONS = _ohif_ui__WEBPACK_IMPORTED_MODULE_1__/* .ViewportActionCornersLocations */ .ld;
11560
12189
  ViewportActionCornersService.REGISTRATION = {
@@ -11563,7 +12192,7 @@ ViewportActionCornersService.REGISTRATION = {
11563
12192
  create: ({
11564
12193
  configuration = {}
11565
12194
  }) => {
11566
- return new _class();
12195
+ return new _ViewportActionCornersService();
11567
12196
  }
11568
12197
  };
11569
12198
  /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ViewportActionCornersService);
@@ -11618,7 +12247,7 @@ const reset = () => {
11618
12247
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
11619
12248
  /* harmony export */ A: () => (/* binding */ getSOPInstanceAttributes)
11620
12249
  /* harmony export */ });
11621
- /* harmony import */ var _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(50719);
12250
+ /* harmony import */ var _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(44656);
11622
12251
 
11623
12252
 
11624
12253
  /**