"use strict";
(globalThis["webpackChunk"] = globalThis["webpackChunk"] || []).push([[1730,2591,3343,5724],{

/***/ 75183
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {

/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   A: () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
var ChangeTypes;
(function (ChangeTypes) {
    ChangeTypes["Interaction"] = "Interaction";
    ChangeTypes["HandlesUpdated"] = "HandlesUpdated";
    ChangeTypes["StatsUpdated"] = "StatsUpdated";
    ChangeTypes["InitialSetup"] = "InitialSetup";
    ChangeTypes["Completed"] = "Completed";
    ChangeTypes["InterpolationUpdated"] = "InterpolationUpdated";
    ChangeTypes["History"] = "History";
    ChangeTypes["MetadataReferenceModified"] = "MetadataReferenceModified";
    ChangeTypes["LabelChange"] = "LabelChange";
})(ChangeTypes || (ChangeTypes = {}));
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ChangeTypes);


/***/ },

/***/ 94021
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {

/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   A: () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
var Events;
(function (Events) {
    Events["TOOL_ACTIVATED"] = "CORNERSTONE_TOOLS_TOOL_ACTIVATED";
    Events["TOOLGROUP_VIEWPORT_ADDED"] = "CORNERSTONE_TOOLS_TOOLGROUP_VIEWPORT_ADDED";
    Events["TOOLGROUP_VIEWPORT_REMOVED"] = "CORNERSTONE_TOOLS_TOOLGROUP_VIEWPORT_REMOVED";
    Events["TOOL_MODE_CHANGED"] = "CORNERSTONE_TOOLS_TOOL_MODE_CHANGED";
    Events["CROSSHAIR_TOOL_CENTER_CHANGED"] = "CORNERSTONE_TOOLS_CROSSHAIR_TOOL_CENTER_CHANGED";
    Events["VOLUMECROPPINGCONTROL_TOOL_CHANGED"] = "CORNERSTONE_TOOLS_VOLUMECROPPINGCONTROL_TOOL_CHANGED";
    Events["VOLUMECROPPING_TOOL_CHANGED"] = "CORNERSTONE_TOOLS_VOLUMECROPPING_TOOL_CHANGED";
    Events["STACK_PREFETCH_COMPLETE"] = "CORNERSTONE_TOOLS_STACK_PREFETCH_COMPLETE";
    Events["ANNOTATION_ADDED"] = "CORNERSTONE_TOOLS_ANNOTATION_ADDED";
    Events["ANNOTATION_COMPLETED"] = "CORNERSTONE_TOOLS_ANNOTATION_COMPLETED";
    Events["ANNOTATION_MODIFIED"] = "CORNERSTONE_TOOLS_ANNOTATION_MODIFIED";
    Events["ANNOTATION_REMOVED"] = "CORNERSTONE_TOOLS_ANNOTATION_REMOVED";
    Events["ANNOTATION_SELECTION_CHANGE"] = "CORNERSTONE_TOOLS_ANNOTATION_SELECTION_CHANGE";
    Events["ANNOTATION_LOCK_CHANGE"] = "CORNERSTONE_TOOLS_ANNOTATION_LOCK_CHANGE";
    Events["ANNOTATION_VISIBILITY_CHANGE"] = "CORNERSTONE_TOOLS_ANNOTATION_VISIBILITY_CHANGE";
    Events["ANNOTATION_RENDERED"] = "CORNERSTONE_TOOLS_ANNOTATION_RENDERED";
    Events["ANNOTATION_CUT_MERGE_PROCESS_COMPLETED"] = "CORNERSTONE_TOOLS_ANNOTATION_CUT_MERGE_PROCESS_COMPLETED";
    Events["ANNOTATION_INTERPOLATION_PROCESS_COMPLETED"] = "CORNERSTONE_TOOLS_ANNOTATION_INTERPOLATION_PROCESS_COMPLETED";
    Events["INTERPOLATED_ANNOTATIONS_REMOVED"] = "CORNERSTONE_TOOLS_INTERPOLATED_ANNOTATIONS_REMOVED";
    Events["SEGMENTATION_MODIFIED"] = "CORNERSTONE_TOOLS_SEGMENTATION_MODIFIED";
    Events["SEGMENTATION_RENDERED"] = "CORNERSTONE_TOOLS_SEGMENTATION_RENDERED";
    Events["SEGMENTATION_REPRESENTATION_ADDED"] = "CORNERSTONE_TOOLS_SEGMENTATION_REPRESENTATION_ADDED";
    Events["SEGMENTATION_ADDED"] = "CORNERSTONE_TOOLS_SEGMENTATION_ADDED";
    Events["SEGMENTATION_REPRESENTATION_MODIFIED"] = "CORNERSTONE_TOOLS_SEGMENTATION_REPRESENTATION_MODIFIED";
    Events["SEGMENTATION_REMOVED"] = "CORNERSTONE_TOOLS_SEGMENTATION_REMOVED";
    Events["SEGMENTATION_REPRESENTATION_REMOVED"] = "CORNERSTONE_TOOLS_SEGMENTATION_REPRESENTATION_REMOVED";
    Events["SEGMENTATION_DATA_MODIFIED"] = "CORNERSTONE_TOOLS_SEGMENTATION_DATA_MODIFIED";
    Events["HISTORY_UNDO"] = "CORNERSTONE_TOOLS_HISTORY_UNDO";
    Events["HISTORY_REDO"] = "CORNERSTONE_TOOLS_HISTORY_REDO";
    Events["KEY_DOWN"] = "CORNERSTONE_TOOLS_KEY_DOWN";
    Events["KEY_UP"] = "CORNERSTONE_TOOLS_KEY_UP";
    Events["MOUSE_DOWN"] = "CORNERSTONE_TOOLS_MOUSE_DOWN";
    Events["MOUSE_UP"] = "CORNERSTONE_TOOLS_MOUSE_UP";
    Events["MOUSE_DOWN_ACTIVATE"] = "CORNERSTONE_TOOLS_MOUSE_DOWN_ACTIVATE";
    Events["MOUSE_DRAG"] = "CORNERSTONE_TOOLS_MOUSE_DRAG";
    Events["MOUSE_MOVE"] = "CORNERSTONE_TOOLS_MOUSE_MOVE";
    Events["MOUSE_CLICK"] = "CORNERSTONE_TOOLS_MOUSE_CLICK";
    Events["MOUSE_DOUBLE_CLICK"] = "CORNERSTONE_TOOLS_MOUSE_DOUBLE_CLICK";
    Events["MOUSE_WHEEL"] = "CORNERSTONE_TOOLS_MOUSE_WHEEL";
    Events["TOUCH_START"] = "CORNERSTONE_TOOLS_TOUCH_START";
    Events["TOUCH_START_ACTIVATE"] = "CORNERSTONE_TOOLS_TOUCH_START_ACTIVATE";
    Events["TOUCH_PRESS"] = "CORNERSTONE_TOOLS_TOUCH_PRESS";
    Events["TOUCH_DRAG"] = "CORNERSTONE_TOOLS_TOUCH_DRAG";
    Events["TOUCH_END"] = "CORNERSTONE_TOOLS_TOUCH_END";
    Events["TOUCH_TAP"] = "CORNERSTONE_TOOLS_TAP";
    Events["TOUCH_SWIPE"] = "CORNERSTONE_TOOLS_SWIPE";
})(Events || (Events = {}));
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Events);


/***/ },

/***/ 18682
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {

/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   A: () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
var SegmentationRepresentations;
(function (SegmentationRepresentations) {
    SegmentationRepresentations["Labelmap"] = "Labelmap";
    SegmentationRepresentations["Contour"] = "Contour";
    SegmentationRepresentations["Surface"] = "Surface";
})(SegmentationRepresentations || (SegmentationRepresentations = {}));
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (SegmentationRepresentations);


/***/ },

/***/ 84093
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {

/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   A: () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
var StrategyCallbacks;
(function (StrategyCallbacks) {
    StrategyCallbacks["CalculateCursorGeometry"] = "calculateCursorGeometry";
    StrategyCallbacks["RenderCursor"] = "renderCursor";
    StrategyCallbacks["OnInteractionStart"] = "onInteractionStart";
    StrategyCallbacks["OnInteractionEnd"] = "onInteractionEnd";
    StrategyCallbacks["Preview"] = "preview";
    StrategyCallbacks["RejectPreview"] = "rejectPreview";
    StrategyCallbacks["AcceptPreview"] = "acceptPreview";
    StrategyCallbacks["Fill"] = "fill";
    StrategyCallbacks["Interpolate"] = "interpolate";
    StrategyCallbacks["StrategyFunction"] = "strategyFunction";
    StrategyCallbacks["CreateIsInThreshold"] = "createIsInThreshold";
    StrategyCallbacks["Initialize"] = "initialize";
    StrategyCallbacks["INTERNAL_setValue"] = "setValue";
    StrategyCallbacks["AddPreview"] = "addPreview";
    StrategyCallbacks["ComputeInnerCircleRadius"] = "computeInnerCircleRadius";
    StrategyCallbacks["GetStatistics"] = "getStatistics";
    StrategyCallbacks["EnsureImageVolumeFor3DManipulation"] = "ensureImageVolumeFor3DManipulation";
    StrategyCallbacks["EnsureSegmentationVolumeFor3DManipulation"] = "ensureSegmentationVolumeFor3DManipulation";
})(StrategyCallbacks || (StrategyCallbacks = {}));
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (StrategyCallbacks);


/***/ },

/***/ 66452
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {

/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   i: () => (/* binding */ MouseBindings),
/* harmony export */   q: () => (/* binding */ KeyboardBindings)
/* harmony export */ });
var MouseBindings;
(function (MouseBindings) {
    MouseBindings[MouseBindings["Primary"] = 1] = "Primary";
    MouseBindings[MouseBindings["Secondary"] = 2] = "Secondary";
    MouseBindings[MouseBindings["Primary_And_Secondary"] = 3] = "Primary_And_Secondary";
    MouseBindings[MouseBindings["Auxiliary"] = 4] = "Auxiliary";
    MouseBindings[MouseBindings["Primary_And_Auxiliary"] = 5] = "Primary_And_Auxiliary";
    MouseBindings[MouseBindings["Secondary_And_Auxiliary"] = 6] = "Secondary_And_Auxiliary";
    MouseBindings[MouseBindings["Primary_And_Secondary_And_Auxiliary"] = 7] = "Primary_And_Secondary_And_Auxiliary";
    MouseBindings[MouseBindings["Fourth_Button"] = 8] = "Fourth_Button";
    MouseBindings[MouseBindings["Fifth_Button"] = 16] = "Fifth_Button";
    MouseBindings[MouseBindings["Wheel"] = 524288] = "Wheel";
    MouseBindings[MouseBindings["Wheel_Primary"] = 524289] = "Wheel_Primary";
})(MouseBindings || (MouseBindings = {}));
var KeyboardBindings;
(function (KeyboardBindings) {
    KeyboardBindings[KeyboardBindings["Shift"] = 16] = "Shift";
    KeyboardBindings[KeyboardBindings["Ctrl"] = 17] = "Ctrl";
    KeyboardBindings[KeyboardBindings["Alt"] = 18] = "Alt";
    KeyboardBindings[KeyboardBindings["Meta"] = 91] = "Meta";
    KeyboardBindings[KeyboardBindings["ShiftCtrl"] = 1617] = "ShiftCtrl";
    KeyboardBindings[KeyboardBindings["ShiftAlt"] = 1618] = "ShiftAlt";
    KeyboardBindings[KeyboardBindings["ShiftMeta"] = 1691] = "ShiftMeta";
    KeyboardBindings[KeyboardBindings["CtrlAlt"] = 1718] = "CtrlAlt";
    KeyboardBindings[KeyboardBindings["CtrlMeta"] = 1791] = "CtrlMeta";
    KeyboardBindings[KeyboardBindings["AltMeta"] = 1891] = "AltMeta";
})(KeyboardBindings || (KeyboardBindings = {}));



/***/ },

/***/ 49892
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {

/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   A: () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
var ToolModes;
(function (ToolModes) {
    ToolModes["Active"] = "Active";
    ToolModes["Passive"] = "Passive";
    ToolModes["Enabled"] = "Enabled";
    ToolModes["Disabled"] = "Disabled";
})(ToolModes || (ToolModes = {}));
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ToolModes);


/***/ },

/***/ 10401
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {

/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   H: () => (/* binding */ Swipe)
/* harmony export */ });
var Swipe;
(function (Swipe) {
    Swipe["UP"] = "UP";
    Swipe["DOWN"] = "DOWN";
    Swipe["LEFT"] = "LEFT";
    Swipe["RIGHT"] = "RIGHT";
})(Swipe || (Swipe = {}));



/***/ },

/***/ 29857
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {

// ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);

// EXPORTS
__webpack_require__.d(__webpack_exports__, {
  AnnotationStyleStates: () => (/* reexport */ enums_AnnotationStyleStates),
  ChangeTypes: () => (/* reexport */ ChangeTypes/* default */.A),
  Events: () => (/* reexport */ Events/* default */.A),
  KeyboardBindings: () => (/* reexport */ ToolBindings/* KeyboardBindings */.q),
  MeasurementType: () => (/* reexport */ MeasurementType),
  MouseBindings: () => (/* reexport */ ToolBindings/* MouseBindings */.i),
  SegmentationRepresentations: () => (/* reexport */ SegmentationRepresentations/* default */.A),
  StrategyCallbacks: () => (/* reexport */ StrategyCallbacks/* default */.A),
  Swipe: () => (/* reexport */ Touch/* Swipe */.H),
  ToolModes: () => (/* reexport */ ToolModes/* default */.A),
  WorkerTypes: () => (/* reexport */ WorkerTypes)
});

// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/enums/ToolBindings.js
var ToolBindings = __webpack_require__(66452);
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/enums/ToolModes.js
var ToolModes = __webpack_require__(49892);
;// ../../../node_modules/@cornerstonejs/tools/dist/esm/enums/AnnotationStyleStates.js
var AnnotationStyleStates;
(function (AnnotationStyleStates) {
    AnnotationStyleStates["Default"] = "";
    AnnotationStyleStates["Highlighted"] = "Highlighted";
    AnnotationStyleStates["Selected"] = "Selected";
    AnnotationStyleStates["Locked"] = "Locked";
    AnnotationStyleStates["AutoGenerated"] = "AutoGenerated";
})(AnnotationStyleStates || (AnnotationStyleStates = {}));
/* harmony default export */ const enums_AnnotationStyleStates = (AnnotationStyleStates);

// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/enums/Events.js
var Events = __webpack_require__(94021);
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/enums/SegmentationRepresentations.js
var SegmentationRepresentations = __webpack_require__(18682);
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/enums/Touch.js
var Touch = __webpack_require__(10401);
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/enums/StrategyCallbacks.js
var StrategyCallbacks = __webpack_require__(84093);
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/enums/ChangeTypes.js
var ChangeTypes = __webpack_require__(75183);
;// ../../../node_modules/@cornerstonejs/tools/dist/esm/enums/WorkerTypes.js
var WorkerTypes_ChangeTypes;
(function (ChangeTypes) {
    ChangeTypes["POLYSEG_CONTOUR_TO_LABELMAP"] = "Converting Contour to Labelmap";
    ChangeTypes["POLYSEG_SURFACE_TO_LABELMAP"] = "Converting Surfaces to Labelmap";
    ChangeTypes["POLYSEG_CONTOUR_TO_SURFACE"] = "Converting Contour to Surface";
    ChangeTypes["POLYSEG_LABELMAP_TO_SURFACE"] = "Converting Labelmap to Surface";
    ChangeTypes["SURFACE_CLIPPING"] = "Clipping Surfaces";
    ChangeTypes["COMPUTE_STATISTICS"] = "Computing Statistics";
    ChangeTypes["INTERPOLATE_LABELMAP"] = "Interpolating Labelmap";
    ChangeTypes["COMPUTE_LARGEST_BIDIRECTIONAL"] = "Computing Largest Bidirectional";
    ChangeTypes["GENERATE_CONTOUR_SETS"] = "Generating Contour Sets";
})(WorkerTypes_ChangeTypes || (WorkerTypes_ChangeTypes = {}));
/* harmony default export */ const WorkerTypes = (WorkerTypes_ChangeTypes);

;// ../../../node_modules/@cornerstonejs/tools/dist/esm/enums/MeasurementType.js
var MeasurementType;
(function (MeasurementType) {
    MeasurementType["Linear"] = "Linear";
    MeasurementType["Area"] = "Area";
    MeasurementType["Volume"] = "Volume";
    MeasurementType["Pixel"] = "Pixel";
})(MeasurementType || (MeasurementType = {}));

;// ../../../node_modules/@cornerstonejs/tools/dist/esm/enums/index.js













/***/ },

/***/ 14696
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {


// EXPORTS
__webpack_require__.d(__webpack_exports__, {
  "default": () => (/* binding */ dynamicVolumeExtension)
});

// NAMESPACE OBJECT: ../../../extensions/cornerstone-dynamic-volume/src/actions/index.ts
var actions_namespaceObject = {};
__webpack_require__.r(actions_namespaceObject);
__webpack_require__.d(actions_namespaceObject, {
  updateSegmentationsChartDisplaySet: () => (updateSegmentationsChartDisplaySet)
});

;// ../../../extensions/cornerstone-dynamic-volume/package.json
const package_namespaceObject = /*#__PURE__*/JSON.parse('{"UU":"@ohif/extension-cornerstone-dynamic-volume"}');
;// ../../../extensions/cornerstone-dynamic-volume/src/id.js

const id = package_namespaceObject.UU;
const SOPClassHandlerName = 'dynamic-volume';

// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/index.js
var esm = __webpack_require__(4667);
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/core/dist/esm/index.js + 1 modules
var dist_esm = __webpack_require__(15327);
// EXTERNAL MODULE: ../../core/src/index.ts + 69 modules
var src = __webpack_require__(42356);
;// ../../../extensions/cornerstone-dynamic-volume/src/actions/updateSegmentationsChartDisplaySet.ts



const CHART_MODALITY = 'CHT';
const SEG_CHART_INSTANCE_UID = src/* utils */.Wp.guid();

// Private SOPClassUid for chart data
const ChartDataSOPClassUid = '1.9.451.13215.7.3.2.7.6.1';
const {
  utilities: csToolsUtils
} = esm;
function _getDateTimeStr() {
  const now = new Date();
  const date = now.getFullYear() + ('0' + now.getUTCMonth()).slice(-2) + ('0' + now.getUTCDate()).slice(-2);
  const time = ('0' + now.getUTCHours()).slice(-2) + ('0' + now.getUTCMinutes()).slice(-2) + ('0' + now.getUTCSeconds()).slice(-2);
  return {
    date,
    time
  };
}
function _getTimePointsDataByTagName(volume, timePointsTag) {
  const uniqueTimePoints = volume.imageIds.reduce((timePoints, imageId) => {
    const instance = src/* DicomMetadataStore */.H8.getInstanceByImageId(imageId);
    const timePointValue = instance[timePointsTag];
    if (timePointValue !== undefined) {
      timePoints.add(timePointValue);
    }
    return timePoints;
  }, new Set());
  return Array.from(uniqueTimePoints).sort((a, b) => a - b);
}
function _convertTimePointsUnit(timePoints, timePointsUnit) {
  const validUnits = ['ms', 's', 'm', 'h'];
  const divisors = [1000, 60, 60];
  const currentUnitIndex = validUnits.indexOf(timePointsUnit);
  let divisor = 1;
  if (currentUnitIndex !== -1) {
    for (let i = currentUnitIndex; i < validUnits.length - 1; i++) {
      const newDivisor = divisor * divisors[i];
      const greaterThanDivisorCount = timePoints.filter(timePoint => timePoint > newDivisor).length;

      // Change the scale only if more than 50% of the time points are
      // greater than the new divisor.
      if (greaterThanDivisorCount <= timePoints.length / 2) {
        break;
      }
      divisor = newDivisor;
      timePointsUnit = validUnits[i + 1];
    }
    if (divisor > 1) {
      timePoints = timePoints.map(timePoint => timePoint / divisor);
    }
  }
  return {
    timePoints,
    timePointsUnit
  };
}

// It currently supports only one tag but a few other will be added soon
// Supported 4D Tags
//   (0018,1060) Trigger Time                   [NOK]
//   (0018,0081) Echo Time                      [NOK]
//   (0018,0086) Echo Number                    [NOK]
//   (0020,0100) Temporal Position Identifier   [NOK]
//   (0054,1300) FrameReferenceTime             [OK]
function _getTimePointsData(volume) {
  const timePointsTags = {
    FrameReferenceTime: {
      unit: 'ms'
    }
  };
  const timePointsTagNames = Object.keys(timePointsTags);
  let timePoints;
  let timePointsUnit;
  for (let i = 0; i < timePointsTagNames.length; i++) {
    const tagName = timePointsTagNames[i];
    const curTimePoints = _getTimePointsDataByTagName(volume, tagName);
    if (curTimePoints.length) {
      timePoints = curTimePoints;
      timePointsUnit = timePointsTags[tagName].unit;
      break;
    }
  }
  if (!timePoints.length) {
    const concatTagNames = timePointsTagNames.join(', ');
    throw new Error(`Could not extract time points data for the following tags: ${concatTagNames}`);
  }
  const convertedTimePoints = _convertTimePointsUnit(timePoints, timePointsUnit);
  timePoints = convertedTimePoints.timePoints;
  timePointsUnit = convertedTimePoints.timePointsUnit;
  return {
    timePoints,
    timePointsUnit
  };
}
function _getSegmentationData(segmentation, volumesTimePointsCache, {
  servicesManager
}) {
  const {
    displaySetService,
    segmentationService,
    viewportGridService
  } = servicesManager.services;
  const displaySets = displaySetService.getActiveDisplaySets();
  const dynamic4DDisplaySet = displaySets.find(displaySet => {
    const anInstance = displaySet.instances?.[0];
    if (anInstance) {
      return anInstance.FrameReferenceTime !== undefined || anInstance.NumberOfTimeSlices !== undefined;
    }
    return false;
  });

  // const referencedDynamicVolume = cs.cache.getVolume(dynamic4DDisplaySet.displaySetInstanceUID);
  let volumeCacheKey;
  const volumeId = dynamic4DDisplaySet.displaySetInstanceUID;
  for (const [key] of dist_esm.cache._volumeCache) {
    if (key.includes(volumeId)) {
      volumeCacheKey = key;
      break;
    }
  }
  let referencedDynamicVolume;
  if (volumeCacheKey) {
    referencedDynamicVolume = dist_esm.cache.getVolume(volumeCacheKey);
  }
  const {
    StudyInstanceUID,
    StudyDescription
  } = src/* DicomMetadataStore */.H8.getInstanceByImageId(referencedDynamicVolume.imageIds[0]);
  const segmentationVolume = segmentationService.getLabelmapVolume(segmentation.segmentationId);
  const maskVolumeId = segmentationVolume?.volumeId;
  const [timeData, _] = csToolsUtils.dynamicVolume.getDataInTime(referencedDynamicVolume, {
    maskVolumeId
  });
  const pixelCount = timeData.length;
  if (pixelCount === 0) {
    return [];
  }

  // Todo: this is useless we should be able to grab color with just segRepUID and segmentIndex
  // const color = csTools.segmentation.config.color.getSegmentIndexColor(
  //   segmentationRepresentationUID,
  //   1 // segmentIndex
  // );
  const viewportId = viewportGridService.getActiveViewportId();
  const color = segmentationService.getSegmentColor(viewportId, segmentation.segmentationId, 1);
  const hexColor = dist_esm.utilities.color.rgbToHex(color[0], color[1], color[2]);
  let timePointsData = volumesTimePointsCache.get(referencedDynamicVolume);
  if (!timePointsData) {
    timePointsData = _getTimePointsData(referencedDynamicVolume);
    volumesTimePointsCache.set(referencedDynamicVolume, timePointsData);
  }
  const {
    timePoints,
    timePointsUnit
  } = timePointsData;
  if (timePoints.length !== timeData[0].length) {
    throw new Error('Invalid number of time points returned');
  }
  const timepointsCount = timePoints.length;
  const chartSeriesData = new Array(timepointsCount);
  for (let i = 0; i < timepointsCount; i++) {
    const average = timeData.reduce((acc, cur) => acc + cur[i] / pixelCount, 0);
    chartSeriesData[i] = [timePoints[i], average];
  }
  return {
    StudyInstanceUID,
    StudyDescription,
    chartData: {
      series: {
        label: segmentation.label,
        points: chartSeriesData,
        color: hexColor
      },
      axis: {
        x: {
          label: `Time (${timePointsUnit})`
        },
        y: {
          label: `Vl (Bq/ml)`
        }
      }
    }
  };
}
function _getInstanceFromSegmentations(segmentations, {
  servicesManager
}) {
  if (!segmentations.length) {
    return;
  }
  const volumesTimePointsCache = new WeakMap();
  const segmentationsData = segmentations.map(segmentation => _getSegmentationData(segmentation, volumesTimePointsCache, {
    servicesManager
  }));
  const {
    date: seriesDate,
    time: seriesTime
  } = _getDateTimeStr();
  const series = segmentationsData.reduce((allSeries, curSegData) => {
    return [...allSeries, curSegData.chartData.series];
  }, []);
  const instance = {
    SOPClassUID: ChartDataSOPClassUid,
    Modality: CHART_MODALITY,
    SOPInstanceUID: src/* utils */.Wp.guid(),
    SeriesDate: seriesDate,
    SeriesTime: seriesTime,
    SeriesInstanceUID: SEG_CHART_INSTANCE_UID,
    StudyInstanceUID: segmentationsData[0].StudyInstanceUID,
    StudyDescription: segmentationsData[0].StudyDescription,
    SeriesNumber: 100,
    SeriesDescription: 'Segmentation chart series data',
    chartData: {
      series,
      axis: {
        ...segmentationsData[0].chartData.axis
      }
    }
  };
  const seriesMetadata = {
    StudyInstanceUID: instance.StudyInstanceUID,
    StudyDescription: instance.StudyDescription,
    SeriesInstanceUID: instance.SeriesInstanceUID,
    SeriesDescription: instance.SeriesDescription,
    SeriesNumber: instance.SeriesNumber,
    SeriesTime: instance.SeriesTime,
    SOPClassUID: instance.SOPClassUID,
    Modality: instance.Modality
  };
  return {
    seriesMetadata,
    instance
  };
}
function updateSegmentationsChartDisplaySet({
  servicesManager
}) {
  const {
    segmentationService
  } = servicesManager.services;
  const segmentations = segmentationService.getSegmentations();
  const {
    seriesMetadata,
    instance
  } = _getInstanceFromSegmentations(segmentations, {
    servicesManager
  }) ?? {};
  if (seriesMetadata && instance) {
    // An event is triggered after adding the instance and the displaySet is created
    src/* DicomMetadataStore */.H8.addSeriesMetadata([seriesMetadata], true);
    src/* DicomMetadataStore */.H8.addInstances([instance], true);
  }
}

;// ../../../extensions/cornerstone-dynamic-volume/src/actions/index.ts


;// ../../../extensions/cornerstone-dynamic-volume/src/commandsModule.ts




const {
  downloadCsv
} = src/* utils */.Wp;
const commandsModule = ({
  commandsManager,
  servicesManager
}) => {
  const services = servicesManager.services;
  const {
    displaySetService,
    viewportGridService,
    segmentationService
  } = services;
  const actions = {
    ...actions_namespaceObject,
    getDynamic4DDisplaySet: () => {
      const displaySets = displaySetService.getActiveDisplaySets();
      const dynamic4DDisplaySet = displaySets.find(displaySet => {
        const anInstance = displaySet.instances?.[0];
        if (anInstance) {
          return anInstance.FrameReferenceTime !== undefined || anInstance.NumberOfTimeSlices !== undefined || anInstance.TemporalPositionIdentifier !== undefined;
        }
        return false;
      });
      return dynamic4DDisplaySet;
    },
    getComputedDisplaySets: () => {
      const displaySetCache = displaySetService.getDisplaySetCache();
      const cachedDisplaySets = [...displaySetCache.values()];
      const computedDisplaySets = cachedDisplaySets.filter(displaySet => {
        return displaySet.isDerived;
      });
      return computedDisplaySets;
    },
    exportTimeReportCSV: ({
      segmentations,
      summaryStats
    }) => {
      const dynamic4DDisplaySet = actions.getDynamic4DDisplaySet();
      const volumeId = dynamic4DDisplaySet?.displaySetInstanceUID;

      // cache._volumeCache is a map that has a key that includes the volumeId
      // it is not exactly the volumeId, but it is the key that includes the volumeId
      // so we can't do cache._volumeCache.get(volumeId) we should iterate
      // over the keys and find the one that includes the volumeId
      let volumeCacheKey;
      for (const [key] of dist_esm.cache._volumeCache) {
        if (key.includes(volumeId)) {
          volumeCacheKey = key;
          break;
        }
      }
      let dynamicVolume;
      if (volumeCacheKey) {
        dynamicVolume = dist_esm.cache.getVolume(volumeCacheKey);
      }
      const instance = dynamic4DDisplaySet.instances[0];
      const csv = [];

      // CSV header information with placeholder empty values for the metadata lines
      csv.push(`Patient ID,${instance.PatientID},`);
      csv.push(`Study Date,${instance.StudyDate},`);
      csv.push(`StudyInstanceUID,${instance.StudyInstanceUID},`);
      csv.push(`StudyDescription,${instance.StudyDescription},`);
      csv.push(`SeriesInstanceUID,${instance.SeriesInstanceUID},`);

      // empty line
      csv.push('');
      csv.push('');

      // Helper function to calculate standard deviation
      function calculateStandardDeviation(data) {
        const n = data.length;
        const mean = data.reduce((acc, value) => acc + value, 0) / n;
        const squaredDifferences = data.map(value => (value - mean) ** 2);
        const variance = squaredDifferences.reduce((acc, value) => acc + value, 0) / n;
        const stdDeviation = Math.sqrt(variance);
        return stdDeviation;
      }
      // Iterate through each segmentation to get the timeData and ijkCoords
      segmentations.forEach(segmentation => {
        const volume = segmentationService.getLabelmapVolume(segmentation.segmentationId);
        const [timeData, ijkCoords] = esm.utilities.dynamicVolume.getDataInTime(dynamicVolume, {
          maskVolumeId: volume.volumeId
        });
        if (summaryStats) {
          // Adding column headers for pixel identifier and segmentation label ids
          let headers = 'Operation,Segmentation Label ID';
          const maxLength = dynamicVolume.numTimePoints;
          for (let t = 0; t < maxLength; t++) {
            headers += `,Time Point ${t}`;
          }
          csv.push(headers);
          // // perform summary statistics on the timeData including for each time point, mean, median, min, max, and standard deviation for
          // // all the voxels in the ROI
          const mean = [];
          const min = [];
          const minIJK = [];
          const max = [];
          const maxIJK = [];
          const std = [];
          const numVoxels = timeData.length;
          // Helper function to calculate standard deviation
          for (let timeIndex = 0; timeIndex < maxLength; timeIndex++) {
            // for each voxel in the ROI, get the value at the current time point
            const voxelValues = [];
            let sum = 0;
            let minValue = Infinity;
            let maxValue = -Infinity;
            let minIndex = 0;
            let maxIndex = 0;

            // Single pass through the data to collect all needed values
            for (let voxelIndex = 0; voxelIndex < numVoxels; voxelIndex++) {
              const value = timeData[voxelIndex][timeIndex];
              voxelValues.push(value);
              sum += value;
              if (value < minValue) {
                minValue = value;
                minIndex = voxelIndex;
              }
              if (value > maxValue) {
                maxValue = value;
                maxIndex = voxelIndex;
              }
            }
            mean.push(sum / numVoxels);
            min.push(minValue);
            minIJK.push(ijkCoords[minIndex]);
            max.push(maxValue);
            maxIJK.push(ijkCoords[maxIndex]);
            std.push(calculateStandardDeviation(voxelValues));
          }
          let row = `Mean,${segmentation.label}`;
          // Generate separate rows for each statistic
          for (let t = 0; t < maxLength; t++) {
            row += `,${mean[t]}`;
          }
          csv.push(row);
          row = `Standard Deviation,${segmentation.label}`;
          for (let t = 0; t < maxLength; t++) {
            row += `,${std[t]}`;
          }
          csv.push(row);
          row = `Min,${segmentation.label}`;
          for (let t = 0; t < maxLength; t++) {
            row += `,${min[t]}`;
          }
          csv.push(row);
          row = `Max,${segmentation.label}`;
          for (let t = 0; t < maxLength; t++) {
            row += `,${max[t]}`;
          }
          csv.push(row);
        } else {
          // Adding column headers for pixel identifier and segmentation label ids
          let headers = 'Pixel Identifier (IJK),Segmentation Label ID';
          const maxLength = dynamicVolume.numTimePoints;
          for (let t = 0; t < maxLength; t++) {
            headers += `,Time Point ${t}`;
          }
          csv.push(headers);
          // Assuming timeData and ijkCoords are of the same length
          for (let i = 0; i < timeData.length; i++) {
            // Generate the pixel identifier
            const pixelIdentifier = `${ijkCoords[i][0]}_${ijkCoords[i][1]}_${ijkCoords[i][2]}`;

            // Start a new row for the current pixel
            let row = `${pixelIdentifier},${segmentation.label}`;

            // Add time data points for this pixel
            for (let t = 0; t < timeData[i].length; t++) {
              row += `,${timeData[i][t]}`;
            }

            // Append the row to the CSV array
            csv.push(row);
          }
        }
      });

      // Convert to CSV string
      const csvContent = csv.join('\n');

      // Generate filename and trigger download
      const filename = `${instance.PatientID}.csv`;
      downloadCsv(csvContent, {
        filename
      });
    },
    swapDynamicWithComputedDisplaySet: ({
      displaySet
    }) => {
      const computedDisplaySet = displaySet;
      const displaySetCache = displaySetService.getDisplaySetCache();
      const cachedDisplaySetKeys = [displaySetCache.keys()];
      const {
        displaySetInstanceUID
      } = computedDisplaySet;
      // Check to see if computed display set is already in cache
      if (!cachedDisplaySetKeys.includes(displaySetInstanceUID)) {
        displaySetCache.set(displaySetInstanceUID, computedDisplaySet);
      }

      // Get all viewports and their corresponding indices
      const {
        viewports
      } = viewportGridService.getState();

      // get the viewports in the grid
      // iterate over them and find the ones that are showing a dynamic
      // volume (displaySet), and replace that exact displaySet with the
      // computed displaySet

      const dynamic4DDisplaySet = actions.getDynamic4DDisplaySet();
      const viewportsToUpdate = [];
      for (const [key, value] of viewports) {
        const viewport = value;
        const viewportOptions = viewport.viewportOptions;
        const {
          displaySetInstanceUIDs
        } = viewport;
        const displaySetInstanceUIDIndex = displaySetInstanceUIDs.indexOf(dynamic4DDisplaySet.displaySetInstanceUID);
        if (displaySetInstanceUIDIndex !== -1) {
          const newViewport = {
            viewportId: viewport.viewportId,
            // merge the other displaySetInstanceUIDs with the new one
            displaySetInstanceUIDs: [...displaySetInstanceUIDs.slice(0, displaySetInstanceUIDIndex), displaySetInstanceUID, ...displaySetInstanceUIDs.slice(displaySetInstanceUIDIndex + 1)],
            viewportOptions: {
              initialImageOptions: viewportOptions.initialImageOptions,
              viewportType: 'volume',
              orientation: viewportOptions.orientation,
              background: viewportOptions.background
            }
          };
          viewportsToUpdate.push(newViewport);
        }
      }
      commandsManager.run('setDisplaySetsForViewports', {
        viewportsToUpdate
      });
    },
    swapComputedWithDynamicDisplaySet: () => {
      // Todo: this assumes there is only one dynamic display set in the viewer
      const dynamicDisplaySet = actions.getDynamic4DDisplaySet();
      const displaySetCache = displaySetService.getDisplaySetCache();
      const cachedDisplaySetKeys = [...displaySetCache.keys()]; // Fix: Spread to get the array
      const {
        displaySetInstanceUID
      } = dynamicDisplaySet;

      // Check to see if dynamic display set is already in cache
      if (!cachedDisplaySetKeys.includes(displaySetInstanceUID)) {
        displaySetCache.set(displaySetInstanceUID, dynamicDisplaySet);
      }

      // Get all viewports and their corresponding indices
      const {
        viewports
      } = viewportGridService.getState();

      // Get the computed 4D display set
      const computed4DDisplaySet = actions.getComputedDisplaySets()[0];
      const viewportsToUpdate = [];
      for (const [key, value] of viewports) {
        const viewport = value;
        const viewportOptions = viewport.viewportOptions;
        const {
          displaySetInstanceUIDs
        } = viewport;
        const displaySetInstanceUIDIndex = displaySetInstanceUIDs.indexOf(computed4DDisplaySet.displaySetInstanceUID);
        if (displaySetInstanceUIDIndex !== -1) {
          const newViewport = {
            viewportId: viewport.viewportId,
            // merge the other displaySetInstanceUIDs with the new one
            displaySetInstanceUIDs: [...displaySetInstanceUIDs.slice(0, displaySetInstanceUIDIndex), displaySetInstanceUID, ...displaySetInstanceUIDs.slice(displaySetInstanceUIDIndex + 1)],
            viewportOptions: {
              initialImageOptions: viewportOptions.initialImageOptions,
              viewportType: 'volume',
              orientation: viewportOptions.orientation,
              background: viewportOptions.background
            }
          };
          viewportsToUpdate.push(newViewport);
        }
      }
      commandsManager.run('setDisplaySetsForViewports', {
        viewportsToUpdate
      });
    },
    createNewLabelMapForDynamicVolume: async ({
      label
    }) => {
      const {
        viewports,
        activeViewportId
      } = viewportGridService.getState();

      // get the dynamic 4D display set
      const dynamic4DDisplaySet = actions.getDynamic4DDisplaySet();
      const dynamic4DDisplaySetInstanceUID = dynamic4DDisplaySet.displaySetInstanceUID;

      // check if the dynamic 4D display set is in the display, if not we might have
      // the computed volumes and we should choose them for the segmentation
      // creation

      let referenceDisplaySet;
      const activeViewport = viewports.get(activeViewportId);
      const activeDisplaySetInstanceUIDs = activeViewport.displaySetInstanceUIDs;
      const dynamicIsInActiveViewport = activeDisplaySetInstanceUIDs.includes(dynamic4DDisplaySetInstanceUID);
      if (dynamicIsInActiveViewport) {
        referenceDisplaySet = dynamic4DDisplaySet;
      }
      if (!referenceDisplaySet) {
        // try to see if there is any derived displaySet in the active viewport
        // which is referencing the dynamic 4D display set

        // Todo: this is wrong but I don't have time to fix it now
        const cachedDisplaySets = displaySetService.getDisplaySetCache();
        for (const [key, displaySet] of cachedDisplaySets) {
          if (displaySet.referenceDisplaySetUID === dynamic4DDisplaySetInstanceUID) {
            referenceDisplaySet = displaySet;
            break;
          }
        }
      }
      if (!referenceDisplaySet) {
        throw new Error('No reference display set found based on the dynamic data');
      }
      const displaySet = displaySetService.getDisplaySetByUID(referenceDisplaySet.displaySetInstanceUID);
      const segmentationId = await segmentationService.createLabelmapForDisplaySet(displaySet, {
        label
      });
      const firstViewport = viewports.values().next().value;
      await segmentationService.addSegmentationRepresentation(firstViewport.viewportId, {
        segmentationId
      });
      return segmentationId;
    }
  };
  const definitions = {
    updateSegmentationsChartDisplaySet: {
      commandFn: actions.updateSegmentationsChartDisplaySet,
      storeContexts: [],
      options: {}
    },
    exportTimeReportCSV: {
      commandFn: actions.exportTimeReportCSV,
      storeContexts: [],
      options: {}
    },
    swapDynamicWithComputedDisplaySet: {
      commandFn: actions.swapDynamicWithComputedDisplaySet,
      storeContexts: [],
      options: {}
    },
    createNewLabelMapForDynamicVolume: {
      commandFn: actions.createNewLabelMapForDynamicVolume,
      storeContexts: [],
      options: {}
    },
    swapComputedWithDynamicDisplaySet: {
      commandFn: actions.swapComputedWithDynamicDisplaySet,
      storeContexts: [],
      options: {}
    }
  };
  return {
    actions,
    definitions,
    defaultContext: 'DYNAMIC-VOLUME:CORNERSTONE'
  };
};
/* harmony default export */ const src_commandsModule = (commandsModule);
// EXTERNAL MODULE: ../../../node_modules/react/index.js
var react = __webpack_require__(86326);
// EXTERNAL MODULE: ../../ui-next/src/index.ts + 3075 modules
var ui_next_src = __webpack_require__(12517);
;// ../../../extensions/cornerstone-dynamic-volume/src/panels/DynamicVolumeControls.tsx




// Helper function to safely convert any value to uppercase string
const toUpperCaseString = value => {
  if (value === null || value === undefined) {
    return '';
  }
  return String(value).toUpperCase();
};
const Header = ({
  title,
  tooltip
}) => /*#__PURE__*/react.createElement("div", {
  className: "flex items-center space-x-1"
}, /*#__PURE__*/react.createElement(ui_next_src/* Tooltip */.m_M, null, /*#__PURE__*/react.createElement(ui_next_src/* TooltipTrigger */.k$k, {
  asChild: true
}, /*#__PURE__*/react.createElement("span", null, /*#__PURE__*/react.createElement(ui_next_src/* Icons */.FI1.ByName, {
  name: "info-link",
  className: "text-primary h-3 w-3"
}))), /*#__PURE__*/react.createElement(ui_next_src/* TooltipContent */.ZIw, {
  sideOffset: 4,
  className: "max-w-xs"
}, /*#__PURE__*/react.createElement("div", null, tooltip))), /*#__PURE__*/react.createElement("span", {
  className: "text-muted-foreground text-xs uppercase tracking-wide"
}, title));
const DynamicVolumeControls = ({
  isPlaying,
  onPlayPauseChange,
  // fps
  fps,
  onFpsChange,
  minFps,
  maxFps,
  // Frames
  currentDimensionGroupNumber,
  onDimensionGroupChange,
  numDimensionGroups,
  onGenerate,
  onDoubleRangeChange,
  rangeValues,
  onDynamicClick
}) => {
  const [computedView, setComputedView] = (0,react.useState)(false);
  const [computeViewMode, setComputeViewMode] = (0,react.useState)(dist_esm.Enums.DynamicOperatorType.SUM);

  // Wrapper for onGenerate to handle potential errors
  const handleGenerate = () => {
    try {
      if (typeof onGenerate === 'function') {
        onGenerate(computeViewMode);
      } else {
        console.error('onGenerate is not a function', onGenerate);
      }
    } catch (error) {
      console.error('Error in onGenerate:', error);
    }
  };
  return /*#__PURE__*/react.createElement("div", {
    className: "flex select-none flex-col"
  }, /*#__PURE__*/react.createElement(ui_next_src/* PanelSection */.aUM, {
    defaultOpen: true
  }, /*#__PURE__*/react.createElement(ui_next_src/* PanelSection */.aUM.Header, null, "Controls"), /*#__PURE__*/react.createElement(ui_next_src/* PanelSection */.aUM.Content, {
    className: "bg-muted space-y-4 px-5 pt-2 pb-4"
  }, /*#__PURE__*/react.createElement("div", {
    className: "mb-4"
  }, /*#__PURE__*/react.createElement(Header, {
    title: "View",
    tooltip: 'Select the view mode, 4D to view the dynamic volume or Computed to view the computed volume'
  }), /*#__PURE__*/react.createElement(ui_next_src/* Tabs */.tUM, {
    value: computedView ? 'computed' : '4d',
    onValueChange: value => {
      const isComputed = value === 'computed';
      setComputedView(isComputed);
      if (!isComputed && typeof onDynamicClick === 'function') {
        onDynamicClick();
      }
    },
    className: "my-2 w-full"
  }, /*#__PURE__*/react.createElement(ui_next_src/* TabsList */.j7C, {
    className: "w-full"
  }, /*#__PURE__*/react.createElement(ui_next_src/* TabsTrigger */.Xib, {
    value: "4d",
    className: "w-1/2"
  }, "4D"), /*#__PURE__*/react.createElement(ui_next_src/* TabsTrigger */.Xib, {
    value: "computed",
    className: "w-1/2"
  }, "Computed")))), /*#__PURE__*/react.createElement("div", null, /*#__PURE__*/react.createElement(DimensionGroupControls, {
    onPlayPauseChange: onPlayPauseChange,
    isPlaying: isPlaying,
    computedView: computedView
    // fps
    ,
    fps: fps,
    onFpsChange: onFpsChange,
    minFps: minFps,
    maxFps: maxFps
    //
    ,
    numDimensionGroups: numDimensionGroups,
    onDimensionGroupChange: onDimensionGroupChange,
    currentDimensionGroupNumber: currentDimensionGroupNumber
  })), /*#__PURE__*/react.createElement("div", {
    className: `mt-3 flex flex-col ${computedView ? '' : 'ohif-disabled'}`
  }, /*#__PURE__*/react.createElement(Header, {
    title: "Computed Operation",
    tooltip: /*#__PURE__*/react.createElement("div", null, "Operation Buttons (SUM, AVERAGE, SUBTRACT): Select the mathematical operation to be applied to the data set.", /*#__PURE__*/react.createElement("br", null), " Range Slider: Choose the numeric range of dimension groups within which the operation will be performed.", /*#__PURE__*/react.createElement("br", null), "Generate Button: Execute the chosen operation on the specified range of data.")
  }), /*#__PURE__*/react.createElement(ui_next_src/* Tabs */.tUM, {
    value: String(computeViewMode),
    onValueChange: value => {
      setComputeViewMode(value);
    },
    className: "mt-2 w-full"
  }, /*#__PURE__*/react.createElement(ui_next_src/* TabsList */.j7C, {
    className: "w-full gap-1"
  }, ' ', /*#__PURE__*/react.createElement(ui_next_src/* TabsTrigger */.Xib, {
    value: String(dist_esm.Enums.DynamicOperatorType.SUM),
    className: "w-1/3"
  }, toUpperCaseString(dist_esm.Enums.DynamicOperatorType.SUM)), /*#__PURE__*/react.createElement(ui_next_src/* TabsTrigger */.Xib, {
    value: String(dist_esm.Enums.DynamicOperatorType.AVERAGE),
    className: "w-1/3"
  }, toUpperCaseString(dist_esm.Enums.DynamicOperatorType.AVERAGE)), /*#__PURE__*/react.createElement(ui_next_src/* TabsTrigger */.Xib, {
    value: String(dist_esm.Enums.DynamicOperatorType.SUBTRACT),
    className: "w-1/3"
  }, toUpperCaseString(dist_esm.Enums.DynamicOperatorType.SUBTRACT)))), /*#__PURE__*/react.createElement("div", {
    className: "mt-2 w-full"
  }, /*#__PURE__*/react.createElement(ui_next_src/* Numeric */.ewR.Container, {
    mode: "doubleRange",
    min: 1,
    max: numDimensionGroups || 1,
    values: rangeValues || [1, numDimensionGroups || 1],
    onChange: onDoubleRangeChange || (() => {})
  }, /*#__PURE__*/react.createElement(ui_next_src/* Numeric */.ewR.DoubleRange, {
    showNumberInputs: true
  }))), /*#__PURE__*/react.createElement(ui_next_src/* Button */.$nd, {
    variant: "default",
    size: "sm",
    className: "mt-2 h-[26px] w-[115px] self-start p-0",
    onClick: handleGenerate
  }, "Generate")))));
};
/* harmony default export */ const panels_DynamicVolumeControls = (DynamicVolumeControls);
function DimensionGroupControls({
  isPlaying,
  onPlayPauseChange,
  fps,
  minFps,
  maxFps,
  onFpsChange,
  numDimensionGroups,
  onDimensionGroupChange,
  currentDimensionGroupNumber,
  computedView
}) {
  const getPlayPauseIconName = () => isPlaying ? 'icon-pause' : 'icon-play';
  return /*#__PURE__*/react.createElement("div", {
    className: computedView ? 'ohif-disabled' : ''
  }, /*#__PURE__*/react.createElement(Header, {
    title: "4D Controls",
    tooltip: /*#__PURE__*/react.createElement("div", null, "Play/Pause Button: Begin or pause the animation of the 4D visualization. ", /*#__PURE__*/react.createElement("br", null), "Dimension Group Selector: Navigate through individual dimension groups of the 4D data.", ' ', /*#__PURE__*/react.createElement("br", null), "FPS (Frames Per Second) Selector: Adjust the playback speed of the animation.")
  }), /*#__PURE__*/react.createElement("div", {
    className: "mt-3 flex justify-between"
  }, /*#__PURE__*/react.createElement(ui_next_src/* Button */.$nd, {
    id: "play-pause-button",
    variant: "secondary",
    size: "default",
    className: "w-[58px]",
    onClick: () => {
      if (typeof onPlayPauseChange === 'function') {
        onPlayPauseChange(!isPlaying);
      }
    }
  }, /*#__PURE__*/react.createElement(ui_next_src/* Icons */.FI1.ByName, {
    name: getPlayPauseIconName(),
    className: "text-foreground h-[24px] w-[24px]"
  })), /*#__PURE__*/react.createElement(ui_next_src/* Numeric */.ewR.Container, {
    mode: "stepper",
    value: currentDimensionGroupNumber || 1,
    onChange: onDimensionGroupChange || (() => {}),
    min: 1,
    max: numDimensionGroups || 1,
    step: 1
  }, /*#__PURE__*/react.createElement("div", {
    className: "flex flex-col items-center"
  }, /*#__PURE__*/react.createElement(ui_next_src/* Numeric */.ewR.NumberStepper, {
    className: "h-[28px] w-[58px]",
    direction: "horizontal"
  }), /*#__PURE__*/react.createElement(ui_next_src/* Numeric */.ewR.Label, {
    className: "text-muted-foreground mt-1 text-sm"
  }, "Frame"))), /*#__PURE__*/react.createElement(ui_next_src/* Numeric */.ewR.Container, {
    mode: "stepper",
    value: fps || 1,
    onChange: onFpsChange || (() => {}),
    min: minFps || 1,
    max: maxFps || 30,
    step: 1
  }, /*#__PURE__*/react.createElement("div", {
    className: "flex flex-col items-center"
  }, /*#__PURE__*/react.createElement(ui_next_src/* Numeric */.ewR.NumberStepper, {
    className: "h-[28px] w-[58px]",
    direction: "horizontal"
  }), /*#__PURE__*/react.createElement(ui_next_src/* Numeric */.ewR.Label, {
    className: "text-muted-foreground mt-1 text-sm"
  }, "FPS")))));
}
;// ../../../extensions/cornerstone-dynamic-volume/src/panels/PanelGenerateImage.tsx






const SOPClassHandlerId = '@ohif/extension-default.sopClassHandlerModule.stack';
function PanelGenerateImage({
  servicesManager,
  commandsManager
}) {
  const {
    cornerstoneViewportService,
    viewportGridService,
    displaySetService
  } = servicesManager.services;
  const [{
    isCineEnabled
  }, cineService] = (0,ui_next_src/* useCine */.tqw)();
  const [{
    activeViewportId
  }] = (0,ui_next_src/* useViewportGrid */.ihW)();

  //
  const [dimensionGroupRange, setDimensionGroupRange] = (0,react.useState)([1, 1]);
  const [computedDisplaySet, setComputedDisplaySet] = (0,react.useState)(null);
  const [dynamicVolume, setDynamicVolume] = (0,react.useState)(null);
  const [frameRate, setFrameRate] = (0,react.useState)(20);
  const [isPlaying, setIsPlaying] = (0,react.useState)(isCineEnabled);
  const [dimensionGroupNumberRendered, setDimensionGroupNumberRendered] = (0,react.useState)(null);
  const [displayingComputed, setDisplayingComputed] = (0,react.useState)(false);

  //
  const uuidComputedVolume = (0,react.useRef)(dist_esm.utilities.uuidv4());
  const uuidDynamicVolume = (0,react.useRef)(null);
  const computedVolumeId = `cornerstoneStreamingImageVolume:${uuidComputedVolume.current}`;
  (0,react.useEffect)(() => {
    const viewportDataChangedEvt = cornerstoneViewportService.EVENTS.VIEWPORT_DATA_CHANGED;
    const cineStateChangedEvt = servicesManager.services.cineService.EVENTS.CINE_STATE_CHANGED;
    const viewportDataChangedCallback = evtDetails => {
      evtDetails.viewportData.data.forEach(volumeData => {
        if (volumeData.volume?.isDynamicVolume()) {
          setDynamicVolume(volumeData.volume);
          uuidDynamicVolume.current = volumeData.displaySetInstanceUID;
          const newRange = [1, volumeData.volume.numDimensionGroups];
          setDimensionGroupRange(newRange);
        }
      });
    };
    const cineStateChangedCallback = evt => {
      setIsPlaying(evt.isPlaying);
    };
    const {
      unsubscribe: unsubscribeViewportData
    } = cornerstoneViewportService.subscribe(viewportDataChangedEvt, viewportDataChangedCallback);
    const {
      unsubscribe: unsubscribeCineState
    } = servicesManager.services.cineService.subscribe(cineStateChangedEvt, cineStateChangedCallback);
    return () => {
      unsubscribeViewportData();
      unsubscribeCineState();
    };
  }, [cornerstoneViewportService, cineService, servicesManager.services.cineService]);
  (0,react.useEffect)(() => {
    const evt = dist_esm.Enums.Events.DYNAMIC_VOLUME_DIMENSION_GROUP_CHANGED;
    const callback = evt => {
      setDimensionGroupNumberRendered(evt.detail.dimensionGroupNumber);
    };
    dist_esm.eventTarget.addEventListener(evt, callback);
    return () => {
      dist_esm.eventTarget.removeEventListener(evt, callback);
    };
  }, []);
  (0,react.useEffect)(() => {
    const displaySetUIDs = viewportGridService.getDisplaySetsUIDsForViewport(activeViewportId);
    if (!displaySetUIDs?.length) {
      return;
    }
    const displaySets = displaySetUIDs.map(displaySetService.getDisplaySetByUID);
    const dynamicVolumeDisplaySet = displaySets.find(displaySet => displaySet.isDynamicVolume);
    if (!dynamicVolumeDisplaySet) {
      return;
    }
    const dynamicVolume = dist_esm.cache.getVolumes().find(volume => volume.volumeId.includes(dynamicVolumeDisplaySet.displaySetInstanceUID));
    if (!dynamicVolume) {
      return;
    }
    setDynamicVolume(dynamicVolume);
    uuidDynamicVolume.current = dynamicVolumeDisplaySet.displaySetInstanceUID;
    setDimensionGroupRange([1, dynamicVolume.numDimensionGroups]);
  }, [activeViewportId, viewportGridService, displaySetService, cornerstoneViewportService, cineService]);
  function renderGeneratedImage(displaySet) {
    commandsManager.runCommand('swapDynamicWithComputedDisplaySet', {
      displaySet
    });
    setDisplayingComputed(true);
  }
  function renderDynamicImage(displaySet) {
    commandsManager.runCommand('swapComputedWithDynamicDisplaySet');
  }

  // Get computed volume from cache, calculate the data across the time frames,
  // set the scalar data to the computedVolume, and create displaySet
  async function onGenerateImage(operationName) {
    const dynamicVolumeId = dynamicVolume.volumeId;
    if (!dynamicVolumeId) {
      return;
    }
    let computedVolume = dist_esm.cache.getVolume(computedVolumeId);
    if (!computedVolume) {
      computedVolume = await dist_esm.volumeLoader.createAndCacheDerivedVolume(dynamicVolumeId, {
        volumeId: computedVolumeId
      });
    }
    const [start, end] = dimensionGroupRange;
    // from start to end, with steps of 1
    const frameNumbers = Array.from({
      length: end - start + 1
    }, (_, i) => start + i);
    const options = {
      dimensionGroupNumbers: operationName === 'SUBTRACT' ? [start, end] : frameNumbers,
      targetVolume: computedVolume
    };
    esm.utilities.dynamicVolume.updateVolumeFromTimeData(dynamicVolume, operationName, options);

    // If computed display set does not exist, create an object to be used as
    // the displaySet. If it does exist, update the image data and vtkTexture
    if (!computedDisplaySet) {
      const displaySet = {
        volumeLoaderSchema: computedVolume.volumeId.split(':')[0],
        displaySetInstanceUID: uuidComputedVolume.current,
        SOPClassHandlerId: SOPClassHandlerId,
        Modality: dynamicVolume.metadata.Modality,
        isMultiFrame: false,
        numImageFrames: 1,
        uid: uuidComputedVolume.current,
        referenceDisplaySetUID: dynamicVolume.volumeId.split(':')[1],
        madeInClient: true,
        FrameOfReferenceUID: dynamicVolume.metadata.FrameOfReferenceUID,
        isDerived: true,
        imageIds: computedVolume.imageIds
      };
      setComputedDisplaySet(displaySet);
      renderGeneratedImage(displaySet);
    } else {
      commandsManager.runCommand('updateVolumeData', {
        volume: computedVolume
      });
      cornerstoneViewportService.getRenderingEngine().render();
      renderGeneratedImage(computedDisplaySet);
    }
  }
  const onPlayPauseChange = isPlaying => {
    isPlaying ? handlePlay() : handleStop();
  };
  const handlePlay = () => {
    setIsPlaying(true);
    const viewportInfo = cornerstoneViewportService.getViewportInfo(activeViewportId);
    if (!viewportInfo) {
      return;
    }
    const {
      element
    } = viewportInfo;
    cineService.playClip(element, {
      framesPerSecond: frameRate,
      viewportId: activeViewportId
    });
  };
  const handleStop = () => {
    setIsPlaying(false);
    const {
      element
    } = cornerstoneViewportService.getViewportInfo(activeViewportId);
    cineService.stopClip(element);
  };
  const handleSetFrameRate = newFrameRate => {
    setFrameRate(newFrameRate);
    handleStop();
    handlePlay();
  };
  return /*#__PURE__*/react.createElement(panels_DynamicVolumeControls, {
    fps: frameRate,
    isPlaying: isPlaying,
    onPlayPauseChange: onPlayPauseChange,
    minFps: 1,
    maxFps: 50,
    onFpsChange: handleSetFrameRate,
    currentDimensionGroupNumber: dimensionGroupNumberRendered,
    numDimensionGroups: dynamicVolume?.numDimensionGroups || 1,
    onDimensionGroupChange: dimensionGroupNumber => {
      dynamicVolume.dimensionGroupNumber = dimensionGroupNumber;
    },
    onGenerate: onGenerateImage,
    onDynamicClick: displayingComputed ? () => renderDynamicImage(computedDisplaySet) : null,
    onDoubleRangeChange: setDimensionGroupRange,
    rangeValues: dimensionGroupRange
  });
}
;// ../../../extensions/cornerstone-dynamic-volume/src/panels/DynamicDataPanel.tsx


function DynamicDataPanel({
  servicesManager,
  commandsManager,
  tab
}) {
  return /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("div", {
    className: "flex flex-col text-white",
    "data-cy": 'dynamic-volume-panel'
  }, /*#__PURE__*/react.createElement(PanelGenerateImage, {
    commandsManager: commandsManager,
    servicesManager: servicesManager
  })));
}
/* harmony default export */ const panels_DynamicDataPanel = (DynamicDataPanel);
;// ../../../extensions/cornerstone-dynamic-volume/src/panels/WorkflowPanel.tsx
/* unused harmony import specifier */ var React;

function WorkflowPanel({
  servicesManager
}) {
  const ProgressDropdownWithService = servicesManager.services.customizationService.getCustomization('progressDropdownWithServiceComponent');
  return /*#__PURE__*/React.createElement("div", {
    "data-cy": 'workflow-panel',
    className: "bg-secondary-dark mb-1 px-3 py-4"
  }, /*#__PURE__*/React.createElement("div", {
    className: "mb-1"
  }, "Workflow"), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(ProgressDropdownWithService, {
    servicesManager: servicesManager
  })));
}
/* harmony default export */ const panels_WorkflowPanel = ((/* unused pure expression or super */ null && (WorkflowPanel)));
;// ../../../extensions/cornerstone-dynamic-volume/src/panels/index.js




// EXTERNAL MODULE: ../../../extensions/default/src/index.ts + 140 modules
var default_src = __webpack_require__(62851);
// EXTERNAL MODULE: ../../../extensions/cornerstone/src/index.tsx + 193 modules
var cornerstone_src = __webpack_require__(63081);
;// ../../../extensions/cornerstone-dynamic-volume/src/panels/DynamicExport.tsx



function DynamicExport({
  commandsManager,
  servicesManager
}) {
  const segmentations = (0,cornerstone_src/* useSegmentations */.jo)({
    servicesManager
  });
  if (!segmentations?.length) {
    return null;
  }
  return /*#__PURE__*/react.createElement("div", {
    className: "flex gap-2"
  }, /*#__PURE__*/react.createElement("div", {
    className: "flex h-8 w-full items-center rounded pr-0.5"
  }, /*#__PURE__*/react.createElement(ui_next_src/* Button */.$nd, {
    size: "sm",
    variant: "ghost",
    className: "pl-1.5",
    onClick: () => {
      commandsManager.runCommand('exportTimeReportCSV', {
        segmentations,
        options: {
          filename: 'TimeData.csv'
        }
      });
    }
  }, /*#__PURE__*/react.createElement(ui_next_src/* Icons */.FI1.Export, null), /*#__PURE__*/react.createElement("span", {
    className: "pl-1"
  }, "Time Data"))), /*#__PURE__*/react.createElement("div", {
    className: "flex h-8 w-full items-center rounded pr-0.5"
  }, /*#__PURE__*/react.createElement(ui_next_src/* Button */.$nd, {
    size: "sm",
    variant: "ghost",
    className: "pl-1.5",
    onClick: () => {
      commandsManager.runCommand('exportTimeReportCSV', {
        segmentations,
        summaryStats: true,
        options: {
          filename: 'ROIStats.csv'
        }
      });
    }
  }, /*#__PURE__*/react.createElement(ui_next_src/* Icons */.FI1.Export, null), /*#__PURE__*/react.createElement("span", {
    className: "pl-1"
  }, "ROI Stats"))));
}
/* harmony default export */ const panels_DynamicExport = (DynamicExport);
;// ../../../extensions/cornerstone-dynamic-volume/src/getPanelModule.tsx





function getPanelModule({
  commandsManager,
  extensionManager,
  servicesManager,
  configuration
}) {
  const {
    toolbarService
  } = servicesManager.services;
  const wrappedDynamicDataPanel = () => {
    return /*#__PURE__*/react.createElement(panels_DynamicDataPanel, {
      commandsManager: commandsManager,
      servicesManager: servicesManager,
      extensionManager: extensionManager
    });
  };
  const wrappedDynamicSegmentation = () => {
    return /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement(default_src/* Toolbox */.OO, {
      buttonSectionId: toolbarService.sections.dynamicToolbox,
      title: "Buttons:Threshold Tools"
    }), /*#__PURE__*/react.createElement(cornerstone_src/* PanelSegmentation */.rE, {
      servicesManager: servicesManager,
      commandsManager: commandsManager,
      extensionManager: extensionManager,
      configuration: configuration
    }, /*#__PURE__*/react.createElement(panels_DynamicExport, {
      servicesManager: servicesManager,
      commandsManager: commandsManager
    })));
  };
  return [{
    name: 'dynamic-volume',
    iconName: 'tab-4d',
    iconLabel: '4D Workflow',
    label: '4D Workflow',
    component: wrappedDynamicDataPanel
  }, {
    name: 'dynamic-segmentation',
    iconName: 'tab-segmentation',
    iconLabel: 'Segmentation',
    label: 'Segmentation',
    component: wrappedDynamicSegmentation
  }];
}
/* harmony default export */ const src_getPanelModule = (getPanelModule);
;// ../../../extensions/cornerstone-dynamic-volume/src/getHangingProtocolModule.ts
const DEFAULT_COLORMAP = '2hot';
const toolGroupIds = {
  pt: 'dynamic4D-pt',
  fusion: 'dynamic4D-fusion',
  ct: 'dynamic4D-ct'
};
function getPTOptions({
  colormap,
  voiInverted
} = {}) {
  return {
    blendMode: 'MIP',
    colormap,
    voi: {
      windowWidth: 5,
      windowCenter: 2.5
    },
    voiInverted
  };
}
function getPTViewports() {
  const ptOptionsParams = {
    colormap: {
      name: DEFAULT_COLORMAP,
      opacity: [{
        value: 0,
        opacity: 0
      }, {
        value: 0.1,
        opacity: 1
      }, {
        value: 1,
        opacity: 1
      }]
    },
    voiInverted: false
  };
  return [{
    viewportOptions: {
      viewportId: 'ptAxial',
      viewportType: 'volume',
      orientation: 'axial',
      toolGroupId: toolGroupIds.pt,
      initialImageOptions: {
        preset: 'middle' // 'first', 'last', 'middle'
      },
      syncGroups: [{
        type: 'cameraPosition',
        id: 'axialSync',
        source: true,
        target: true
      }, {
        type: 'voi',
        id: 'ptWLSync',
        source: true,
        target: true
      }]
    },
    displaySets: [{
      id: 'ptDisplaySet',
      options: {
        ...getPTOptions(ptOptionsParams)
      }
    }]
  }, {
    viewportOptions: {
      viewportId: 'ptSagittal',
      viewportType: 'volume',
      orientation: 'sagittal',
      toolGroupId: toolGroupIds.pt,
      initialImageOptions: {
        preset: 'middle' // 'first', 'last', 'middle'
      },
      syncGroups: [{
        type: 'cameraPosition',
        id: 'sagittalSync',
        source: true,
        target: true
      }, {
        type: 'voi',
        id: 'ptWLSync',
        source: true,
        target: true
      }]
    },
    displaySets: [{
      id: 'ptDisplaySet',
      options: {
        ...getPTOptions(ptOptionsParams)
      }
    }]
  }, {
    viewportOptions: {
      viewportId: 'ptCoronal',
      viewportType: 'volume',
      orientation: 'coronal',
      toolGroupId: toolGroupIds.pt,
      initialImageOptions: {
        preset: 'middle' // 'first', 'last', 'middle'
      },
      syncGroups: [{
        type: 'cameraPosition',
        id: 'coronalSync',
        source: true,
        target: true
      }, {
        type: 'voi',
        id: 'ptWLSync',
        source: true,
        target: true
      }]
    },
    displaySets: [{
      id: 'ptDisplaySet',
      options: {
        ...getPTOptions(ptOptionsParams)
      }
    }]
  }];
}
function getFusionViewports() {
  const ptOptionsParams = {
    colormap: {
      name: DEFAULT_COLORMAP,
      opacity: [{
        value: 0,
        opacity: 0
      }, {
        value: 0.1,
        opacity: 0.8
      }, {
        value: 1,
        opacity: 0.8
      }]
    }
  };
  return [{
    viewportOptions: {
      viewportId: 'fusionAxial',
      viewportType: 'volume',
      orientation: 'axial',
      toolGroupId: toolGroupIds.fusion,
      initialImageOptions: {
        preset: 'middle' // 'first', 'last', 'middle'
      },
      syncGroups: [{
        type: 'cameraPosition',
        id: 'axialSync',
        source: true,
        target: true
      }, {
        type: 'voi',
        id: 'ctWLSync',
        source: false,
        target: true
      }, {
        type: 'voi',
        id: 'fusionWLSync',
        source: true,
        target: true
      }, {
        type: 'voi',
        id: 'ptFusionWLSync',
        source: false,
        target: true,
        options: {
          syncInvertState: false
        }
      }, {
        type: 'hydrateseg',
        id: 'sameFORId',
        source: true,
        target: true,
        options: {
          matchingRules: ['sameFOR']
        }
      }]
    },
    displaySets: [{
      id: 'ctDisplaySet'
    }, {
      options: {
        ...getPTOptions(ptOptionsParams)
      },
      id: 'ptDisplaySet'
    }]
  }, {
    viewportOptions: {
      viewportId: 'fusionSagittal',
      viewportType: 'volume',
      orientation: 'sagittal',
      toolGroupId: toolGroupIds.fusion,
      initialImageOptions: {
        preset: 'middle' // 'first', 'last', 'middle'
      },
      syncGroups: [{
        type: 'cameraPosition',
        id: 'sagittalSync',
        source: true,
        target: true
      }, {
        type: 'voi',
        id: 'ctWLSync',
        source: false,
        target: true
      }, {
        type: 'voi',
        id: 'fusionWLSync',
        source: true,
        target: true
      }, {
        type: 'voi',
        id: 'ptFusionWLSync',
        source: false,
        target: true,
        options: {
          syncInvertState: false
        }
      }, {
        type: 'hydrateseg',
        id: 'sameFORId',
        source: true,
        target: true,
        options: {
          matchingRules: ['sameFOR']
        }
      }]
    },
    displaySets: [{
      id: 'ctDisplaySet'
    }, {
      options: {
        ...getPTOptions(ptOptionsParams)
      },
      id: 'ptDisplaySet'
    }]
  }, {
    viewportOptions: {
      viewportId: 'fusionCoronal',
      viewportType: 'volume',
      orientation: 'coronal',
      toolGroupId: toolGroupIds.fusion,
      initialImageOptions: {
        preset: 'middle' // 'first', 'last', 'middle'
      },
      syncGroups: [{
        type: 'cameraPosition',
        id: 'coronalSync',
        source: true,
        target: true
      }, {
        type: 'voi',
        id: 'ctWLSync',
        source: false,
        target: true
      }, {
        type: 'voi',
        id: 'fusionWLSync',
        source: true,
        target: true
      }, {
        type: 'voi',
        id: 'ptFusionWLSync',
        source: false,
        target: true,
        options: {
          syncInvertState: false
        }
      }, {
        type: 'hydrateseg',
        id: 'sameFORId',
        source: true,
        target: true,
        options: {
          matchingRules: ['sameFOR']
        }
      }]
    },
    displaySets: [{
      id: 'ctDisplaySet'
    }, {
      options: {
        ...getPTOptions(ptOptionsParams)
      },
      id: 'ptDisplaySet'
    }]
  }];
}
function getSeriesChartViewport() {
  return {
    viewportOptions: {
      viewportId: 'seriesChart'
    },
    displaySets: [{
      id: 'chartDisplaySet',
      options: {
        // This dataset does not require the download of any instance since it is pre-computed locally,
        // but interleaveTopToBottom.ts was not loading any series because it consider that all viewports
        // are a Cornerstone viewport which is not true in this case and it waits for all viewports to
        // have called interleaveTopToBottom(...).
        skipLoading: true
      }
    }]
  };
}
function getCTViewports() {
  return [{
    viewportOptions: {
      viewportId: 'ctAxial',
      viewportType: 'volume',
      orientation: 'axial',
      toolGroupId: toolGroupIds.ct,
      initialImageOptions: {
        preset: 'middle' // 'first', 'last', 'middle'
      },
      syncGroups: [{
        type: 'cameraPosition',
        id: 'axialSync',
        source: true,
        target: true
      }, {
        type: 'voi',
        id: 'ctWLSync',
        source: true,
        target: true
      }]
    },
    displaySets: [{
      id: 'ctDisplaySet'
    }]
  }, {
    viewportOptions: {
      viewportId: 'ctSagittal',
      viewportType: 'volume',
      orientation: 'sagittal',
      toolGroupId: toolGroupIds.ct,
      initialImageOptions: {
        preset: 'middle'
      },
      syncGroups: [{
        type: 'cameraPosition',
        id: 'sagittalSync',
        source: true,
        target: true
      }, {
        type: 'voi',
        id: 'ctWLSync',
        source: true,
        target: true
      }]
    },
    displaySets: [{
      id: 'ctDisplaySet'
    }]
  }, {
    viewportOptions: {
      viewportId: 'ctCoronal',
      viewportType: 'volume',
      orientation: 'coronal',
      toolGroupId: toolGroupIds.ct,
      initialImageOptions: {
        preset: 'middle'
      },
      syncGroups: [{
        type: 'cameraPosition',
        id: 'coronalSync',
        source: true,
        target: true
      }, {
        type: 'voi',
        id: 'ctWLSync',
        source: true,
        target: true
      }]
    },
    displaySets: [{
      id: 'ctDisplaySet'
    }]
  }];
}
const defaultProtocol = {
  id: 'default4D',
  locked: true,
  // Don't store this hanging protocol as it applies to the currently active
  // display set by default
  // cacheId: null,
  hasUpdatedPriorsInformation: false,
  name: 'Default',
  createdDate: '2023-01-01T00:00:00.000Z',
  modifiedDate: '2023-01-01T00:00:00.000Z',
  availableTo: {},
  editableBy: {},
  imageLoadStrategy: 'default',
  // "default" , "interleaveTopToBottom",  "interleaveCenter"
  protocolMatchingRules: [{
    attribute: 'ModalitiesInStudy',
    constraint: {
      contains: ['CT', 'PT']
    }
  }],
  // -1 would be used to indicate active only, whereas other values are
  // the number of required priors referenced - so 0 means active with
  // 0 or more priors.
  numberOfPriorsReferenced: -1,
  displaySetSelectors: {
    defaultDisplaySetId: {
      // Unused currently
      imageMatchingRules: [],
      // Matches displaysets, NOT series
      seriesMatchingRules: [
      // Try to match series with images by default, to prevent weird display
      // on SEG/SR containing studies
      {
        attribute: 'numImageFrames',
        constraint: {
          greaterThan: {
            value: 0
          }
        }
      }]
      // Can be used to select matching studies
      // studyMatchingRules: [],
    },
    ctDisplaySet: {
      // Unused currently
      imageMatchingRules: [],
      // Matches displaysets, NOT series
      seriesMatchingRules: [{
        attribute: 'Modality',
        constraint: {
          equals: {
            value: 'CT'
          }
        },
        required: true
      }, {
        attribute: 'isReconstructable',
        constraint: {
          equals: {
            value: true
          }
        },
        required: true
      }]
      // Can be used to select matching studies
      // studyMatchingRules: [],
    },
    ptDisplaySet: {
      // Unused currently
      imageMatchingRules: [],
      // Matches displaysets, NOT series
      seriesMatchingRules: [{
        attribute: 'Modality',
        constraint: {
          equals: 'PT'
        },
        required: true
      }, {
        attribute: 'isReconstructable',
        constraint: {
          equals: {
            value: true
          }
        },
        required: true
      }, {
        attribute: 'SeriesDescription',
        constraint: {
          contains: 'Corrected'
        }
      }, {
        weight: 2,
        attribute: 'SeriesDescription',
        constraint: {
          doesNotContain: {
            value: 'Uncorrected'
          }
        }
      }

      // Should we check if CorrectedImage contains ATTN?
      // (0028,0051) (CorrectedImage): NORM\DTIM\ATTN\SCAT\RADL\DECY
      ]
      // Can be used to select matching studies
      // studyMatchingRules: [],
    },
    chartDisplaySet: {
      // Unused currently
      imageMatchingRules: [],
      // Matches displaysets, NOT series
      seriesMatchingRules: [{
        attribute: 'Modality',
        constraint: {
          equals: {
            value: 'CHT'
          }
        },
        required: true
      }]
    }
  },
  stages: [{
    id: 'dataPreparation',
    name: 'Data Preparation',
    viewportStructure: {
      layoutType: 'grid',
      properties: {
        rows: 1,
        columns: 3
      }
    },
    viewports: [...getPTViewports()],
    createdDate: '2023-01-01T00:00:00.000Z'
  }, {
    id: 'registration',
    name: 'Registration',
    viewportStructure: {
      layoutType: 'grid',
      properties: {
        rows: 3,
        columns: 3
      }
    },
    viewports: [...getFusionViewports(), ...getCTViewports(), ...getPTViewports()],
    createdDate: '2023-01-01T00:00:00.000Z'
  }, {
    id: 'roiQuantification',
    name: 'ROI Quantification',
    viewportStructure: {
      layoutType: 'grid',
      properties: {
        rows: 1,
        columns: 3
      }
    },
    viewports: [...getFusionViewports()],
    createdDate: '2023-01-01T00:00:00.000Z'
  }, {
    id: 'kineticAnalysis',
    name: 'Kinetic Analysis',
    viewportStructure: {
      layoutType: 'grid',
      properties: {
        rows: 2,
        columns: 3,
        layoutOptions: [{
          x: 0,
          y: 0,
          width: 1 / 3,
          height: 1 / 2
        }, {
          x: 1 / 3,
          y: 0,
          width: 1 / 3,
          height: 1 / 2
        }, {
          x: 2 / 3,
          y: 0,
          width: 1 / 3,
          height: 1 / 2
        }, {
          x: 0,
          y: 1 / 2,
          width: 1,
          height: 1 / 2
        }]
      }
    },
    viewports: [...getFusionViewports(), getSeriesChartViewport()],
    createdDate: '2023-01-01T00:00:00.000Z'
  }]
};

/**
 * HangingProtocolModule should provide a list of hanging protocols that will be
 * available in OHIF for Modes to use to decide on the structure of the viewports
 * and also the series that hung in the viewports. Each hanging protocol is defined by
 * { name, protocols}. Examples include the default hanging protocol provided by
 * the default extension that shows 2x2 viewports.
 */

function getHangingProtocolModule() {
  return [{
    name: defaultProtocol.id,
    protocol: defaultProtocol
  }];
}
/* harmony default export */ const src_getHangingProtocolModule = (getHangingProtocolModule);
;// ../../../extensions/cornerstone-dynamic-volume/src/index.ts






/**
 * You can remove any of the following modules if you don't need them.
 */
const dynamicVolumeExtension = {
  /**
   * Only required property. Should be a unique value across all extensions.
   * You ID can be anything you want, but it should be unique.
   */
  id: id,
  /**
   * Perform any pre-registration tasks here. This is called before the extension
   * is registered. Usually we run tasks such as: configuring the libraries
   * (e.g. cornerstone, cornerstoneTools, ...) or registering any services that
   * this extension is providing.
   */
  preRegistration: ({
    servicesManager,
    commandsManager,
    configuration = {}
  }) => {
    // TODO: look for the right fix
    dist_esm.cache.setMaxCacheSize(5 * 1024 * 1024 * 1024);
  },
  /**
   * PanelModule should provide a list of panels that will be available in OHIF
   * for Modes to consume and render. Each panel is defined by a {name,
   * iconName, iconLabel, label, component} object. Example of a panel module
   * is the StudyBrowserPanel that is provided by the default extension in OHIF.
   */
  getPanelModule: src_getPanelModule,
  /**
   * ViewportModule should provide a list of viewports that will be available in OHIF
   * for Modes to consume and use in the viewports. Each viewport is defined by
   * {name, component} object. Example of a viewport module is the CornerstoneViewport
   * that is provided by the Cornerstone extension in OHIF.
   */
  getHangingProtocolModule: src_getHangingProtocolModule,
  /**
   * CommandsModule should provide a list of commands that will be available in OHIF
   * for Modes to consume and use in the viewports. Each command is defined by
   * an object of { actions, definitions, defaultContext } where actions is an
   * object of functions, definitions is an object of available commands, their
   * options, and defaultContext is the default context for the command to run against.
   */
  getCommandsModule: ({
    servicesManager,
    commandsManager,
    extensionManager
  }) => {
    return src_commandsModule({
      servicesManager,
      commandsManager,
      extensionManager
    });
  }
};


/***/ }

}]);