fix(segmentation): upgrade cs3d to fix various segmentation bugs (#3885)

This commit is contained in:
Alireza 2024-01-09 10:15:56 -05:00 committed by GitHub
parent a8a0bdb2df
commit b1efe40aa1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 241 additions and 171 deletions

View File

@ -168,6 +168,8 @@ function OHIFCornerstoneRTViewport(props) {
}, [servicesManager, viewportId, rtDisplaySet, rtIsLoading]);
useEffect(() => {
// I'm not sure what is this, since in RT we support Overlapping segmnets
// via contours
const { unsubscribe } = segmentationService.subscribe(
segmentationService.EVENTS.SEGMENTATION_LOADING_COMPLETE,
evt => {

View File

@ -44,9 +44,9 @@
},
"dependencies": {
"@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^1.40.3",
"@cornerstonejs/tools": "^1.40.3",
"@kitware/vtk.js": "27.3.1",
"@cornerstonejs/adapters": "^1.43.7",
"@cornerstonejs/tools": "^1.43.7",
"@kitware/vtk.js": "29.3.0",
"react-color": "^2.19.3"
}
}

View File

@ -189,6 +189,15 @@ async function _loadSegments({ extensionManager, servicesManager, segDisplaySet,
}
});
if (results.overlappingSegments) {
uiNotificationService.show({
title: 'Overlapping Segments',
message:
'Unsupported overlapping segments detected, segmentation rendering results may be incorrect.',
type: 'warning',
});
}
if (!usedRecommendedDisplayCIELabValue) {
// Display a notification about the non-utilization of RecommendedDisplayCIELabValue
uiNotificationService.show({

View File

@ -1,7 +1,7 @@
import { createReportAsync } from '@ohif/extension-default';
import React, { useEffect, useState, useCallback } from 'react';
import PropTypes from 'prop-types';
import { SegmentationGroupTable, LegacyButtonGroup, LegacyButton } from '@ohif/ui';
import { SegmentationGroupTable } from '@ohif/ui';
import callInputDialog from './callInputDialog';
import callColorPickerDialog from './colorPickerDialog';

View File

@ -37,7 +37,7 @@ const initialState = {
},
ThresholdBrush: {
brushSize: 15,
thresholdRange: [-500, 500],
thresholdRange: null,
},
activeTool: null,
};
@ -88,6 +88,8 @@ function SegmentationToolbox({ servicesManager, extensionManager }) {
const setToolActive = useCallback(
toolName => {
initializeThresholdValue(toolName);
toolbarService.recordInteraction({
interactionType: 'tool',
commands: [
@ -178,6 +180,24 @@ function SegmentationToolbox({ servicesManager, extensionManager }) {
[toolGroupService]
);
function initializeThresholdValue(toolName: any) {
if (state.ThresholdBrush.thresholdRange === null) {
// set the default threshold range from the tool configuration
const toolGroupIds = toolGroupService.getToolGroupIds();
const toolGroupId = toolGroupIds[0];
const toolGroup = toolGroupService.getToolGroup(toolGroupId);
const toolConfig = toolGroup.getToolConfiguration(toolName);
const defaultThresholdRange = toolConfig?.strategySpecificConfiguration?.THRESHOLD?.threshold;
dispatch({
type: ACTIONS.SET_TOOL_CONFIG,
payload: {
tool: 'ThresholdBrush',
config: { thresholdRange: defaultThresholdRange },
},
});
}
}
const onBrushSizeChange = useCallback(
(valueAsStringOrNumber, toolCategory) => {
const value = Number(valueAsStringOrNumber);
@ -200,8 +220,8 @@ function SegmentationToolbox({ servicesManager, extensionManager }) {
const handleRangeChange = useCallback(
newRange => {
if (
newRange[0] === state.ThresholdBrush.thresholdRange[0] &&
newRange[1] === state.ThresholdBrush.thresholdRange[1]
newRange[0] === state.ThresholdBrush.thresholdRange?.[0] &&
newRange[1] === state.ThresholdBrush.thresholdRange?.[1]
) {
return;
}
@ -213,7 +233,7 @@ function SegmentationToolbox({ servicesManager, extensionManager }) {
const toolGroup = toolGroupService.getToolGroup(toolGroupId);
toolGroup.setToolConfiguration(toolName, {
strategySpecificConfiguration: {
THRESHOLD_INSIDE_CIRCLE: {
THRESHOLD: {
threshold: newRange,
},
},
@ -365,7 +385,7 @@ function SegmentationToolbox({ servicesManager, extensionManager }) {
<InputDoubleRange
values={state.ThresholdBrush.thresholdRange}
onChange={handleRangeChange}
minValue={-1000}
minValue={-1000} // Todo: these should be configurable
maxValue={1000}
step={1}
showLabel={true}

View File

@ -172,14 +172,6 @@ function OHIFCornerstoneSEGViewport(props) {
if (evt.segDisplaySet.displaySetInstanceUID === segDisplaySet.displaySetInstanceUID) {
setSegIsLoading(false);
}
if (evt.overlappingSegments) {
uiNotificationService.show({
title: 'Overlapping Segments',
message: 'Overlapping segments detected which is not currently supported',
type: 'warning',
});
}
}
);

View File

@ -44,9 +44,9 @@
},
"dependencies": {
"@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^1.40.3",
"@cornerstonejs/core": "^1.40.3",
"@cornerstonejs/tools": "^1.40.3",
"@cornerstonejs/adapters": "^1.43.7",
"@cornerstonejs/core": "^1.43.7",
"@cornerstonejs/tools": "^1.43.7",
"classnames": "^2.3.2"
}
}

View File

@ -36,7 +36,7 @@
"@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2",
"@cornerstonejs/codec-openjpeg": "^1.2.2",
"@cornerstonejs/codec-openjph": "^2.4.2",
"@cornerstonejs/dicom-image-loader": "^1.40.3",
"@cornerstonejs/dicom-image-loader": "^1.43.7",
"@ohif/core": "3.8.0-beta.42",
"@ohif/ui": "3.8.0-beta.42",
"dcmjs": "^0.29.12",
@ -52,11 +52,11 @@
},
"dependencies": {
"@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^1.40.3",
"@cornerstonejs/core": "^1.40.3",
"@cornerstonejs/streaming-image-volume-loader": "^1.40.3",
"@cornerstonejs/tools": "^1.40.3",
"@kitware/vtk.js": "27.3.1",
"@cornerstonejs/adapters": "^1.43.7",
"@cornerstonejs/core": "^1.43.7",
"@cornerstonejs/streaming-image-volume-loader": "^1.43.7",
"@cornerstonejs/tools": "^1.43.7",
"@kitware/vtk.js": "29.3.01",
"html2canvas": "^1.4.1",
"lodash.debounce": "4.0.8",
"lodash.merge": "^4.6.2",

View File

@ -253,10 +253,10 @@ export default async function init({
/**
* Runs error handler for failed requests.
* @param event
* @param event
*/
const imageLoadFailedHandler = ({ detail }) => {
const handler = errorHandler.getHTTPErrorHandler()
const handler = errorHandler.getHTTPErrorHandler();
handler(detail.error);
};
@ -290,7 +290,7 @@ export default async function init({
});
eventTarget.addEventListener(EVENTS.IMAGE_LOAD_FAILED, imageLoadFailedHandler);
eventTarget.addEventListener(EVENTS.IMAGE_LOAD_ERROR, imageLoadFailedHandler);
function elementEnabledHandler(evt) {
const { element } = evt.detail;

View File

@ -1,5 +1,3 @@
import cloneDeep from 'lodash.clonedeep';
import { Types as OhifTypes, ServicesManager, PubSubService } from '@ohif/core';
import {
cache,
@ -11,7 +9,6 @@ import {
volumeLoader,
} from '@cornerstonejs/core';
import {
CONSTANTS as cstConstants,
Enums as csToolsEnums,
segmentation as cstSegmentation,
Types as cstTypes,
@ -23,7 +20,6 @@ import { easeInOutBell, reverseEaseInOutBell } from '../../utils/transitions';
import { Segment, Segmentation, SegmentationConfig } from './SegmentationServiceTypes';
import { mapROIContoursToRTStructData } from './RTSTRUCT/mapROIContoursToRTStructData';
const { COLOR_LUT } = cstConstants;
const LABELMAP = csToolsEnums.SegmentationRepresentations.Labelmap;
const CONTOUR = csToolsEnums.SegmentationRepresentations.Contour;
@ -465,15 +461,6 @@ class SegmentationService extends PubSubService {
},
]);
// if first segmentation, we can use the default colorLUT, otherwise
// we need to generate a new one and use a new colorLUT
const colorLUTIndex = 0;
if (Object.keys(this.segmentations).length !== 0) {
const newColorLUT = this.generateNewColorLUT();
const colorLUTIndex = this.getNextColorLUTIndex();
cstSegmentation.config.color.addColorLUT(newColorLUT, colorLUTIndex);
}
this.segmentations[segmentationId] = {
...segmentation,
label: segmentation.label || '',
@ -482,7 +469,6 @@ class SegmentationService extends PubSubService {
segmentCount: segmentation.segmentCount ?? 0,
isActive: false,
isVisible: true,
colorLUTIndex,
};
cachedSegmentation = this.segmentations[segmentationId];
@ -1037,8 +1023,6 @@ class SegmentationService extends PubSubService {
segmentation.hydrated = true;
}
const { colorLUTIndex } = segmentation;
// Based on the segmentationId, set the colorLUTIndex.
const segmentationRepresentationUIDs = await cstSegmentation.addSegmentationRepresentations(
toolGroupId,
@ -1057,12 +1041,6 @@ class SegmentationService extends PubSubService {
segmentationRepresentationUIDs[0]
);
cstSegmentation.config.color.setColorLUT(
toolGroupId,
segmentationRepresentationUIDs[0],
colorLUTIndex
);
// add the segmentation segments properly
for (const segment of segmentation.segments) {
if (segment === null || segment === undefined) {
@ -1530,7 +1508,6 @@ class SegmentationService extends PubSubService {
segments: [],
isVisible: true,
isActive: false,
colorLUTIndex: 0,
};
}
@ -2124,23 +2101,6 @@ class SegmentationService extends PubSubService {
return viewportInfo.getToolGroupId();
};
private getNextColorLUTIndex = (): number => {
let i = 0;
while (true) {
if (cstSegmentation.state.getColorLUT(i) === undefined) {
return i;
}
i++;
}
};
private generateNewColorLUT() {
const newColorLUT = cloneDeep(COLOR_LUT);
return newColorLUT;
}
/**
* Converts object of objects to array.
*

View File

@ -1,5 +1,5 @@
import { Types, Enums } from '@cornerstonejs/core';
import { Types as UITypes } from '@ohif/ui';
import { Types as CoreTypes } from '@ohif/core';
import { StackViewportData, VolumeViewportData } from '../../types/CornerstoneCacheService';
import getCornerstoneBlendMode from '../../utils/getCornerstoneBlendMode';
import getCornerstoneOrientation from '../../utils/getCornerstoneOrientation';
@ -18,7 +18,7 @@ export type ViewportOptions = {
toolGroupId: string;
viewportId: string;
// Presentation ID to store/load presentation state from
presentationIds?: UITypes.PresentationIds;
presentationIds?: CoreTypes.PresentationIds;
orientation?: Enums.OrientationAxis;
background?: Types.Point3;
displayArea?: Types.DisplayArea;
@ -36,7 +36,7 @@ export type PublicViewportOptions = {
id?: string;
viewportType?: string;
toolGroupId?: string;
presentationIds?: UITypes.PresentationIds;
presentationIds?: CoreTypes.PresentationIds;
viewportId?: string;
orientation?: Enums.OrientationAxis;
background?: Types.Point3;
@ -71,7 +71,7 @@ export type DisplaySetOptions = {
voiInverted: boolean;
blendMode?: Enums.BlendModes;
slabThickness?: number;
colormap?: { name: string, opacity?: number };
colormap?: { name: string; opacity?: number };
displayPreset?: string;
};

View File

@ -1,12 +1,12 @@
/** Store presentation data for either stack viewports or volume viewports */
import { Types } from '@cornerstonejs/core';
import { Types as UITypes } from '@ohif/ui';
import { Types as CoreTypes } from '@ohif/core';
/**
* Has information on the presentation of the viewport.
*/
export interface Presentation extends Types.StackViewportProperties {
presentationIds: UITypes.PresentationIds;
presentationIds: CoreTypes.PresentationIds;
viewportType: string;
initialImageIndex: number;
camera: Types.ICamera;

View File

@ -30,8 +30,8 @@
"start": "yarn run dev"
},
"peerDependencies": {
"@cornerstonejs/core": "^1.40.3",
"@cornerstonejs/tools": "^1.40.3",
"@cornerstonejs/core": "^1.43.7",
"@cornerstonejs/tools": "^1.43.7",
"@ohif/core": "3.8.0-beta.42",
"@ohif/extension-cornerstone-dicom-sr": "3.8.0-beta.42",
"@ohif/ui": "3.8.0-beta.42",

View File

@ -1,21 +1,3 @@
const brushInstanceNames = {
CircularBrush: 'CircularBrush',
CircularEraser: 'CircularEraser',
SphereBrush: 'SphereBrush',
SphereEraser: 'SphereEraser',
ThresholdCircularBrush: 'ThresholdCircularBrush',
ThresholdSphereBrush: 'ThresholdSphereBrush',
};
const brushStrategies = {
CircularBrush: 'FILL_INSIDE_CIRCLE',
CircularEraser: 'ERASE_INSIDE_CIRCLE',
SphereBrush: 'FILL_INSIDE_SPHERE',
SphereEraser: 'ERASE_INSIDE_SPHERE',
ThresholdCircularBrush: 'THRESHOLD_INSIDE_CIRCLE',
ThresholdSphereBrush: 'THRESHOLD_INSIDE_SPHERE',
};
function createTools(utilityModule) {
const { toolNames, Enums } = utilityModule.exports;
return {
@ -25,22 +7,66 @@ function createTools(utilityModule) {
{ toolName: toolNames.Zoom, bindings: [{ mouseButton: Enums.MouseBindings.Secondary }] },
{ toolName: toolNames.StackScrollMouseWheel, bindings: [] },
],
passive: Object.keys(brushInstanceNames)
.map(brushName => ({
toolName: brushName,
passive: [
{
toolName: 'CircularBrush',
parentTool: 'Brush',
configuration: {
activeStrategy: brushStrategies[brushName],
activeStrategy: 'FILL_INSIDE_CIRCLE',
},
}))
.concat([
{ toolName: toolNames.CircleScissors },
{ toolName: toolNames.RectangleScissors },
{ toolName: toolNames.SphereScissors },
{ toolName: toolNames.StackScroll },
{ toolName: toolNames.Magnify },
{ toolName: toolNames.SegmentationDisplay },
]),
},
{
toolName: 'CircularEraser',
parentTool: 'Brush',
configuration: {
activeStrategy: 'ERASE_INSIDE_CIRCLE',
},
},
{
toolName: 'SphereBrush',
parentTool: 'Brush',
configuration: {
activeStrategy: 'FILL_INSIDE_SPHERE',
},
},
{
toolName: 'SphereEraser',
parentTool: 'Brush',
configuration: {
activeStrategy: 'ERASE_INSIDE_SPHERE',
},
},
{
toolName: 'ThresholdCircularBrush',
parentTool: 'Brush',
configuration: {
activeStrategy: 'THRESHOLD_INSIDE_CIRCLE',
strategySpecificConfiguration: {
THRESHOLD: {
threshold: [-500, 500],
},
},
},
},
{
toolName: 'ThresholdSphereBrush',
parentTool: 'Brush',
configuration: {
activeStrategy: 'THRESHOLD_INSIDE_SPHERE',
strategySpecificConfiguration: {
THRESHOLD: {
threshold: [-500, 500],
},
},
},
},
{ toolName: toolNames.CircleScissors },
{ toolName: toolNames.RectangleScissors },
{ toolName: toolNames.SphereScissors },
{ toolName: toolNames.StackScroll },
{ toolName: toolNames.Magnify },
{ toolName: toolNames.SegmentationDisplay },
],
disabled: [{ toolName: toolNames.ReferenceLines }],
};
}

View File

@ -57,7 +57,7 @@
},
"dependencies": {
"@babel/runtime": "^7.20.13",
"@kitware/vtk.js": "27.3.1",
"@kitware/vtk.js": "29.3.0",
"core-js": "^3.2.1"
},
"peerDependencies": {

View File

@ -85,7 +85,7 @@ describe('OHIF Cornerstone Toolbar', () => {
// The exact text is slightly dependent on the viewport resolution, so leave a range
cy.get('@viewportInfoTopLeft').should($txt => {
const text = $txt.text();
expect(text).to.include('W:193').include('L:479');
expect(text).to.include('W:1185').include('L:479');
});
});

View File

@ -51,7 +51,7 @@
"@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2",
"@cornerstonejs/codec-openjpeg": "^1.2.2",
"@cornerstonejs/codec-openjph": "^2.4.5",
"@cornerstonejs/dicom-image-loader": "^1.40.3",
"@cornerstonejs/dicom-image-loader": "^1.43.7",
"@ohif/core": "3.8.0-beta.42",
"@ohif/extension-cornerstone": "3.8.0-beta.42",
"@ohif/extension-cornerstone-dicom-rt": "3.8.0-beta.42",

View File

@ -1,4 +1,4 @@
import React, {useEffect, useCallback, useMemo} from 'react';
import React, { useEffect, useCallback } from 'react';
import PropTypes from 'prop-types';
import { ServicesManager, Types, MeasurementService } from '@ohif/core';
import { ViewportGrid, ViewportPane, useViewportGrid } from '@ohif/ui';
@ -9,6 +9,7 @@ import { useAppConfig } from '@state';
function ViewerViewportGrid(props) {
const { servicesManager, viewportComponents, dataSource } = props;
const [viewportGrid, viewportGridService] = useViewportGrid();
const [appConfig] = useAppConfig();
const { layout, activeViewportId, viewports } = viewportGrid;
const { numCols, numRows } = layout;
@ -18,18 +19,6 @@ function ViewerViewportGrid(props) {
servicesManager as ServicesManager
).services;
/**
* Determine whether users need to use the tools directly, or whether they need to click once to activate the viewport before using tools.
* If 'activateViewportBeforeInteraction' is available in the 'window.config' object, use its value;
* otherwise, default to true.
* If true, users need to click once to activate the viewport before using the tools.
* if false, tools can be used directly.
*/
const activateViewportBeforeInteraction = useMemo(() => {
const [appConfig] = useAppConfig();
return appConfig?.activateViewportBeforeInteraction ?? true;
}, []);
/**
* This callback runs after the viewports structure has changed in any way.
* On initial display, that means if it has changed by applying a HangingProtocol,
@ -324,7 +313,8 @@ function ViewerViewportGrid(props) {
<div
data-cy="viewport-pane"
className={classNames('flex h-full w-full flex-col', {
'pointer-events-none': !isActive && activateViewportBeforeInteraction,
'pointer-events-none':
!isActive && (appConfig?.activateViewportBeforeInteraction ?? true),
})}
>
<ViewportComponent

View File

@ -35,7 +35,7 @@
"@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2",
"@cornerstonejs/codec-openjpeg": "^1.2.2",
"@cornerstonejs/codec-openjph": "^2.4.2",
"@cornerstonejs/dicom-image-loader": "^1.40.3",
"@cornerstonejs/dicom-image-loader": "^1.43.7",
"@ohif/ui": "3.8.0-beta.42",
"cornerstone-math": "0.1.9",
"dicom-parser": "^1.8.21"

View File

@ -1,3 +1,5 @@
import ViewportGridService from './ViewportGridService';
import type { PresentationIds } from './ViewportGridService';
export default ViewportGridService;
export type { PresentationIds };

View File

@ -7,6 +7,7 @@ import type {
BaseDataSourceConfigurationAPI,
BaseDataSourceConfigurationAPIItem,
} from './DataSourceConfigurationAPI';
import type { PresentationIds } from '../services/ViewportGridService';
export type * from '../services/CustomizationService/types';
// Separate out some generic types
@ -34,4 +35,5 @@ export {
DataSourceDefinition,
BaseDataSourceConfigurationAPI,
BaseDataSourceConfigurationAPIItem,
PresentationIds,
};

View File

@ -60,10 +60,10 @@ module.exports = {
? // Deploy preview: keep it fast!
['en']
: isI18nStaging
? // Staging locales: https://docusaurus-i18n-staging.netlify.app/
['en']
: // Production locales
['en'],
? // Staging locales: https://docusaurus-i18n-staging.netlify.app/
['en']
: // Production locales
['en'],
},
onBrokenLinks: 'warn',
onBrokenMarkdownLinks: 'warn',
@ -88,7 +88,7 @@ module.exports = {
},
}),
path.resolve(__dirname, './pluginOHIFWebpackConfig.js'),
'plugin-image-zoom', // 3rd party plugin for image click to pop
'docusaurus-plugin-image-zoom', // 3rd party plugin for image click to pop
[
'@docusaurus/plugin-client-redirects',
{
@ -281,6 +281,16 @@ module.exports = {
apiKey: 'c220dd24fe4f86248eea3b1238a1fb60',
indexName: 'ohif',
},
// zoom: {
// selector: '.markdown > img',
// background: {
// light: 'rgb(255, 255, 255)',
// dark: 'rgb(50, 50, 50)',
// },
// config: {
// // options you can specify via https://github.com/francoischalifour/medium-zoom#usage
// },
// },
navbar: {
hideOnScroll: false,
logo: {

View File

@ -35,12 +35,13 @@
"@docusaurus/preset-classic": "2.4.3",
"@docusaurus/remark-plugin-npm2yarn": "2.4.3",
"@docusaurus/theme-live-codeblock": "2.4.3",
"docusaurus-plugin-image-zoom": "^1.0.1",
"@docusaurus/theme-classic": "2.4.3",
"@mdx-js/react": "^1.6.21",
"@svgr/webpack": "^5.5.0",
"classnames": "^2.3.2",
"clsx": "^1.1.1",
"file-loader": "^6.2.0",
"plugin-image-zoom": "ataft/plugin-image-zoom",
"url-loader": "^4.1.1"
},
"peerDependencies": {

View File

@ -45,7 +45,7 @@ function ToolSettings({ options }) {
onChange={e => option.onChange(e)}
allowNumberEdit={true}
showAdjustmentArrows={false}
inputClassName="ml-1 w-4/5"
inputClassName="ml-1 w-4/5 cursor-pointer"
/>
</div>
</div>

View File

@ -1,6 +1,5 @@
import PropTypes from 'prop-types';
import ThumbnailType from './ThumbnailType';
import type { PresentationIds } from '../contextProviders/getPresentationIds';
// A few miscellaneous types declared inline here.

131
yarn.lock
View File

@ -1394,7 +1394,7 @@
core-js-pure "^3.30.2"
regenerator-runtime "^0.14.0"
"@babel/runtime@7.17.9", "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.3", "@babel/runtime@^7.18.6", "@babel/runtime@^7.20.13", "@babel/runtime@^7.20.6", "@babel/runtime@^7.23.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.4", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
"@babel/runtime@7.22.11", "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.3", "@babel/runtime@^7.18.6", "@babel/runtime@^7.20.13", "@babel/runtime@^7.20.6", "@babel/runtime@^7.23.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.4", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
version "7.23.6"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.6.tgz#c05e610dc228855dc92ef1b53d07389ed8ab521d"
integrity sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ==
@ -1450,10 +1450,10 @@
resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9"
integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==
"@cornerstonejs/adapters@^1.40.3":
version "1.40.3"
resolved "https://registry.yarnpkg.com/@cornerstonejs/adapters/-/adapters-1.40.3.tgz#aaf9e86e648bf3e6531f1d16d9439be48aee40f5"
integrity sha512-StTYbq1RWBHI9yd2Xax6ebk0PX/pvKDmA4j9+WkBTh1MNnNGxABGpRHSdRKa96YlhGnVM1z5u0Ox5BmBMIAy2w==
"@cornerstonejs/adapters@^1.43.7":
version "1.43.7"
resolved "https://registry.yarnpkg.com/@cornerstonejs/adapters/-/adapters-1.43.7.tgz#920344cd6548cfa26ebe05db01ea94ef9121dc5e"
integrity sha512-X6tQDcT9PeXXrmEoDaCb/hHjWEk+h7svz4XRfCWJKqbTRNmpTWmr70KY2lMRMm/FVPC+Ix2KdHStBN2/9zLDsg==
dependencies:
"@babel/runtime-corejs2" "^7.17.8"
buffer "^6.0.3"
@ -1502,45 +1502,45 @@
resolved "https://registry.yarnpkg.com/@cornerstonejs/codec-openjph/-/codec-openjph-2.4.5.tgz#8690b61a86fa53ef38a70eee9d665a79229517c0"
integrity sha512-MZCUy8VG0VG5Nl1l58+g+kH3LujAzLYTfJqkwpWI2gjSrGXnP6lgwyy4GmPRZWVoS40/B1LDNALK905cNWm+sg==
"@cornerstonejs/core@^1.40.3":
version "1.40.3"
resolved "https://registry.yarnpkg.com/@cornerstonejs/core/-/core-1.40.3.tgz#b591434fa9b80397f97541e4380c09b5cb4b28a0"
integrity sha512-7YgEJM02zZLJZNP4RHp+X1xg+i70ZnV5TkhQaOZSCaoKTEup1I7w3ywMDCrvMMXdE+D8qB6dmvSamJjtWDzKbg==
"@cornerstonejs/core@^1.43.7":
version "1.43.7"
resolved "https://registry.yarnpkg.com/@cornerstonejs/core/-/core-1.43.7.tgz#6da8c3598fc79b99357f1bc039b385447179ab67"
integrity sha512-36jYRnIxIGHyEL2pngpHiLX3HQINXabzi8P8K6BMf7HcWv9sgbWwmglUv71+gCo2my3Ai+vDUWrpoGIrmu+RGA==
dependencies:
"@kitware/vtk.js" "27.3.1"
"@kitware/vtk.js" "29.3.0"
comlink "^4.4.1"
detect-gpu "^5.0.22"
gl-matrix "^3.4.3"
lodash.clonedeep "4.5.0"
"@cornerstonejs/dicom-image-loader@^1.40.3":
version "1.40.3"
resolved "https://registry.yarnpkg.com/@cornerstonejs/dicom-image-loader/-/dicom-image-loader-1.40.3.tgz#2a397bcb306231bf8ead1826d3cb98bc9614ed66"
integrity sha512-GaxI9kYmbc8NtbqQAuyv5Ofu91L/ASxcNDKbNVX6rFQ3HQ0n0OspxsarMLKn4oTY0hRFf+3dJYgM+cTmd8obtw==
"@cornerstonejs/dicom-image-loader@^1.43.7":
version "1.43.7"
resolved "https://registry.yarnpkg.com/@cornerstonejs/dicom-image-loader/-/dicom-image-loader-1.43.7.tgz#76b013815f7c5688604f76c7473a292397ad31ad"
integrity sha512-9wvXOx0S4TgIU+2SdYJUnGjv5yM4ylVJWt2q1q6yV6FuCEyhd1NB6cvAJSF61DlqWwS3oSiQRqU6wRf7wh73Jw==
dependencies:
"@cornerstonejs/codec-charls" "^1.2.3"
"@cornerstonejs/codec-libjpeg-turbo-8bit" "^1.2.2"
"@cornerstonejs/codec-openjpeg" "^1.2.2"
"@cornerstonejs/codec-openjph" "^2.4.5"
"@cornerstonejs/core" "^1.40.3"
"@cornerstonejs/core" "^1.43.7"
dicom-parser "^1.8.9"
pako "^2.0.4"
uuid "^9.0.0"
"@cornerstonejs/streaming-image-volume-loader@^1.40.3":
version "1.40.3"
resolved "https://registry.yarnpkg.com/@cornerstonejs/streaming-image-volume-loader/-/streaming-image-volume-loader-1.40.3.tgz#bf3f5e53a9986c2400dc62d8d13ee138fc192b4a"
integrity sha512-QYgdlKOvJxDyoD+2LxlY1EAaxKza0b/2dD65u1055qWvfWWJe8sqipGUbuDtShlcDdCSZLe6oPCHV5IVFhI5cQ==
"@cornerstonejs/streaming-image-volume-loader@^1.43.7":
version "1.43.7"
resolved "https://registry.yarnpkg.com/@cornerstonejs/streaming-image-volume-loader/-/streaming-image-volume-loader-1.43.7.tgz#972f675bd6de81cb6e65d495f0243013c17062bf"
integrity sha512-0FmGeLzFub4TSLhhxq8fDRAj20UF2C7lM9EA4UvEc/iR/B65ly9lGiMONB58Wodl9HamHHkmr4moD1Sjn3sfBg==
dependencies:
"@cornerstonejs/core" "^1.40.3"
"@cornerstonejs/core" "^1.43.7"
comlink "^4.4.1"
"@cornerstonejs/tools@^1.40.3":
version "1.40.3"
resolved "https://registry.yarnpkg.com/@cornerstonejs/tools/-/tools-1.40.3.tgz#2878185a5b848bd07e0a90482a2661525c2e2df8"
integrity sha512-h5+AibxT19nUPg5mTJ0v6xwyjUcN+a4Y1tLo9/mZmzjqLEUk4VljNAtcIj+bRPplNqET5sygZ/StOwC94fFItQ==
"@cornerstonejs/tools@^1.43.7":
version "1.43.7"
resolved "https://registry.yarnpkg.com/@cornerstonejs/tools/-/tools-1.43.7.tgz#70c3e75636bde19f6fa7d9c86ef61ececf8a2b9c"
integrity sha512-4yhWGeNsSF2F06T6sGLjARX7F7atUwUNv5qnMqFVZ7b/TfQbpdB8zkXHA0Rhz/YB3ebr/zWvRxDtzah+5VMxnQ==
dependencies:
"@cornerstonejs/core" "^1.40.3"
"@cornerstonejs/core" "^1.43.7"
comlink "^4.4.1"
lodash.clonedeep "4.5.0"
lodash.get "^4.4.2"
@ -2789,12 +2789,35 @@
resolved "https://registry.yarnpkg.com/@juggle/resize-observer/-/resize-observer-3.4.0.tgz#08d6c5e20cf7e4cc02fd181c4b0c225cd31dbb60"
integrity sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==
"@kitware/vtk.js@27.3.1":
version "27.3.1"
resolved "https://registry.yarnpkg.com/@kitware/vtk.js/-/vtk.js-27.3.1.tgz#65004b041642663da94e6a488ebb813576e7de7d"
integrity sha512-GvAXdOKtDDbkaSdO+UhKnDST4CW1C3fHgaDvA0wn1ZWTLm/6SFAMzarTjpzsVGYCPoEYIhCAAlBQ7K7aDcu3Vg==
"@kitware/vtk.js@29.3.0":
version "29.3.0"
resolved "https://registry.yarnpkg.com/@kitware/vtk.js/-/vtk.js-29.3.0.tgz#8601e07cde3da61c285aabfcb3484ae1ffb1074b"
integrity sha512-EofIxo6Qcfhh8SRx8Xp7B8HGM//2tzjQbhrMQsiaoPgs3yhtrqm+CBFmqboxt+waF8qUKxuUQb+DzM8cX2ivAg==
dependencies:
"@babel/runtime" "7.17.9"
"@babel/runtime" "7.22.11"
"@types/webxr" "^0.5.5"
commander "9.2.0"
d3-scale "4.0.2"
fast-deep-equal "^3.1.3"
fflate "0.7.3"
gl-matrix "3.4.3"
globalthis "1.0.3"
seedrandom "3.0.5"
shader-loader "1.3.1"
shelljs "0.8.5"
spark-md5 "3.0.2"
stream-browserify "3.0.0"
webworker-promise "0.5.0"
worker-loader "3.0.8"
xmlbuilder2 "3.0.2"
"@kitware/vtk.js@29.3.01":
version "29.3.1"
resolved "https://registry.yarnpkg.com/@kitware/vtk.js/-/vtk.js-29.3.1.tgz#007df75c1f4744b4779087b9306a667c6acdc3c8"
integrity sha512-TM3uBVwJWdMIU+VD+OnSxQU45lJiJiOxxkx56Du6K4d18u5fHi7nBkSlNhTtOCX5H8amwIofaPCKRnYRNkjosA==
dependencies:
"@babel/runtime" "7.22.11"
"@types/webxr" "^0.5.5"
commander "9.2.0"
d3-scale "4.0.2"
fast-deep-equal "^3.1.3"
@ -5459,6 +5482,11 @@
anymatch "^3.0.0"
source-map "^0.6.0"
"@types/webxr@^0.5.5":
version "0.5.10"
resolved "https://registry.yarnpkg.com/@types/webxr/-/webxr-0.5.10.tgz#19c76208ec015ca3f139505e14d94d6b740f518a"
integrity sha512-n3u5sqXQJhf1CS68mw3Wf16FQ4cRPNBBwdYLFzq3UddiADOim1Pn3Y6PBdDilz1vOJF3ybLxJ8ZEDlLIzrOQZg==
"@types/ws@^8.2.2", "@types/ws@^8.5.5":
version "8.5.10"
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.10.tgz#4acfb517970853fa6574a3a6886791d04a396787"
@ -8936,6 +8964,14 @@ document.contains@^1.0.1:
dependencies:
define-properties "^1.1.3"
docusaurus-plugin-image-zoom@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/docusaurus-plugin-image-zoom/-/docusaurus-plugin-image-zoom-1.0.1.tgz#17afec39f2e630cac50a4ed3a8bbdad8d0aa8b9d"
integrity sha512-96IpSKUx2RWy3db9aZ0s673OQo5DWgV9UVWouS+CPOSIVEdCWh6HKmWf6tB9rsoaiIF3oNn9keiyv6neEyKb1Q==
dependencies:
medium-zoom "^1.0.6"
validate-peer-dependencies "^2.2.0"
dom-converter@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768"
@ -14217,7 +14253,7 @@ media-typer@0.3.0:
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==
medium-zoom@^1.0.8:
medium-zoom@^1.0.6:
version "1.1.0"
resolved "https://registry.yarnpkg.com/medium-zoom/-/medium-zoom-1.1.0.tgz#6efb6bbda861a02064ee71a2617a8dc4381ecc71"
integrity sha512-ewyDsp7k4InCUp3jRmwHBRFGyjBimKps/AJLjRSox+2q/2H4p/PNpQf+pwONWlJiOudkBXtbdmVbFjqyybfTmQ==
@ -15974,6 +16010,18 @@ path-parse@^1.0.6, path-parse@^1.0.7:
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
path-root-regex@^0.1.0:
version "0.1.2"
resolved "https://registry.yarnpkg.com/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d"
integrity sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==
path-root@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/path-root/-/path-root-0.1.1.tgz#9a4a6814cac1c0cd73360a95f32083c8ea4745b7"
integrity sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==
dependencies:
path-root-regex "^0.1.0"
path-scurry@^1.10.1, path-scurry@^1.6.1:
version "1.10.1"
resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.1.tgz#9ba6bf5aa8500fe9fd67df4f0d9483b2b0bfc698"
@ -16164,12 +16212,6 @@ please-upgrade-node@^3.1.1, please-upgrade-node@^3.2.0:
dependencies:
semver-compare "^1.0.0"
plugin-image-zoom@ataft/plugin-image-zoom:
version "1.1.0"
resolved "https://codeload.github.com/ataft/plugin-image-zoom/tar.gz/8e1b866c79ed6d42cefc4c52f851f1dfd1d0c7de"
dependencies:
medium-zoom "^1.0.4"
polished@^4.2.2:
version "4.2.2"
resolved "https://registry.yarnpkg.com/polished/-/polished-4.2.2.tgz#2529bb7c3198945373c52e34618c8fe7b1aa84d1"
@ -18189,6 +18231,13 @@ resolve-from@^4.0.0:
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
resolve-package-path@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/resolve-package-path/-/resolve-package-path-4.0.3.tgz#31dab6897236ea6613c72b83658d88898a9040aa"
integrity sha512-SRpNAPW4kewOaNUt8VPqhJ0UMxawMwzJD8V7m1cJfdSTK9ieZwS6K7Dabsm4bmLFM96Z5Y/UznrpG5kt1im8yA==
dependencies:
path-root "^0.1.1"
resolve-pathname@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd"
@ -20691,6 +20740,14 @@ validate-npm-package-name@^3.0.0:
dependencies:
builtins "^1.0.3"
validate-peer-dependencies@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/validate-peer-dependencies/-/validate-peer-dependencies-2.2.0.tgz#47b8ff008f66a66fc5d8699123844522c1d874f4"
integrity sha512-8X1OWlERjiUY6P6tdeU9E0EwO8RA3bahoOVG7ulOZT5MqgNDUO/BQoVjYiHPcNe+v8glsboZRIw9iToMAA2zAA==
dependencies:
resolve-package-path "^4.0.3"
semver "^7.3.8"
validate.js@^0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/validate.js/-/validate.js-0.12.0.tgz#17f989e37c192ea2f826bbf19bf4e97e6e4be68f"