From b1efe40aa146e4052cc47b3f774cabbb47a8d1a6 Mon Sep 17 00:00:00 2001 From: Alireza Date: Tue, 9 Jan 2024 10:15:56 -0500 Subject: [PATCH] fix(segmentation): upgrade cs3d to fix various segmentation bugs (#3885) --- .../viewports/OHIFCornerstoneRTViewport.tsx | 2 + extensions/cornerstone-dicom-seg/package.json | 6 +- .../src/getSopClassHandlerModule.js | 9 ++ .../src/panels/PanelSegmentation.tsx | 2 +- .../src/panels/SegmentationToolbox.tsx | 30 +++- .../viewports/OHIFCornerstoneSEGViewport.tsx | 8 -- extensions/cornerstone-dicom-sr/package.json | 6 +- extensions/cornerstone/package.json | 12 +- extensions/cornerstone/src/init.tsx | 6 +- .../SegmentationService.ts | 40 ------ .../src/services/ViewportService/Viewport.ts | 8 +- .../cornerstone/src/types/Presentation.ts | 4 +- extensions/measurement-tracking/package.json | 4 +- modes/segmentation/src/initToolGroups.ts | 88 +++++++----- package.json | 2 +- .../OHIFCornerstoneToolbar.spec.js | 2 +- platform/app/package.json | 2 +- platform/app/src/components/ViewportGrid.tsx | 18 +-- platform/core/package.json | 2 +- .../src/services/ViewportGridService/index.ts | 2 + platform/core/src/types/index.ts | 2 + platform/docs/docusaurus.config.js | 20 ++- platform/docs/package.json | 3 +- .../AdvancedToolbox/ToolSettings.tsx | 2 +- platform/ui/src/types/index.ts | 1 - yarn.lock | 131 +++++++++++++----- 26 files changed, 241 insertions(+), 171 deletions(-) diff --git a/extensions/cornerstone-dicom-rt/src/viewports/OHIFCornerstoneRTViewport.tsx b/extensions/cornerstone-dicom-rt/src/viewports/OHIFCornerstoneRTViewport.tsx index e9c7450c6..e0e12ca57 100644 --- a/extensions/cornerstone-dicom-rt/src/viewports/OHIFCornerstoneRTViewport.tsx +++ b/extensions/cornerstone-dicom-rt/src/viewports/OHIFCornerstoneRTViewport.tsx @@ -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 => { diff --git a/extensions/cornerstone-dicom-seg/package.json b/extensions/cornerstone-dicom-seg/package.json index ba9ae5afe..80091f016 100644 --- a/extensions/cornerstone-dicom-seg/package.json +++ b/extensions/cornerstone-dicom-seg/package.json @@ -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" } } diff --git a/extensions/cornerstone-dicom-seg/src/getSopClassHandlerModule.js b/extensions/cornerstone-dicom-seg/src/getSopClassHandlerModule.js index 68a6b15bd..d150201e0 100644 --- a/extensions/cornerstone-dicom-seg/src/getSopClassHandlerModule.js +++ b/extensions/cornerstone-dicom-seg/src/getSopClassHandlerModule.js @@ -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({ diff --git a/extensions/cornerstone-dicom-seg/src/panels/PanelSegmentation.tsx b/extensions/cornerstone-dicom-seg/src/panels/PanelSegmentation.tsx index 381fa7cc5..ea1ab1de6 100644 --- a/extensions/cornerstone-dicom-seg/src/panels/PanelSegmentation.tsx +++ b/extensions/cornerstone-dicom-seg/src/panels/PanelSegmentation.tsx @@ -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'; diff --git a/extensions/cornerstone-dicom-seg/src/panels/SegmentationToolbox.tsx b/extensions/cornerstone-dicom-seg/src/panels/SegmentationToolbox.tsx index f2d580cff..868a5279f 100644 --- a/extensions/cornerstone-dicom-seg/src/panels/SegmentationToolbox.tsx +++ b/extensions/cornerstone-dicom-seg/src/panels/SegmentationToolbox.tsx @@ -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 }) { { - 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; diff --git a/extensions/cornerstone/src/services/SegmentationService/SegmentationService.ts b/extensions/cornerstone/src/services/SegmentationService/SegmentationService.ts index 6c48d5dfb..f71dbff5d 100644 --- a/extensions/cornerstone/src/services/SegmentationService/SegmentationService.ts +++ b/extensions/cornerstone/src/services/SegmentationService/SegmentationService.ts @@ -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. * diff --git a/extensions/cornerstone/src/services/ViewportService/Viewport.ts b/extensions/cornerstone/src/services/ViewportService/Viewport.ts index 26063a9b1..f0e417090 100644 --- a/extensions/cornerstone/src/services/ViewportService/Viewport.ts +++ b/extensions/cornerstone/src/services/ViewportService/Viewport.ts @@ -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; }; diff --git a/extensions/cornerstone/src/types/Presentation.ts b/extensions/cornerstone/src/types/Presentation.ts index 82f13f745..f8711b686 100644 --- a/extensions/cornerstone/src/types/Presentation.ts +++ b/extensions/cornerstone/src/types/Presentation.ts @@ -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; diff --git a/extensions/measurement-tracking/package.json b/extensions/measurement-tracking/package.json index 582067a8d..3f5bbb629 100644 --- a/extensions/measurement-tracking/package.json +++ b/extensions/measurement-tracking/package.json @@ -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", diff --git a/modes/segmentation/src/initToolGroups.ts b/modes/segmentation/src/initToolGroups.ts index 58204839e..e549f7a89 100644 --- a/modes/segmentation/src/initToolGroups.ts +++ b/modes/segmentation/src/initToolGroups.ts @@ -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 }], }; } diff --git a/package.json b/package.json index e4882be7a..4c37e921a 100644 --- a/package.json +++ b/package.json @@ -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": { diff --git a/platform/app/cypress/integration/measurement-tracking/OHIFCornerstoneToolbar.spec.js b/platform/app/cypress/integration/measurement-tracking/OHIFCornerstoneToolbar.spec.js index d6a7bb24d..b9721a21f 100644 --- a/platform/app/cypress/integration/measurement-tracking/OHIFCornerstoneToolbar.spec.js +++ b/platform/app/cypress/integration/measurement-tracking/OHIFCornerstoneToolbar.spec.js @@ -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'); }); }); diff --git a/platform/app/package.json b/platform/app/package.json index 314e9e285..7374762e1 100644 --- a/platform/app/package.json +++ b/platform/app/package.json @@ -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", diff --git a/platform/app/src/components/ViewportGrid.tsx b/platform/app/src/components/ViewportGrid.tsx index ac43a24d8..c3151116d 100644 --- a/platform/app/src/components/ViewportGrid.tsx +++ b/platform/app/src/components/ViewportGrid.tsx @@ -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) {
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: { diff --git a/platform/docs/package.json b/platform/docs/package.json index b7f9e9ed4..a5a519b89 100644 --- a/platform/docs/package.json +++ b/platform/docs/package.json @@ -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": { diff --git a/platform/ui/src/components/AdvancedToolbox/ToolSettings.tsx b/platform/ui/src/components/AdvancedToolbox/ToolSettings.tsx index 14a5c5a5c..75eae9129 100644 --- a/platform/ui/src/components/AdvancedToolbox/ToolSettings.tsx +++ b/platform/ui/src/components/AdvancedToolbox/ToolSettings.tsx @@ -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" />
diff --git a/platform/ui/src/types/index.ts b/platform/ui/src/types/index.ts index 284eea278..2553d6200 100644 --- a/platform/ui/src/types/index.ts +++ b/platform/ui/src/types/index.ts @@ -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. diff --git a/yarn.lock b/yarn.lock index ed1ecc288..6fb798c06 100644 --- a/yarn.lock +++ b/yarn.lock @@ -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"