@ohif/app 3.8.0-beta.8 → 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 (99) hide show
  1. package/dist/{220.bundle.f7e1c96c94245e70f2be.js → 109.bundle.b4fee2a22b622839baf5.js} +4466 -3715
  2. package/dist/{471.bundle.49c8d281adbae4a2c4df.js → 121.bundle.47f05840a5b3cdf75543.js} +94 -113
  3. package/dist/141.bundle.556b4c1e4cab770417ac.js +8620 -0
  4. package/dist/{687.bundle.9065db35c01823286f08.js → 164.bundle.fadc7c5d634402c73b5f.js} +22 -38
  5. package/dist/17dd54813d5acc10bf8f.wasm +0 -0
  6. package/dist/183.bundle.a3e238998be71c4b2af8.js +30410 -0
  7. package/dist/{506.bundle.5731bb4349e266491225.js → 188.bundle.51dc4b37920f45594393.js} +23 -28
  8. package/dist/{342.bundle.e7c3d500f86fdfcc62b5.js → 206.bundle.fcaa081a0d1f68095c31.js} +1991 -1145
  9. package/dist/20fc4c659b85ccd2a9c0.wasm +0 -0
  10. package/dist/217.bundle.d44bbaa50b6fa563fe15.js +115126 -0
  11. package/dist/{451.bundle.57c21db5d003c75e9d61.js → 295.bundle.5ace95771ced62bdcab8.js} +111 -128
  12. package/dist/{125.bundle.253395f320b72180da63.js → 297.bundle.194d8985ab974839b5b6.js} +7 -8
  13. package/dist/{19.bundle.f77c5787b6d8ac0b638b.js → 325.bundle.fd8e0c18db4708d03a91.js} +477 -373
  14. package/dist/335.bundle.8400aa5a88697a6b9d53.js +2590 -0
  15. package/dist/{202.bundle.d3490836f71e001dd30f.js → 342.bundle.e6d0bba29351b5650a8c.js} +566 -868
  16. package/dist/{776.bundle.a2dedb405a12ffd7699b.js → 41.bundle.0905b258a90a7c6437bb.js} +7453 -3624
  17. package/dist/422.bundle.c6fd037b075dd54f1ba7.js +865 -0
  18. package/dist/{957.bundle.9ea4506963ef8b2d84ba.js → 433.bundle.e0018820758f5a86fa7f.js} +14797 -27561
  19. package/dist/445.bundle.38c6d2af64e41cd7c614.js +7835 -0
  20. package/dist/{126.bundle.6e7111d58bcc937ffd80.js → 448.bundle.5e6da31477887bf53016.js} +356 -430
  21. package/dist/487.bundle.89d973049defb3ba6cb7.js +1876 -0
  22. package/dist/{886.bundle.c8dd3ecc42a4253de278.js → 530.bundle.207b38c15c4c01e4db0e.js} +104 -121
  23. package/dist/{250.bundle.aea3335667054bdefe36.js → 544.bundle.1c1f57118560046649c1.js} +37 -62
  24. package/dist/574.bundle.d648fea691d6709bf2b4.js +2652 -0
  25. package/dist/{181.css → 574.css} +1 -1
  26. package/dist/{410.bundle.15c855b0ff4a1a674fb8.js → 594.bundle.84076375b127b9c7f673.js} +183 -221
  27. package/dist/{221.bundle.aef554202c58483cb34e.js → 633.bundle.acab89baaa06a299d679.js} +365 -553
  28. package/dist/{774.bundle.4b2dc46a35012b898e1a.js → 644.bundle.1e77691d2eeb96a423b0.js} +1852 -8945
  29. package/dist/{663.bundle.d7be28450db14266cdd0.js → 669.bundle.b17e8a621e38d92c653f.js} +310 -265
  30. package/dist/699.bundle.9367d7ef9f7615b2e733.js +772 -0
  31. package/dist/702.bundle.963481fbf871984b646f.js +8426 -0
  32. package/dist/722.bundle.afab1fe6bfcd569130ac.js +1083 -0
  33. package/dist/{359.bundle.45ecb3d28e8c22142606.js → 724.bundle.55f9f49816de931af91a.js} +165 -260
  34. package/dist/{757.bundle.ec8301d8e70d2b990f65.js → 726.bundle.0b3d9277d22fe7e15b89.js} +512 -879
  35. package/dist/{530.bundle.a03b6f942ace3e1baa1e.js → 835.bundle.15aff0b7433bb0dd6d6d.js} +37 -30
  36. package/dist/{822.bundle.82cdc418f8f56da6060b.js → 862.bundle.d32ab08e64806b2e964d.js} +81 -97
  37. package/dist/{236.bundle.4e9924934a747afac132.js → 889.bundle.8ef8b723d0163d5d135c.js} +207 -199
  38. package/dist/{281.bundle.deb7492d143e7768d8bf.js → 905.bundle.8a96e1a75b7cfe5ec093.js} +157 -124
  39. package/dist/{814.bundle.c8c951d20039b63b865a.js → 907.bundle.5c88ed911bed18582da4.js} +16 -30
  40. package/dist/{417.bundle.af0a207c29b109f84159.js → 931.bundle.d270a1fda9a2836c3cc5.js} +26 -26
  41. package/dist/{686.bundle.dccef1f36e4bc79bcc48.js → 939.bundle.9d93b2e47c52338747a2.js} +7 -8
  42. package/dist/94.bundle.f5f2479c214180d05d42.js +778 -0
  43. package/dist/{12.bundle.b5ca13e5363f170ecb3b.js → 961.bundle.f4e52bc76d3044d05372.js} +20 -33
  44. package/dist/app-config.js +1 -0
  45. package/dist/app.bundle.css +16 -13
  46. package/dist/{app.bundle.a978edc59b9d82f2eb22.js → app.bundle.ed937512f7d19d61c411.js} +183396 -87682
  47. package/dist/assets/images/CT-AAA.png +0 -0
  48. package/dist/assets/images/CT-AAA2.png +0 -0
  49. package/dist/assets/images/CT-Air.png +0 -0
  50. package/dist/assets/images/CT-Bone.png +0 -0
  51. package/dist/assets/images/CT-Bones.png +0 -0
  52. package/dist/assets/images/CT-Cardiac.png +0 -0
  53. package/dist/assets/images/CT-Cardiac2.png +0 -0
  54. package/dist/assets/images/CT-Cardiac3.png +0 -0
  55. package/dist/assets/images/CT-Chest-Contrast-Enhanced.png +0 -0
  56. package/dist/assets/images/CT-Chest-Vessels.png +0 -0
  57. package/dist/assets/images/CT-Coronary-Arteries-2.png +0 -0
  58. package/dist/assets/images/CT-Coronary-Arteries-3.png +0 -0
  59. package/dist/assets/images/CT-Coronary-Arteries.png +0 -0
  60. package/dist/assets/images/CT-Cropped-Volume-Bone.png +0 -0
  61. package/dist/assets/images/CT-Fat.png +0 -0
  62. package/dist/assets/images/CT-Liver-Vasculature.png +0 -0
  63. package/dist/assets/images/CT-Lung.png +0 -0
  64. package/dist/assets/images/CT-MIP.png +0 -0
  65. package/dist/assets/images/CT-Muscle.png +0 -0
  66. package/dist/assets/images/CT-Pulmonary-Arteries.png +0 -0
  67. package/dist/assets/images/CT-Soft-Tissue.png +0 -0
  68. package/dist/assets/images/DTI-FA-Brain.png +0 -0
  69. package/dist/assets/images/MR-Angio.png +0 -0
  70. package/dist/assets/images/MR-Default.png +0 -0
  71. package/dist/assets/images/MR-MIP.png +0 -0
  72. package/dist/assets/images/MR-T2-Brain.png +0 -0
  73. package/dist/assets/images/VolumeRendering.png +0 -0
  74. package/dist/cornerstoneDICOMImageLoader.min.js +1 -1
  75. package/dist/cornerstoneDICOMImageLoader.min.js.map +1 -1
  76. package/dist/{dicom-microscopy-viewer.bundle.2c146384eb9466d02ff8.js → dicom-microscopy-viewer.bundle.d3a56dc9f62df5e11019.js} +3 -3
  77. package/dist/histogram-worker.bundle.829e14ec12c2b41a4323.js +359 -0
  78. package/dist/index.html +1 -1
  79. package/dist/{index.worker.e62ecca63f1a2e124230.worker.js → index.worker.64c896c4316fcd506666.worker.js} +2 -2
  80. package/dist/index.worker.64c896c4316fcd506666.worker.js.map +1 -0
  81. package/dist/polySeg.bundle.f1a6ece1396dc1385155.js +249 -0
  82. package/dist/serve.json +12 -0
  83. package/dist/sw.js +1 -1
  84. package/package.json +26 -22
  85. package/dist/181.bundle.a62b9f0ec692299acb35.js +0 -1527
  86. package/dist/23.bundle.e008ad788170f2ed5569.js +0 -900
  87. package/dist/604.bundle.a51f83e64004bca5f497.js +0 -1848
  88. package/dist/613.bundle.9e7072e5b575354fe51e.js +0 -532
  89. package/dist/743.bundle.489f7df3a089d4d374e1.js +0 -78007
  90. package/dist/75788f12450d4c5ed494.wasm +0 -0
  91. package/dist/775.bundle.2285e7e0e67878948c0d.js +0 -1009
  92. package/dist/788.bundle.207ac23c0dfa70cbe3fb.js +0 -2682
  93. package/dist/82.bundle.d6fdcca0f67540bb226a.js +0 -1049
  94. package/dist/index.worker.e62ecca63f1a2e124230.worker.js.map +0 -1
  95. /package/dist/{19.css → 325.css} +0 -0
  96. /package/dist/{776.css → 41.css} +0 -0
  97. /package/dist/{579.css → 481.css} +0 -0
  98. /package/dist/{250.css → 544.css} +0 -0
  99. /package/dist/{221.css → 633.css} +0 -0
@@ -1,9 +1,9 @@
1
- (self["webpackChunk"] = self["webpackChunk"] || []).push([[221,579],{
1
+ "use strict";
2
+ (globalThis["webpackChunk"] = globalThis["webpackChunk"] || []).push([[633,481],{
2
3
 
3
- /***/ 9943:
4
+ /***/ 27400:
4
5
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
5
6
 
6
- "use strict";
7
7
  // ESM COMPAT FLAG
8
8
  __webpack_require__.r(__webpack_exports__);
9
9
 
@@ -13,23 +13,25 @@ __webpack_require__.d(__webpack_exports__, {
13
13
  });
14
14
 
15
15
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone-dicom-seg/package.json
16
- const package_namespaceObject = JSON.parse('{"u2":"@ohif/extension-cornerstone-dicom-seg"}');
16
+ const package_namespaceObject = /*#__PURE__*/JSON.parse('{"UU":"@ohif/extension-cornerstone-dicom-seg"}');
17
17
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone-dicom-seg/src/id.js
18
18
 
19
- const id = package_namespaceObject.u2;
19
+ const id = package_namespaceObject.UU;
20
20
  const SOPClassHandlerName = 'dicom-seg';
21
21
  const SOPClassHandlerId = `${id}.sopClassHandlerModule.${SOPClassHandlerName}`;
22
22
 
23
23
  // EXTERNAL MODULE: ../../../node_modules/react/index.js
24
- var react = __webpack_require__(43001);
25
- // EXTERNAL MODULE: ../../core/src/index.ts + 65 modules
26
- var src = __webpack_require__(71771);
27
- // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/core/dist/esm/index.js + 331 modules
28
- var esm = __webpack_require__(3743);
24
+ var react = __webpack_require__(41766);
25
+ // EXTERNAL MODULE: ../../core/src/index.ts + 70 modules
26
+ var src = __webpack_require__(55411);
27
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/core/dist/esm/index.js + 327 modules
28
+ var esm = __webpack_require__(44656);
29
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/index.js + 18 modules
30
+ var dist_esm = __webpack_require__(24542);
29
31
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/adapters/dist/adapters.es.js
30
- var adapters_es = __webpack_require__(91202);
32
+ var adapters_es = __webpack_require__(83342);
31
33
  // EXTERNAL MODULE: ../../../node_modules/dcmjs/build/dcmjs.es.js
32
- var dcmjs_es = __webpack_require__(67540);
34
+ var dcmjs_es = __webpack_require__(31426);
33
35
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone-dicom-seg/src/utils/dicomlabToRGB.ts
34
36
 
35
37
 
@@ -39,7 +41,7 @@ var dcmjs_es = __webpack_require__(67540);
39
41
  * @returns The RGB color as an array of three integers between 0 and 255.
40
42
  */
41
43
  function dicomlabToRGB(cielab) {
42
- const rgb = dcmjs_es["default"].data.Colors.dicomlab2RGB(cielab).map(x => Math.round(x * 255));
44
+ const rgb = dcmjs_es/* default.data */.Ay.data.Colors.dicomlab2RGB(cielab).map(x => Math.round(x * 255));
43
45
  return rgb;
44
46
  }
45
47
 
@@ -49,6 +51,7 @@ function dicomlabToRGB(cielab) {
49
51
 
50
52
 
51
53
 
54
+
52
55
  const sopClassUids = ['1.2.840.10008.5.1.4.1.1.66.4'];
53
56
  let loadPromises = {};
54
57
  function _getDisplaySetsFromSeries(instances, servicesManager, extensionManager) {
@@ -119,12 +122,9 @@ function _getDisplaySetsFromSeries(instances, servicesManager, extensionManager)
119
122
  displaySet.referencedVolumeId = referencedVolumeId;
120
123
  return referencedDisplaySet;
121
124
  };
122
- displaySet.load = async _ref => {
123
- let {
124
- headers
125
- } = _ref;
126
- return await _load(displaySet, servicesManager, extensionManager, headers);
127
- };
125
+ displaySet.load = async ({
126
+ headers
127
+ }) => await _load(displaySet, servicesManager, extensionManager, headers);
128
128
  return [displaySet];
129
129
  }
130
130
  function _load(segDisplaySet, servicesManager, extensionManager, headers) {
@@ -161,16 +161,16 @@ function _load(segDisplaySet, servicesManager, extensionManager, headers) {
161
161
  });
162
162
  return loadPromises[SOPInstanceUID];
163
163
  }
164
- async function _loadSegments(_ref2) {
165
- let {
166
- extensionManager,
167
- servicesManager,
168
- segDisplaySet,
169
- headers
170
- } = _ref2;
164
+ async function _loadSegments({
165
+ extensionManager,
166
+ servicesManager,
167
+ segDisplaySet,
168
+ headers
169
+ }) {
171
170
  const utilityModule = extensionManager.getModuleEntry('@ohif/extension-cornerstone.utilityModule.common');
172
171
  const {
173
- segmentationService
172
+ segmentationService,
173
+ uiNotificationService
174
174
  } = servicesManager.services;
175
175
  const {
176
176
  dicomLoaderService
@@ -187,7 +187,7 @@ async function _loadSegments(_ref2) {
187
187
  // Todo: what should be defaults here
188
188
  const tolerance = 0.001;
189
189
  const skipOverlapping = true;
190
- esm.eventTarget.addEventListener(adapters_es/* Enums */.Y.Events.SEGMENTATION_LOAD_PROGRESS, evt => {
190
+ esm.eventTarget.addEventListener(adapters_es/* Enums */.fX.Events.SEGMENTATION_LOAD_PROGRESS, evt => {
191
191
  const {
192
192
  percentComplete
193
193
  } = evt.detail;
@@ -195,28 +195,50 @@ async function _loadSegments(_ref2) {
195
195
  percentComplete
196
196
  });
197
197
  });
198
- const results = await adapters_es.adaptersSEG.Cornerstone3D.Segmentation.generateToolState(imageIds, arrayBuffer, esm.metaData, {
198
+ const results = await adapters_es/* adaptersSEG */.ql.Cornerstone3D.Segmentation.generateToolState(imageIds, arrayBuffer, esm.metaData, {
199
199
  skipOverlapping,
200
200
  tolerance,
201
201
  eventTarget: esm.eventTarget,
202
202
  triggerEvent: esm.triggerEvent
203
203
  });
204
+ let usedRecommendedDisplayCIELabValue = true;
204
205
  results.segMetadata.data.forEach((data, i) => {
205
206
  if (i > 0) {
206
- data.rgba = dicomlabToRGB(data.RecommendedDisplayCIELabValue);
207
+ data.rgba = data.RecommendedDisplayCIELabValue;
208
+ if (data.rgba) {
209
+ data.rgba = dicomlabToRGB(data.rgba);
210
+ } else {
211
+ usedRecommendedDisplayCIELabValue = false;
212
+ data.rgba = dist_esm.CONSTANTS.COLOR_LUT[i % dist_esm.CONSTANTS.COLOR_LUT.length];
213
+ }
207
214
  }
208
215
  });
216
+ if (results.overlappingSegments) {
217
+ uiNotificationService.show({
218
+ title: 'Overlapping Segments',
219
+ message: 'Unsupported overlapping segments detected, segmentation rendering results may be incorrect.',
220
+ type: 'warning'
221
+ });
222
+ }
223
+ if (!usedRecommendedDisplayCIELabValue) {
224
+ // Display a notification about the non-utilization of RecommendedDisplayCIELabValue
225
+ uiNotificationService.show({
226
+ title: 'DICOM SEG import',
227
+ message: 'RecommendedDisplayCIELabValue not found for one or more segments. The default color was used instead.',
228
+ type: 'warning',
229
+ duration: 5000
230
+ });
231
+ }
209
232
  Object.assign(segDisplaySet, results);
210
233
  }
211
234
  function _segmentationExists(segDisplaySet, segmentationService) {
212
235
  // This should be abstracted with the CornerstoneCacheService
213
236
  return segmentationService.getSegmentation(segDisplaySet.displaySetInstanceUID);
214
237
  }
215
- function getSopClassHandlerModule(_ref3) {
216
- let {
217
- servicesManager,
218
- extensionManager
219
- } = _ref3;
238
+ function getSopClassHandlerModule({
239
+ servicesManager,
240
+ extensionManager
241
+ }) {
220
242
  const getDisplaySetsFromSeries = instances => {
221
243
  return _getDisplaySetsFromSeries(instances, servicesManager, extensionManager);
222
244
  };
@@ -292,24 +314,29 @@ function getHangingProtocolModule() {
292
314
  /* harmony default export */ const src_getHangingProtocolModule = (getHangingProtocolModule);
293
315
 
294
316
  // EXTERNAL MODULE: ./state/index.js + 1 modules
295
- var state = __webpack_require__(62657);
296
- // EXTERNAL MODULE: ../../../extensions/default/src/index.ts + 76 modules
297
- var default_src = __webpack_require__(56342);
317
+ var state = __webpack_require__(15575);
318
+ // EXTERNAL MODULE: ../../ui/src/index.js + 785 modules
319
+ var ui_src = __webpack_require__(5085);
320
+ // EXTERNAL MODULE: ../../../extensions/default/src/index.ts + 85 modules
321
+ var default_src = __webpack_require__(7206);
298
322
  // EXTERNAL MODULE: ../../../node_modules/prop-types/index.js
299
- var prop_types = __webpack_require__(3827);
323
+ var prop_types = __webpack_require__(11374);
300
324
  var prop_types_default = /*#__PURE__*/__webpack_require__.n(prop_types);
301
- // EXTERNAL MODULE: ../../ui/src/index.js + 486 modules
302
- var ui_src = __webpack_require__(22582);
325
+ ;// CONCATENATED MODULE: ../../../extensions/cornerstone-dicom-seg/src/types/segmentation.tsx
326
+ let SegmentationPanelMode = /*#__PURE__*/function (SegmentationPanelMode) {
327
+ SegmentationPanelMode["Expanded"] = "expanded";
328
+ SegmentationPanelMode["Dropdown"] = "dropdown";
329
+ return SegmentationPanelMode;
330
+ }({});
303
331
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone-dicom-seg/src/panels/callInputDialog.tsx
304
332
 
305
333
 
306
334
  function callInputDialog(uiDialogService, label, callback) {
307
335
  const dialogId = 'enter-segment-label';
308
- const onSubmitHandler = _ref => {
309
- let {
310
- action,
311
- value
312
- } = _ref;
336
+ const onSubmitHandler = ({
337
+ action,
338
+ value
339
+ }) => {
313
340
  switch (action.id) {
314
341
  case 'save':
315
342
  callback(value.label, action.id);
@@ -328,7 +355,7 @@ function callInputDialog(uiDialogService, label, callback) {
328
355
  centralize: true,
329
356
  isDraggable: false,
330
357
  showOverlay: true,
331
- content: ui_src/* Dialog */.Vq,
358
+ content: ui_src/* Dialog */.lG,
332
359
  contentProps: {
333
360
  title: 'Segment',
334
361
  value: {
@@ -341,19 +368,18 @@ function callInputDialog(uiDialogService, label, callback) {
341
368
  actions: [{
342
369
  id: 'cancel',
343
370
  text: 'Cancel',
344
- type: ui_src/* ButtonEnums.type */.LZ.dt.secondary
371
+ type: ui_src/* ButtonEnums.type */.Ny.NW.secondary
345
372
  }, {
346
373
  id: 'save',
347
374
  text: 'Confirm',
348
- type: ui_src/* ButtonEnums.type */.LZ.dt.primary
375
+ type: ui_src/* ButtonEnums.type */.Ny.NW.primary
349
376
  }],
350
377
  onSubmit: onSubmitHandler,
351
- body: _ref2 => {
352
- let {
353
- value,
354
- setValue
355
- } = _ref2;
356
- return /*#__PURE__*/react.createElement(ui_src/* Input */.II, {
378
+ body: ({
379
+ value,
380
+ setValue
381
+ }) => {
382
+ return /*#__PURE__*/react.createElement(ui_src/* Input */.pd, {
357
383
  label: "Enter the segment label",
358
384
  labelClassName: "text-white text-[14px] leading-[1.2]",
359
385
  autoFocus: true,
@@ -385,7 +411,7 @@ function callInputDialog(uiDialogService, label, callback) {
385
411
  }
386
412
  /* harmony default export */ const panels_callInputDialog = (callInputDialog);
387
413
  // EXTERNAL MODULE: ../../../node_modules/react-color/es/index.js + 219 modules
388
- var es = __webpack_require__(22831);
414
+ var es = __webpack_require__(13726);
389
415
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone-dicom-seg/src/panels/colorPickerDialog.css
390
416
  // extracted by mini-css-extract-plugin
391
417
 
@@ -396,11 +422,10 @@ var es = __webpack_require__(22831);
396
422
 
397
423
  function callColorPickerDialog(uiDialogService, rgbaColor, callback) {
398
424
  const dialogId = 'pick-color';
399
- const onSubmitHandler = _ref => {
400
- let {
401
- action,
402
- value
403
- } = _ref;
425
+ const onSubmitHandler = ({
426
+ action,
427
+ value
428
+ }) => {
404
429
  switch (action.id) {
405
430
  case 'save':
406
431
  callback(value.rgbaColor, action.id);
@@ -419,7 +444,7 @@ function callColorPickerDialog(uiDialogService, rgbaColor, callback) {
419
444
  centralize: true,
420
445
  isDraggable: false,
421
446
  showOverlay: true,
422
- content: ui_src/* Dialog */.Vq,
447
+ content: ui_src/* Dialog */.lG,
423
448
  contentProps: {
424
449
  title: 'Segment Color',
425
450
  value: {
@@ -439,17 +464,16 @@ function callColorPickerDialog(uiDialogService, rgbaColor, callback) {
439
464
  type: 'secondary'
440
465
  }],
441
466
  onSubmit: onSubmitHandler,
442
- body: _ref2 => {
443
- let {
444
- value,
445
- setValue
446
- } = _ref2;
467
+ body: ({
468
+ value,
469
+ setValue
470
+ }) => {
447
471
  const handleChange = color => {
448
472
  setValue({
449
473
  rgbaColor: color.rgb
450
474
  });
451
475
  };
452
- return /*#__PURE__*/react.createElement(es/* ChromePicker */.AI, {
476
+ return /*#__PURE__*/react.createElement(es/* ChromePicker */.xk, {
453
477
  color: value.rgbaColor,
454
478
  onChange: handleChange,
455
479
  presetColors: [],
@@ -462,7 +486,7 @@ function callColorPickerDialog(uiDialogService, rgbaColor, callback) {
462
486
  }
463
487
  /* harmony default export */ const colorPickerDialog = (callColorPickerDialog);
464
488
  // EXTERNAL MODULE: ../../../node_modules/react-i18next/dist/es/index.js + 15 modules
465
- var dist_es = __webpack_require__(69190);
489
+ var dist_es = __webpack_require__(80619);
466
490
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone-dicom-seg/src/panels/PanelSegmentation.tsx
467
491
 
468
492
 
@@ -471,22 +495,28 @@ var dist_es = __webpack_require__(69190);
471
495
 
472
496
 
473
497
 
474
- function PanelSegmentation(_ref) {
475
- let {
476
- servicesManager,
477
- commandsManager,
478
- extensionManager,
479
- configuration
480
- } = _ref;
498
+
499
+ const components = {
500
+ [SegmentationPanelMode.Expanded]: ui_src/* SegmentationGroupTableExpanded */.fO,
501
+ [SegmentationPanelMode.Dropdown]: ui_src/* SegmentationGroupTable */.QQ
502
+ };
503
+ function PanelSegmentation({
504
+ servicesManager,
505
+ commandsManager,
506
+ extensionManager,
507
+ configuration
508
+ }) {
481
509
  const {
482
510
  segmentationService,
483
511
  viewportGridService,
484
- uiDialogService
512
+ uiDialogService,
513
+ displaySetService
485
514
  } = servicesManager.services;
486
515
  const {
487
516
  t
488
- } = (0,dist_es/* useTranslation */.$G)('PanelSegmentation');
517
+ } = (0,dist_es/* useTranslation */.Bd)('PanelSegmentation');
489
518
  const [selectedSegmentationId, setSelectedSegmentationId] = (0,react.useState)(null);
519
+ const [addSegmentationClassName, setAddSegmentationClassName] = (0,react.useState)('');
490
520
  const [segmentationConfiguration, setSegmentationConfiguration] = (0,react.useState)(segmentationService.getConfiguration());
491
521
  const [segmentations, setSegmentations] = (0,react.useState)(() => segmentationService.getSegmentations());
492
522
  (0,react.useEffect)(() => {
@@ -511,6 +541,47 @@ function PanelSegmentation(_ref) {
511
541
  });
512
542
  };
513
543
  }, []);
544
+
545
+ // temporary measure to not allow add segmentation when the selected viewport
546
+ // is stack viewport
547
+ (0,react.useEffect)(() => {
548
+ const handleActiveViewportChange = viewportId => {
549
+ const displaySetUIDs = viewportGridService.getDisplaySetsUIDsForViewport(viewportId || viewportGridService.getActiveViewportId());
550
+ if (!displaySetUIDs) {
551
+ return;
552
+ }
553
+ const isReconstructable = displaySetUIDs?.some(displaySetUID => {
554
+ const displaySet = displaySetService.getDisplaySetByUID(displaySetUID);
555
+ return displaySet?.isReconstructable;
556
+ }) || false;
557
+ if (isReconstructable) {
558
+ setAddSegmentationClassName('');
559
+ } else {
560
+ setAddSegmentationClassName('ohif-disabled');
561
+ }
562
+ };
563
+
564
+ // Handle initial state
565
+ handleActiveViewportChange();
566
+ const changed = viewportGridService.EVENTS.ACTIVE_VIEWPORT_ID_CHANGED;
567
+ const ready = viewportGridService.EVENTS.VIEWPORTS_READY;
568
+ const subs = [];
569
+ [ready, changed].forEach(evt => {
570
+ const {
571
+ unsubscribe
572
+ } = viewportGridService.subscribe(evt, ({
573
+ viewportId
574
+ }) => {
575
+ handleActiveViewportChange(viewportId);
576
+ });
577
+ subs.push(unsubscribe);
578
+ });
579
+
580
+ // Clean up
581
+ return () => {
582
+ subs.forEach(unsub => unsub());
583
+ };
584
+ }, []);
514
585
  const getToolGroupIds = segmentationId => {
515
586
  const toolGroupIds = segmentationService.getToolGroupIdsWithSegmentation(segmentationId);
516
587
  return toolGroupIds;
@@ -567,7 +638,6 @@ function PanelSegmentation(_ref) {
567
638
  );
568
639
  });
569
640
  };
570
-
571
641
  const onSegmentColorClick = (segmentationId, segmentIndex) => {
572
642
  const segmentation = segmentationService.getSegmentation(segmentationId);
573
643
  const segment = segmentation.segments[segmentIndex];
@@ -591,6 +661,8 @@ function PanelSegmentation(_ref) {
591
661
  const onSegmentDelete = (segmentationId, segmentIndex) => {
592
662
  segmentationService.removeSegment(segmentationId, segmentIndex);
593
663
  };
664
+
665
+ // segment hide
594
666
  const onToggleSegmentVisibility = (segmentationId, segmentIndex) => {
595
667
  const segmentation = segmentationService.getSegmentation(segmentationId);
596
668
  const segmentInfo = segmentation.segments[segmentIndex];
@@ -607,6 +679,15 @@ function PanelSegmentation(_ref) {
607
679
  };
608
680
  const onToggleSegmentationVisibility = segmentationId => {
609
681
  segmentationService.toggleSegmentationVisibility(segmentationId);
682
+ const segmentation = segmentationService.getSegmentation(segmentationId);
683
+ const isVisible = segmentation.isVisible;
684
+ const segments = segmentation.segments;
685
+ const toolGroupIds = getToolGroupIds(segmentationId);
686
+ toolGroupIds.forEach(toolGroupId => {
687
+ segments.forEach((segment, segmentIndex) => {
688
+ segmentationService.setSegmentVisibility(segmentationId, segmentIndex, isVisible, toolGroupId);
689
+ });
690
+ });
610
691
  };
611
692
  const _setSegmentationConfiguration = (0,react.useCallback)((segmentationId, key, value) => {
612
693
  segmentationService.setConfiguration({
@@ -647,14 +728,17 @@ function PanelSegmentation(_ref) {
647
728
  segmentationId
648
729
  });
649
730
  };
650
- return /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("div", {
651
- className: "ohif-scrollbar flex min-h-0 flex-auto select-none flex-col justify-between overflow-auto"
652
- }, /*#__PURE__*/react.createElement(ui_src/* SegmentationGroupTable */.cX, {
731
+ const SegmentationGroupTableComponent = components[configuration?.segmentationPanelMode] || ui_src/* SegmentationGroupTable */.QQ;
732
+ const allowAddSegment = configuration?.addSegment;
733
+ const onSegmentationAddWrapper = configuration?.onSegmentationAdd && typeof configuration?.onSegmentationAdd === 'function' ? configuration?.onSegmentationAdd : onSegmentationAdd;
734
+ return /*#__PURE__*/react.createElement(SegmentationGroupTableComponent, {
653
735
  title: t('Segmentations'),
654
736
  segmentations: segmentations,
655
737
  disableEditing: configuration.disableEditing,
656
738
  activeSegmentationId: selectedSegmentationId || '',
657
- onSegmentationAdd: onSegmentationAdd,
739
+ onSegmentationAdd: onSegmentationAddWrapper,
740
+ addSegmentationClassName: addSegmentationClassName,
741
+ showAddSegment: allowAddSegment,
658
742
  onSegmentationClick: onSegmentationClick,
659
743
  onSegmentationDelete: onSegmentationDelete,
660
744
  onSegmentationDownload: onSegmentationDownload,
@@ -680,7 +764,7 @@ function PanelSegmentation(_ref) {
680
764
  setOutlineWidthActive: value => _setSegmentationConfiguration(selectedSegmentationId, 'outlineWidthActive', value),
681
765
  setFillAlpha: value => _setSegmentationConfiguration(selectedSegmentationId, 'fillAlpha', value),
682
766
  setFillAlphaInactive: value => _setSegmentationConfiguration(selectedSegmentationId, 'fillAlphaInactive', value)
683
- })));
767
+ });
684
768
  }
685
769
  PanelSegmentation.propTypes = {
686
770
  commandsManager: prop_types_default().shape({
@@ -698,405 +782,42 @@ PanelSegmentation.propTypes = {
698
782
  }).isRequired
699
783
  }).isRequired
700
784
  };
701
- // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/index.js + 348 modules
702
- var dist_esm = __webpack_require__(14957);
703
- ;// CONCATENATED MODULE: ../../../extensions/cornerstone-dicom-seg/src/panels/SegmentationToolbox.tsx
704
-
705
-
706
-
707
- const {
708
- segmentation: segmentationUtils
709
- } = dist_esm.utilities;
710
- const TOOL_TYPES = {
711
- CIRCULAR_BRUSH: 'CircularBrush',
712
- SPHERE_BRUSH: 'SphereBrush',
713
- CIRCULAR_ERASER: 'CircularEraser',
714
- SPHERE_ERASER: 'SphereEraser',
715
- CIRCLE_SHAPE: 'CircleScissor',
716
- RECTANGLE_SHAPE: 'RectangleScissor',
717
- SPHERE_SHAPE: 'SphereScissor',
718
- THRESHOLD_CIRCULAR_BRUSH: 'ThresholdCircularBrush',
719
- THRESHOLD_SPHERE_BRUSH: 'ThresholdSphereBrush'
720
- };
721
- const ACTIONS = {
722
- SET_TOOL_CONFIG: 'SET_TOOL_CONFIG',
723
- SET_ACTIVE_TOOL: 'SET_ACTIVE_TOOL'
724
- };
725
- const initialState = {
726
- Brush: {
727
- brushSize: 15,
728
- mode: 'CircularBrush' // Can be 'CircularBrush' or 'SphereBrush'
729
- },
730
-
731
- Eraser: {
732
- brushSize: 15,
733
- mode: 'CircularEraser' // Can be 'CircularEraser' or 'SphereEraser'
734
- },
735
-
736
- Shapes: {
737
- brushSize: 15,
738
- mode: 'CircleScissor' // E.g., 'CircleScissor', 'RectangleScissor', or 'SphereScissor'
739
- },
740
-
741
- ThresholdBrush: {
742
- brushSize: 15,
743
- thresholdRange: [-500, 500]
744
- },
745
- activeTool: null
746
- };
747
- function toolboxReducer(state, action) {
748
- switch (action.type) {
749
- case ACTIONS.SET_TOOL_CONFIG:
750
- const {
751
- tool,
752
- config
753
- } = action.payload;
754
- return {
755
- ...state,
756
- [tool]: {
757
- ...state[tool],
758
- ...config
759
- }
760
- };
761
- case ACTIONS.SET_ACTIVE_TOOL:
762
- return {
763
- ...state,
764
- activeTool: action.payload
765
- };
766
- default:
767
- return state;
768
- }
769
- }
770
- function SegmentationToolbox(_ref) {
771
- let {
772
- servicesManager,
773
- extensionManager
774
- } = _ref;
775
- const {
776
- toolbarService,
777
- segmentationService,
778
- toolGroupService
779
- } = servicesManager.services;
780
- const [viewportGrid] = (0,ui_src/* useViewportGrid */.O_)();
781
- const {
782
- viewports,
783
- activeViewportId
784
- } = viewportGrid;
785
- const [toolsEnabled, setToolsEnabled] = (0,react.useState)(false);
786
- const [state, dispatch] = (0,react.useReducer)(toolboxReducer, initialState);
787
- const updateActiveTool = (0,react.useCallback)(() => {
788
- if (!viewports?.size || activeViewportId === undefined) {
789
- return;
790
- }
791
- const viewport = viewports.get(activeViewportId);
792
- if (!viewport) {
793
- return;
794
- }
795
- dispatch({
796
- type: ACTIONS.SET_ACTIVE_TOOL,
797
- payload: toolGroupService.getActiveToolForViewport(viewport.viewportId)
798
- });
799
- }, [activeViewportId, viewports, toolGroupService, dispatch]);
800
- const setToolActive = (0,react.useCallback)(toolName => {
801
- toolbarService.recordInteraction({
802
- interactionType: 'tool',
803
- commands: [{
804
- commandName: 'setToolActive',
805
- commandOptions: {
806
- toolName
807
- }
808
- }]
809
- });
810
- dispatch({
811
- type: ACTIONS.SET_ACTIVE_TOOL,
812
- payload: toolName
813
- });
814
- }, [toolbarService, dispatch]);
815
-
816
- /**
817
- * sets the tools enabled IF there are segmentations
818
- */
819
- (0,react.useEffect)(() => {
820
- const events = [segmentationService.EVENTS.SEGMENTATION_ADDED, segmentationService.EVENTS.SEGMENTATION_UPDATED, segmentationService.EVENTS.SEGMENTATION_REMOVED];
821
- const unsubscriptions = [];
822
- events.forEach(event => {
823
- const {
824
- unsubscribe
825
- } = segmentationService.subscribe(event, () => {
826
- const segmentations = segmentationService.getSegmentations();
827
- const activeSegmentation = segmentations?.find(seg => seg.isActive);
828
- setToolsEnabled(activeSegmentation?.segmentCount > 0);
829
- });
830
- unsubscriptions.push(unsubscribe);
831
- });
832
- updateActiveTool();
833
- return () => {
834
- unsubscriptions.forEach(unsubscribe => unsubscribe());
835
- };
836
- }, [activeViewportId, viewports, segmentationService, updateActiveTool]);
837
-
838
- /**
839
- * Update the active tool when the toolbar state changes
840
- */
841
- (0,react.useEffect)(() => {
842
- const {
843
- unsubscribe
844
- } = toolbarService.subscribe(toolbarService.EVENTS.TOOL_BAR_STATE_MODIFIED, () => {
845
- updateActiveTool();
846
- });
847
- return () => {
848
- unsubscribe();
849
- };
850
- }, [toolbarService, updateActiveTool]);
851
- (0,react.useEffect)(() => {
852
- // if the active tool is not a brush tool then do nothing
853
- if (!Object.values(TOOL_TYPES).includes(state.activeTool)) {
854
- return;
855
- }
856
-
857
- // if the tool is Segmentation and it is enabled then do nothing
858
- if (toolsEnabled) {
859
- return;
860
- }
861
-
862
- // if the tool is Segmentation and it is disabled, then switch
863
- // back to the window level tool to not confuse the user when no
864
- // segmentation is active or when there is no segment in the segmentation
865
- setToolActive('WindowLevel');
866
- }, [toolsEnabled, state.activeTool, setToolActive]);
867
- const updateBrushSize = (0,react.useCallback)((toolName, brushSize) => {
868
- toolGroupService.getToolGroupIds()?.forEach(toolGroupId => {
869
- segmentationUtils.setBrushSizeForToolGroup(toolGroupId, brushSize, toolName);
870
- });
871
- }, [toolGroupService]);
872
- const onBrushSizeChange = (0,react.useCallback)((valueAsStringOrNumber, toolCategory) => {
873
- const value = Number(valueAsStringOrNumber);
874
- _getToolNamesFromCategory(toolCategory).forEach(toolName => {
875
- updateBrushSize(toolName, value);
876
- });
877
- dispatch({
878
- type: ACTIONS.SET_TOOL_CONFIG,
879
- payload: {
880
- tool: toolCategory,
881
- config: {
882
- brushSize: value
883
- }
884
- }
885
- });
886
- }, [toolGroupService, dispatch]);
887
- const handleRangeChange = (0,react.useCallback)(newRange => {
888
- if (newRange[0] === state.ThresholdBrush.thresholdRange[0] && newRange[1] === state.ThresholdBrush.thresholdRange[1]) {
889
- return;
890
- }
891
- const toolNames = _getToolNamesFromCategory('ThresholdBrush');
892
- toolNames.forEach(toolName => {
893
- toolGroupService.getToolGroupIds()?.forEach(toolGroupId => {
894
- const toolGroup = toolGroupService.getToolGroup(toolGroupId);
895
- toolGroup.setToolConfiguration(toolName, {
896
- strategySpecificConfiguration: {
897
- THRESHOLD_INSIDE_CIRCLE: {
898
- threshold: newRange
899
- }
900
- }
901
- });
902
- });
903
- });
904
- dispatch({
905
- type: ACTIONS.SET_TOOL_CONFIG,
906
- payload: {
907
- tool: 'ThresholdBrush',
908
- config: {
909
- thresholdRange: newRange
910
- }
911
- }
912
- });
913
- }, [toolGroupService, dispatch, state.ThresholdBrush.thresholdRange]);
914
- return /*#__PURE__*/react.createElement(ui_src/* AdvancedToolbox */.bY, {
915
- title: "Segmentation Tools",
916
- items: [{
917
- name: 'Brush',
918
- icon: 'icon-tool-brush',
919
- disabled: !toolsEnabled,
920
- active: state.activeTool === TOOL_TYPES.CIRCULAR_BRUSH || state.activeTool === TOOL_TYPES.SPHERE_BRUSH,
921
- onClick: () => setToolActive(TOOL_TYPES.CIRCULAR_BRUSH),
922
- options: [{
923
- name: 'Radius (mm)',
924
- id: 'brush-radius',
925
- type: 'range',
926
- min: 0.5,
927
- max: 99.5,
928
- value: state.Brush.brushSize,
929
- step: 0.5,
930
- onChange: value => onBrushSizeChange(value, 'Brush')
931
- }, {
932
- name: 'Mode',
933
- type: 'radio',
934
- id: 'brush-mode',
935
- value: state.Brush.mode,
936
- values: [{
937
- value: TOOL_TYPES.CIRCULAR_BRUSH,
938
- label: 'Circle'
939
- }, {
940
- value: TOOL_TYPES.SPHERE_BRUSH,
941
- label: 'Sphere'
942
- }],
943
- onChange: value => setToolActive(value)
944
- }]
945
- }, {
946
- name: 'Eraser',
947
- icon: 'icon-tool-eraser',
948
- disabled: !toolsEnabled,
949
- active: state.activeTool === TOOL_TYPES.CIRCULAR_ERASER || state.activeTool === TOOL_TYPES.SPHERE_ERASER,
950
- onClick: () => setToolActive(TOOL_TYPES.CIRCULAR_ERASER),
951
- options: [{
952
- name: 'Radius (mm)',
953
- type: 'range',
954
- id: 'eraser-radius',
955
- min: 0.5,
956
- max: 99.5,
957
- value: state.Eraser.brushSize,
958
- step: 0.5,
959
- onChange: value => onBrushSizeChange(value, 'Eraser')
960
- }, {
961
- name: 'Mode',
962
- type: 'radio',
963
- id: 'eraser-mode',
964
- value: state.Eraser.mode,
965
- values: [{
966
- value: TOOL_TYPES.CIRCULAR_ERASER,
967
- label: 'Circle'
968
- }, {
969
- value: TOOL_TYPES.SPHERE_ERASER,
970
- label: 'Sphere'
971
- }],
972
- onChange: value => setToolActive(value)
973
- }]
974
- }, {
975
- name: 'Shapes',
976
- icon: 'icon-tool-shape',
977
- disabled: !toolsEnabled,
978
- active: state.activeTool === TOOL_TYPES.CIRCLE_SHAPE || state.activeTool === TOOL_TYPES.RECTANGLE_SHAPE || state.activeTool === TOOL_TYPES.SPHERE_SHAPE,
979
- onClick: () => setToolActive(TOOL_TYPES.CIRCLE_SHAPE),
980
- options: [{
981
- name: 'Mode',
982
- type: 'radio',
983
- value: state.Shapes.mode,
984
- id: 'shape-mode',
985
- values: [{
986
- value: TOOL_TYPES.CIRCLE_SHAPE,
987
- label: 'Circle'
988
- }, {
989
- value: TOOL_TYPES.RECTANGLE_SHAPE,
990
- label: 'Rectangle'
991
- }, {
992
- value: TOOL_TYPES.SPHERE_SHAPE,
993
- label: 'Sphere'
994
- }],
995
- onChange: value => setToolActive(value)
996
- }]
997
- }, {
998
- name: 'Threshold Tool',
999
- icon: 'icon-tool-threshold',
1000
- disabled: !toolsEnabled,
1001
- active: state.activeTool === TOOL_TYPES.THRESHOLD_CIRCULAR_BRUSH || state.activeTool === TOOL_TYPES.THRESHOLD_SPHERE_BRUSH,
1002
- onClick: () => setToolActive(TOOL_TYPES.THRESHOLD_CIRCULAR_BRUSH),
1003
- options: [{
1004
- name: 'Radius (mm)',
1005
- id: 'threshold-radius',
1006
- type: 'range',
1007
- min: 0.5,
1008
- max: 99.5,
1009
- value: state.ThresholdBrush.brushSize,
1010
- step: 0.5,
1011
- onChange: value => onBrushSizeChange(value, 'ThresholdBrush')
1012
- }, {
1013
- name: 'Mode',
1014
- type: 'radio',
1015
- id: 'threshold-mode',
1016
- value: state.activeTool,
1017
- values: [{
1018
- value: TOOL_TYPES.THRESHOLD_CIRCULAR_BRUSH,
1019
- label: 'Circle'
1020
- }, {
1021
- value: TOOL_TYPES.THRESHOLD_SPHERE_BRUSH,
1022
- label: 'Sphere'
1023
- }],
1024
- onChange: value => setToolActive(value)
1025
- }, {
1026
- type: 'custom',
1027
- id: 'segmentation-threshold-range',
1028
- children: () => {
1029
- return /*#__PURE__*/react.createElement("div", null, /*#__PURE__*/react.createElement("div", {
1030
- className: "bg-secondary-light h-[1px]"
1031
- }), /*#__PURE__*/react.createElement("div", {
1032
- className: "mt-1 text-[13px] text-white"
1033
- }, "Threshold"), /*#__PURE__*/react.createElement(ui_src/* InputDoubleRange */.R0, {
1034
- values: state.ThresholdBrush.thresholdRange,
1035
- onChange: handleRangeChange,
1036
- minValue: -1000,
1037
- maxValue: 1000,
1038
- step: 1,
1039
- showLabel: true,
1040
- allowNumberEdit: true,
1041
- showAdjustmentArrows: false
1042
- }));
1043
- }
1044
- }]
1045
- }]
1046
- });
1047
- }
1048
- function _getToolNamesFromCategory(category) {
1049
- let toolNames = [];
1050
- switch (category) {
1051
- case 'Brush':
1052
- toolNames = ['CircularBrush', 'SphereBrush'];
1053
- break;
1054
- case 'Eraser':
1055
- toolNames = ['CircularEraser', 'SphereEraser'];
1056
- break;
1057
- case 'ThresholdBrush':
1058
- toolNames = ['ThresholdCircularBrush', 'ThresholdSphereBrush'];
1059
- break;
1060
- default:
1061
- break;
1062
- }
1063
- return toolNames;
1064
- }
1065
- /* harmony default export */ const panels_SegmentationToolbox = (SegmentationToolbox);
1066
785
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone-dicom-seg/src/getPanelModule.tsx
1067
786
 
1068
787
 
1069
788
 
1070
789
 
1071
- const getPanelModule = _ref => {
1072
- let {
1073
- commandsManager,
1074
- servicesManager,
1075
- extensionManager,
1076
- configuration
1077
- } = _ref;
790
+ const getPanelModule = ({
791
+ commandsManager,
792
+ servicesManager,
793
+ extensionManager,
794
+ configuration,
795
+ title
796
+ }) => {
1078
797
  const {
1079
798
  customizationService
1080
799
  } = servicesManager.services;
1081
800
  const wrappedPanelSegmentation = configuration => {
1082
- const [appConfig] = (0,state/* useAppConfig */.M)();
1083
- const disableEditingForMode = customizationService.get('segmentation.disableEditing');
801
+ const [appConfig] = (0,state/* useAppConfig */.r)();
1084
802
  return /*#__PURE__*/react.createElement(PanelSegmentation, {
1085
803
  commandsManager: commandsManager,
1086
804
  servicesManager: servicesManager,
1087
805
  extensionManager: extensionManager,
1088
806
  configuration: {
1089
807
  ...configuration,
1090
- disableEditing: appConfig.disableEditing || disableEditingForMode?.value
808
+ disableEditing: appConfig.disableEditing,
809
+ ...customizationService.get('segmentation.panel')
1091
810
  }
1092
811
  });
1093
812
  };
1094
813
  const wrappedPanelSegmentationWithTools = configuration => {
1095
- const [appConfig] = (0,state/* useAppConfig */.M)();
1096
- return /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement(panels_SegmentationToolbox, {
814
+ const [appConfig] = (0,state/* useAppConfig */.r)();
815
+ return /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement(ui_src/* Toolbox */.OO, {
1097
816
  commandsManager: commandsManager,
1098
817
  servicesManager: servicesManager,
1099
818
  extensionManager: extensionManager,
819
+ buttonSectionId: "segmentationToolbox",
820
+ title: "Segmentation Tools",
1100
821
  configuration: {
1101
822
  ...configuration
1102
823
  }
@@ -1105,7 +826,9 @@ const getPanelModule = _ref => {
1105
826
  servicesManager: servicesManager,
1106
827
  extensionManager: extensionManager,
1107
828
  configuration: {
1108
- ...configuration
829
+ ...configuration,
830
+ disableEditing: appConfig.disableEditing,
831
+ ...customizationService.get('segmentation.panel')
1109
832
  }
1110
833
  }));
1111
834
  };
@@ -1124,12 +847,12 @@ const getPanelModule = _ref => {
1124
847
  }];
1125
848
  };
1126
849
  /* harmony default export */ const src_getPanelModule = (getPanelModule);
1127
- // EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/Filters/General/ImageMarchingSquares.js + 2 modules
1128
- var ImageMarchingSquares = __webpack_require__(49399);
850
+ // EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/Filters/General/ImageMarchingSquares.js
851
+ var ImageMarchingSquares = __webpack_require__(52754);
1129
852
  // EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/Common/Core/DataArray.js
1130
- var DataArray = __webpack_require__(54131);
1131
- // EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/Common/DataModel/ImageData.js + 2 modules
1132
- var ImageData = __webpack_require__(96372);
853
+ var DataArray = __webpack_require__(45128);
854
+ // EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/Common/DataModel/ImageData.js
855
+ var ImageData = __webpack_require__(51250);
1133
856
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone-dicom-seg/src/utils/hydrationUtils.ts
1134
857
 
1135
858
 
@@ -1147,13 +870,12 @@ var ImageData = __webpack_require__(96372);
1147
870
  *
1148
871
  * @returns Returns true upon successful update of viewports for segmentation rendering.
1149
872
  */
1150
- async function updateViewportsForSegmentationRendering(_ref) {
1151
- let {
1152
- viewportId,
1153
- loadFn,
1154
- servicesManager,
1155
- referencedDisplaySetInstanceUID
1156
- } = _ref;
873
+ async function updateViewportsForSegmentationRendering({
874
+ viewportId,
875
+ loadFn,
876
+ servicesManager,
877
+ referencedDisplaySetInstanceUID
878
+ }) {
1157
879
  const {
1158
880
  cornerstoneViewportService,
1159
881
  segmentationService,
@@ -1221,11 +943,10 @@ async function updateViewportsForSegmentationRendering(_ref) {
1221
943
  viewportGridService.setDisplaySetsForViewports(updatedViewports);
1222
944
  return true;
1223
945
  }
1224
- const getTargetViewport = _ref2 => {
1225
- let {
1226
- viewportId,
1227
- viewportGridService
1228
- } = _ref2;
946
+ const getTargetViewport = ({
947
+ viewportId,
948
+ viewportGridService
949
+ }) => {
1229
950
  const {
1230
951
  viewports,
1231
952
  activeViewportId
@@ -1247,12 +968,11 @@ const getTargetViewport = _ref2 => {
1247
968
  *
1248
969
  * @returns {Array} Returns an array of viewports that require updates for segmentation rendering.
1249
970
  */
1250
- function getUpdatedViewportsForSegmentation(_ref3) {
1251
- let {
1252
- viewportId,
1253
- servicesManager,
1254
- referencedDisplaySetInstanceUID
1255
- } = _ref3;
971
+ function getUpdatedViewportsForSegmentation({
972
+ viewportId,
973
+ servicesManager,
974
+ referencedDisplaySetInstanceUID
975
+ }) {
1256
976
  const {
1257
977
  hangingProtocolService,
1258
978
  displaySetService,
@@ -1288,7 +1008,7 @@ function getUpdatedViewportsForSegmentation(_ref3) {
1288
1008
  });
1289
1009
  }
1290
1010
  });
1291
- return updatedViewports;
1011
+ return updatedViewports.filter(v => v.viewportOptions?.viewportType !== 'volume3d');
1292
1012
  }
1293
1013
 
1294
1014
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone-dicom-seg/src/commandsModule.ts
@@ -1302,9 +1022,12 @@ function getUpdatedViewportsForSegmentation(_ref3) {
1302
1022
 
1303
1023
 
1304
1024
 
1025
+ const {
1026
+ segmentation: segmentationUtils
1027
+ } = dist_esm.utilities;
1305
1028
  const {
1306
1029
  datasetToBlob
1307
- } = dcmjs_es["default"].data;
1030
+ } = dcmjs_es/* default.data */.Ay.data;
1308
1031
  const {
1309
1032
  Cornerstone3D: {
1310
1033
  Segmentation: {
@@ -1312,28 +1035,28 @@ const {
1312
1035
  generateSegmentation
1313
1036
  }
1314
1037
  }
1315
- } = adapters_es.adaptersSEG;
1038
+ } = adapters_es/* adaptersSEG */.ql;
1316
1039
  const {
1317
1040
  Cornerstone3D: {
1318
1041
  RTSS: {
1319
1042
  generateRTSSFromSegmentations
1320
1043
  }
1321
1044
  }
1322
- } = adapters_es.adaptersRT;
1045
+ } = adapters_es/* adaptersRT */.f_;
1323
1046
  const {
1324
1047
  downloadDICOMData
1325
- } = adapters_es.helpers;
1326
- const commandsModule = _ref => {
1327
- let {
1328
- servicesManager,
1329
- extensionManager
1330
- } = _ref;
1048
+ } = adapters_es/* helpers */._$;
1049
+ const commandsModule = ({
1050
+ servicesManager,
1051
+ extensionManager
1052
+ }) => {
1331
1053
  const {
1332
1054
  uiNotificationService,
1333
1055
  segmentationService,
1334
1056
  uiDialogService,
1335
1057
  displaySetService,
1336
- viewportGridService
1058
+ viewportGridService,
1059
+ toolGroupService
1337
1060
  } = servicesManager.services;
1338
1061
  const actions = {
1339
1062
  /**
@@ -1360,10 +1083,9 @@ const commandsModule = _ref => {
1360
1083
  * @param params.viewportId - the target viewport ID.
1361
1084
  *
1362
1085
  */
1363
- createEmptySegmentationForViewport: async _ref2 => {
1364
- let {
1365
- viewportId
1366
- } = _ref2;
1086
+ createEmptySegmentationForViewport: async ({
1087
+ viewportId
1088
+ }) => {
1367
1089
  const viewport = getTargetViewport({
1368
1090
  viewportId,
1369
1091
  viewportGridService
@@ -1412,11 +1134,10 @@ const commandsModule = _ref => {
1412
1134
  * @param params.viewportId - the target viewport ID.
1413
1135
  *
1414
1136
  */
1415
- loadSegmentationsForViewport: async _ref3 => {
1416
- let {
1417
- segmentations,
1418
- viewportId
1419
- } = _ref3;
1137
+ loadSegmentationsForViewport: async ({
1138
+ segmentations,
1139
+ viewportId
1140
+ }) => {
1420
1141
  updateViewportsForSegmentationRendering({
1421
1142
  viewportId,
1422
1143
  servicesManager,
@@ -1479,13 +1200,13 @@ const commandsModule = _ref => {
1479
1200
  * @param params.displaySets - Array of display sets to be loaded for segmentation.
1480
1201
  *
1481
1202
  */
1482
- loadSegmentationDisplaySetsForViewport: async _ref4 => {
1483
- let {
1484
- viewportId,
1485
- displaySets
1486
- } = _ref4;
1203
+ loadSegmentationDisplaySetsForViewport: async ({
1204
+ viewportId,
1205
+ displaySets
1206
+ }) => {
1487
1207
  // Todo: handle adding more than one segmentation
1488
1208
  const displaySet = displaySets[0];
1209
+ const referencedDisplaySet = displaySetService.getDisplaySetByUID(displaySet.referencedDisplaySetInstanceUID);
1489
1210
  updateViewportsForSegmentationRendering({
1490
1211
  viewportId,
1491
1212
  servicesManager,
@@ -1496,6 +1217,8 @@ const commandsModule = _ref => {
1496
1217
  const serviceFunction = segDisplaySet.Modality === 'SEG' ? 'createSegmentationForSEGDisplaySet' : 'createSegmentationForRTDisplaySet';
1497
1218
  const boundFn = segmentationService[serviceFunction].bind(segmentationService);
1498
1219
  const segmentationId = await boundFn(segDisplaySet, null, suppressEvents);
1220
+ const segmentation = segmentationService.getSegmentation(segmentationId);
1221
+ segmentation.description = `S${referencedDisplaySet.SeriesNumber}: ${referencedDisplaySet.SeriesDescription}`;
1499
1222
  return segmentationId;
1500
1223
  }
1501
1224
  });
@@ -1513,11 +1236,10 @@ const commandsModule = _ref => {
1513
1236
  *
1514
1237
  * @returns Returns the generated segmentation data.
1515
1238
  */
1516
- generateSegmentation: _ref5 => {
1517
- let {
1518
- segmentationId,
1519
- options = {}
1520
- } = _ref5;
1239
+ generateSegmentation: ({
1240
+ segmentationId,
1241
+ options = {}
1242
+ }) => {
1521
1243
  const segmentation = dist_esm.segmentation.state.getSegmentation(segmentationId);
1522
1244
  const {
1523
1245
  referencedVolumeId
@@ -1537,7 +1259,7 @@ const commandsModule = _ref => {
1537
1259
  label,
1538
1260
  color
1539
1261
  } = segment;
1540
- const RecommendedDisplayCIELabValue = dcmjs_es["default"].data.Colors.rgb2DICOMLAB(color.slice(0, 3).map(value => value / 255)).map(value => Math.round(value));
1262
+ const RecommendedDisplayCIELabValue = dcmjs_es/* default.data */.Ay.data.Colors.rgb2DICOMLAB(color.slice(0, 3).map(value => value / 255)).map(value => Math.round(value));
1541
1263
  const segmentMetadata = {
1542
1264
  SegmentNumber: segmentIndex.toString(),
1543
1265
  SegmentLabel: label,
@@ -1570,10 +1292,9 @@ const commandsModule = _ref => {
1570
1292
  * @param params.segmentationId - ID of the segmentation to be downloaded.
1571
1293
  *
1572
1294
  */
1573
- downloadSegmentation: _ref6 => {
1574
- let {
1575
- segmentationId
1576
- } = _ref6;
1295
+ downloadSegmentation: ({
1296
+ segmentationId
1297
+ }) => {
1577
1298
  const segmentationInOHIF = segmentationService.getSegmentation(segmentationId);
1578
1299
  const generatedSegmentation = actions.generateSegmentation({
1579
1300
  segmentationId
@@ -1592,11 +1313,10 @@ const commandsModule = _ref => {
1592
1313
  * @returns {Object|void} Returns the naturalized report if successfully stored,
1593
1314
  * otherwise throws an error.
1594
1315
  */
1595
- storeSegmentation: async _ref7 => {
1596
- let {
1597
- segmentationId,
1598
- dataSource
1599
- } = _ref7;
1316
+ storeSegmentation: async ({
1317
+ segmentationId,
1318
+ dataSource
1319
+ }) => {
1600
1320
  const promptResult = await (0,default_src.createReportDialogPrompt)(uiDialogService, {
1601
1321
  extensionManager
1602
1322
  });
@@ -1641,15 +1361,14 @@ const commandsModule = _ref => {
1641
1361
  * converts dataset to downloadable blob.
1642
1362
  *
1643
1363
  */
1644
- downloadRTSS: _ref8 => {
1645
- let {
1646
- segmentationId
1647
- } = _ref8;
1364
+ downloadRTSS: ({
1365
+ segmentationId
1366
+ }) => {
1648
1367
  const segmentations = segmentationService.getSegmentation(segmentationId);
1649
1368
  const vtkUtils = {
1650
- vtkImageMarchingSquares: ImageMarchingSquares/* default */.ZP,
1651
- vtkDataArray: DataArray/* default */.ZP,
1652
- vtkImageData: ImageData/* default */.ZP
1369
+ vtkImageMarchingSquares: ImageMarchingSquares/* default */.Ay,
1370
+ vtkDataArray: DataArray/* default */.Ay,
1371
+ vtkImageData: ImageData/* default */.Ay
1653
1372
  };
1654
1373
  const RTSS = generateRTSSFromSegmentations(segmentations, src.classes.MetadataProvider, src.DicomMetadataStore, esm.cache, dist_esm.Enums, vtkUtils);
1655
1374
  try {
@@ -1661,6 +1380,38 @@ const commandsModule = _ref => {
1661
1380
  } catch (e) {
1662
1381
  console.warn(e);
1663
1382
  }
1383
+ },
1384
+ setBrushSize: ({
1385
+ value,
1386
+ toolNames
1387
+ }) => {
1388
+ const brushSize = Number(value);
1389
+ toolGroupService.getToolGroupIds()?.forEach(toolGroupId => {
1390
+ if (toolNames?.length === 0) {
1391
+ segmentationUtils.setBrushSizeForToolGroup(toolGroupId, brushSize);
1392
+ } else {
1393
+ toolNames?.forEach(toolName => {
1394
+ segmentationUtils.setBrushSizeForToolGroup(toolGroupId, brushSize, toolName);
1395
+ });
1396
+ }
1397
+ });
1398
+ },
1399
+ setThresholdRange: ({
1400
+ value,
1401
+ toolNames = ['ThresholdCircularBrush', 'ThresholdSphereBrush']
1402
+ }) => {
1403
+ toolGroupService.getToolGroupIds()?.forEach(toolGroupId => {
1404
+ const toolGroup = toolGroupService.getToolGroup(toolGroupId);
1405
+ toolNames?.forEach(toolName => {
1406
+ toolGroup.setToolConfiguration(toolName, {
1407
+ strategySpecificConfiguration: {
1408
+ THRESHOLD: {
1409
+ threshold: value
1410
+ }
1411
+ }
1412
+ });
1413
+ });
1414
+ });
1664
1415
  }
1665
1416
  };
1666
1417
  const definitions = {
@@ -1687,21 +1438,89 @@ const commandsModule = _ref => {
1687
1438
  },
1688
1439
  downloadRTSS: {
1689
1440
  commandFn: actions.downloadRTSS
1441
+ },
1442
+ setBrushSize: {
1443
+ commandFn: actions.setBrushSize
1444
+ },
1445
+ setThresholdRange: {
1446
+ commandFn: actions.setThresholdRange
1690
1447
  }
1691
1448
  };
1692
1449
  return {
1693
1450
  actions,
1694
- definitions
1451
+ definitions,
1452
+ defaultContext: 'SEGMENTATION'
1695
1453
  };
1696
1454
  };
1697
1455
  /* harmony default export */ const src_commandsModule = (commandsModule);
1698
- ;// CONCATENATED MODULE: ../../../extensions/cornerstone-dicom-seg/src/init.ts
1456
+ ;// CONCATENATED MODULE: ../../../extensions/cornerstone-dicom-seg/src/getToolbarModule.ts
1457
+ function getToolbarModule({
1458
+ commandsManager,
1459
+ servicesManager
1460
+ }) {
1461
+ const {
1462
+ segmentationService,
1463
+ toolGroupService
1464
+ } = servicesManager.services;
1465
+ return [{
1466
+ name: 'evaluate.cornerstone.segmentation',
1467
+ evaluate: ({
1468
+ viewportId,
1469
+ button,
1470
+ toolNames,
1471
+ disabledText
1472
+ }) => {
1473
+ // Todo: we need to pass in the button section Id since we are kind of
1474
+ // forcing the button to have black background since initially
1475
+ // it is designed for the toolbox not the toolbar on top
1476
+ // we should then branch the buttonSectionId to have different styles
1477
+ const segmentations = segmentationService.getSegmentations();
1478
+ if (!segmentations?.length) {
1479
+ return {
1480
+ disabled: true,
1481
+ className: '!text-common-bright !bg-black opacity-50',
1482
+ disabledText: disabledText ?? 'No segmentations available'
1483
+ };
1484
+ }
1485
+ const toolGroup = toolGroupService.getToolGroupForViewport(viewportId);
1486
+ if (!toolGroup) {
1487
+ return;
1488
+ }
1489
+ const toolName = getToolNameForButton(button);
1490
+ if (!toolGroup || !toolGroup.hasTool(toolName)) {
1491
+ return {
1492
+ disabled: true,
1493
+ className: '!text-common-bright ohif-disabled',
1494
+ disabledText: disabledText ?? 'Not available on the current viewport'
1495
+ };
1496
+ }
1497
+ const isPrimaryActive = toolNames ? toolNames.includes(toolGroup.getActivePrimaryMouseButtonTool()) : toolGroup.getActivePrimaryMouseButtonTool() === toolName;
1498
+ return {
1499
+ disabled: false,
1500
+ className: isPrimaryActive ? '!text-black !bg-primary-light hover:bg-primary-light hover-text-black hover:cursor-pointer' : '!text-common-bright !bg-black hover:bg-primary-light hover:cursor-pointer hover:text-black',
1501
+ // Todo: isActive right now is used for nested buttons where the primary
1502
+ // button needs to be fully rounded (vs partial rounded) when active
1503
+ // otherwise it does not have any other use
1504
+ isActive: isPrimaryActive
1505
+ };
1506
+ }
1507
+ }];
1508
+ }
1509
+
1510
+ // Todo: this is duplicate, we should move it to a shared location
1511
+ function getToolNameForButton(button) {
1512
+ const {
1513
+ props
1514
+ } = button;
1515
+ const commands = props?.commands || button.commands;
1516
+ const commandsArray = Array.isArray(commands) ? commands : [commands];
1517
+ const firstCommand = commandsArray[0];
1518
+ if (firstCommand?.commandOptions) {
1519
+ return firstCommand.commandOptions.toolName ?? props?.id ?? button.id;
1520
+ }
1699
1521
 
1700
- function init(_ref) {
1701
- let {
1702
- configuration = {}
1703
- } = _ref;
1704
- (0,dist_esm.addTool)(dist_esm.BrushTool);
1522
+ // use id as a fallback for toolName
1523
+ return props?.id ?? button.id;
1705
1524
  }
1706
1525
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone-dicom-seg/src/index.tsx
1707
1526
  function _extends() { _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 _extends.apply(this, arguments); }
@@ -1713,7 +1532,7 @@ function _extends() { _extends = Object.assign ? Object.assign.bind() : function
1713
1532
 
1714
1533
 
1715
1534
  const Component = /*#__PURE__*/react.lazy(() => {
1716
- return __webpack_require__.e(/* import() */ 451).then(__webpack_require__.bind(__webpack_require__, 4451));
1535
+ return __webpack_require__.e(/* import() */ 295).then(__webpack_require__.bind(__webpack_require__, 58295));
1717
1536
  });
1718
1537
  const OHIFCornerstoneSEGViewport = props => {
1719
1538
  return /*#__PURE__*/react.createElement(react.Suspense, {
@@ -1730,7 +1549,6 @@ const extension = {
1730
1549
  * You ID can be anything you want, but it should be unique.
1731
1550
  */
1732
1551
  id: id,
1733
- preRegistration: init,
1734
1552
  /**
1735
1553
  * PanelModule should provide a list of panels that will be available in OHIF
1736
1554
  * for Modes to consume and render. Each panel is defined by a {name,
@@ -1739,11 +1557,12 @@ const extension = {
1739
1557
  */
1740
1558
  getPanelModule: src_getPanelModule,
1741
1559
  getCommandsModule: src_commandsModule,
1742
- getViewportModule(_ref) {
1743
- let {
1744
- servicesManager,
1745
- extensionManager
1746
- } = _ref;
1560
+ getToolbarModule: getToolbarModule,
1561
+ getViewportModule({
1562
+ servicesManager,
1563
+ extensionManager,
1564
+ commandsManager
1565
+ }) {
1747
1566
  const ExtendedOHIFCornerstoneSEGViewport = props => {
1748
1567
  return /*#__PURE__*/react.createElement(OHIFCornerstoneSEGViewport, _extends({
1749
1568
  servicesManager: servicesManager,
@@ -1767,13 +1586,6 @@ const extension = {
1767
1586
  };
1768
1587
  /* harmony default export */ const cornerstone_dicom_seg_src = (extension);
1769
1588
 
1770
- /***/ }),
1771
-
1772
- /***/ 78753:
1773
- /***/ (() => {
1774
-
1775
- /* (ignored) */
1776
-
1777
1589
  /***/ })
1778
1590
 
1779
1591
  }]);