diff --git a/extensions/cornerstone-dicom-rt/src/viewports/OHIFCornerstoneRTViewport.tsx b/extensions/cornerstone-dicom-rt/src/viewports/OHIFCornerstoneRTViewport.tsx index bef64b145..1b2b42b22 100644 --- a/extensions/cornerstone-dicom-rt/src/viewports/OHIFCornerstoneRTViewport.tsx +++ b/extensions/cornerstone-dicom-rt/src/viewports/OHIFCornerstoneRTViewport.tsx @@ -116,7 +116,10 @@ function OHIFCornerstoneRTViewport(props) { orientation: viewportOptions.orientation, viewportId: viewportOptions.viewportId, }} - onElementEnabled={onElementEnabled} + onElementEnabled={evt => { + props.onElementEnabled?.(evt); + onElementEnabled(evt); + }} onElementDisabled={onElementDisabled} > ); diff --git a/extensions/cornerstone-dicom-seg/package.json b/extensions/cornerstone-dicom-seg/package.json index 8c0e004ba..dd88915f0 100644 --- a/extensions/cornerstone-dicom-seg/package.json +++ b/extensions/cornerstone-dicom-seg/package.json @@ -46,9 +46,9 @@ }, "dependencies": { "@babel/runtime": "^7.20.13", - "@cornerstonejs/adapters": "^1.70.5", - "@cornerstonejs/core": "^1.70.5", - "@kitware/vtk.js": "30.3.1", + "@cornerstonejs/adapters": "^1.70.6", + "@cornerstonejs/core": "^1.70.6", + "@kitware/vtk.js": "30.3.3", "react-color": "^2.19.3" } } diff --git a/extensions/cornerstone-dicom-seg/src/commandsModule.ts b/extensions/cornerstone-dicom-seg/src/commandsModule.ts index 5bff8aeef..4a770d7e1 100644 --- a/extensions/cornerstone-dicom-seg/src/commandsModule.ts +++ b/extensions/cornerstone-dicom-seg/src/commandsModule.ts @@ -434,30 +434,6 @@ const commandsModule = ({ }); }); }, - toggleThresholdRangeAndDynamic() { - const toolGroupIds = toolGroupService.getToolGroupIds(); - - if (!toolGroupIds) { - return; - } - - toolGroupIds.forEach(toolGroupId => { - const toolGroup = toolGroupService.getToolGroup(toolGroupId); - const brushInstances = segmentationUtils.getBrushToolInstances(toolGroup.id); - - brushInstances.forEach(({ configuration }) => { - const { activeStrategy, strategySpecificConfiguration } = configuration; - - if (activeStrategy.startsWith('THRESHOLD')) { - const thresholdConfig = strategySpecificConfiguration.THRESHOLD; - - if (thresholdConfig) { - thresholdConfig.isDynamic = !thresholdConfig.isDynamic; - } - } - }); - }); - }, }; const definitions = { @@ -491,9 +467,6 @@ const commandsModule = ({ setThresholdRange: { commandFn: actions.setThresholdRange, }, - toggleThresholdRangeAndDynamic: { - commandFn: actions.toggleThresholdRangeAndDynamic, - }, }; return { diff --git a/extensions/cornerstone-dicom-seg/src/getToolbarModule.ts b/extensions/cornerstone-dicom-seg/src/getToolbarModule.ts index 0a06cf7eb..8bfe0c1e1 100644 --- a/extensions/cornerstone-dicom-seg/src/getToolbarModule.ts +++ b/extensions/cornerstone-dicom-seg/src/getToolbarModule.ts @@ -59,12 +59,8 @@ function getToolNameForButton(button) { const commands = props?.commands || button.commands; const commandsArray = Array.isArray(commands) ? commands : [commands]; const firstCommand = commandsArray[0]; - if (typeof firstCommand === 'string') { - // likely not a cornerstone tool - return null; - } - if ('commandOptions' in firstCommand) { + if (firstCommand?.commandOptions) { return firstCommand.commandOptions.toolName ?? props?.id ?? button.id; } diff --git a/extensions/cornerstone-dicom-seg/src/panels/PanelSegmentation.tsx b/extensions/cornerstone-dicom-seg/src/panels/PanelSegmentation.tsx index c7f0232c9..e640ca309 100644 --- a/extensions/cornerstone-dicom-seg/src/panels/PanelSegmentation.tsx +++ b/extensions/cornerstone-dicom-seg/src/panels/PanelSegmentation.tsx @@ -18,11 +18,13 @@ export default function PanelSegmentation({ extensionManager, configuration, }) { - const { segmentationService, viewportGridService, uiDialogService } = servicesManager.services; + const { segmentationService, viewportGridService, uiDialogService, displaySetService } = + servicesManager.services; const { t } = useTranslation('PanelSegmentation'); const [selectedSegmentationId, setSelectedSegmentationId] = useState(null); + const [addSegmentationClassName, setAddSegmentationClassName] = useState(''); const [segmentationConfiguration, setSegmentationConfiguration] = useState( segmentationService.getConfiguration() ); @@ -52,6 +54,52 @@ export default function PanelSegmentation({ }; }, []); + // temporary measure to not allow add segmentation when the selected viewport + // is stack viewport + useEffect(() => { + const handleActiveViewportChange = viewportId => { + const displaySetUIDs = viewportGridService.getDisplaySetsUIDsForViewport( + viewportId || viewportGridService.getActiveViewportId() + ); + + if (!displaySetUIDs) { + return; + } + + const isReconstructable = + displaySetUIDs?.some(displaySetUID => { + const displaySet = displaySetService.getDisplaySetByUID(displaySetUID); + return displaySet?.isReconstructable; + }) || false; + + if (isReconstructable) { + setAddSegmentationClassName(''); + } else { + setAddSegmentationClassName('ohif-disabled'); + } + }; + + // Handle initial state + handleActiveViewportChange(); + + const changed = viewportGridService.EVENTS.ACTIVE_VIEWPORT_ID_CHANGED; + const ready = viewportGridService.EVENTS.VIEWPORTS_READY; + + const subs = []; + [ready, changed].forEach(evt => { + const { unsubscribe } = viewportGridService.subscribe(evt, ({ viewportId }) => { + handleActiveViewportChange(viewportId); + }); + + subs.push(unsubscribe); + }); + + // Clean up + return () => { + subs.forEach(unsub => unsub()); + }; + }, []); + const getToolGroupIds = segmentationId => { const toolGroupIds = segmentationService.getToolGroupIdsWithSegmentation(segmentationId); @@ -152,6 +200,7 @@ export default function PanelSegmentation({ segmentationService.removeSegment(segmentationId, segmentIndex); }; + // segment hide const onToggleSegmentVisibility = (segmentationId, segmentIndex) => { const segmentation = segmentationService.getSegmentation(segmentationId); const segmentInfo = segmentation.segments[segmentIndex]; @@ -257,6 +306,7 @@ export default function PanelSegmentation({ disableEditing={configuration.disableEditing} activeSegmentationId={selectedSegmentationId || ''} onSegmentationAdd={onSegmentationAddWrapper} + addSegmentationClassName={addSegmentationClassName} showAddSegment={allowAddSegment} onSegmentationClick={onSegmentationClick} onSegmentationDelete={onSegmentationDelete} diff --git a/extensions/cornerstone-dicom-seg/src/viewports/OHIFCornerstoneSEGViewport.tsx b/extensions/cornerstone-dicom-seg/src/viewports/OHIFCornerstoneSEGViewport.tsx index d14e720de..894a4c407 100644 --- a/extensions/cornerstone-dicom-seg/src/viewports/OHIFCornerstoneSEGViewport.tsx +++ b/extensions/cornerstone-dicom-seg/src/viewports/OHIFCornerstoneSEGViewport.tsx @@ -112,7 +112,10 @@ function OHIFCornerstoneSEGViewport(props) { orientation: viewportOptions.orientation, viewportId: viewportOptions.viewportId, }} - onElementEnabled={onElementEnabled} + onElementEnabled={evt => { + props.onElementEnabled?.(evt); + onElementEnabled(evt); + }} onElementDisabled={onElementDisabled} > ); diff --git a/extensions/cornerstone-dicom-sr/package.json b/extensions/cornerstone-dicom-sr/package.json index 120ce6049..2b4a1ec11 100644 --- a/extensions/cornerstone-dicom-sr/package.json +++ b/extensions/cornerstone-dicom-sr/package.json @@ -46,9 +46,9 @@ }, "dependencies": { "@babel/runtime": "^7.20.13", - "@cornerstonejs/adapters": "^1.70.5", - "@cornerstonejs/core": "^1.70.5", - "@cornerstonejs/tools": "^1.70.5", + "@cornerstonejs/adapters": "^1.70.6", + "@cornerstonejs/core": "^1.70.6", + "@cornerstonejs/tools": "^1.70.6", "classnames": "^2.3.2" } } diff --git a/extensions/cornerstone-dicom-sr/src/tools/DICOMSRDisplayTool.ts b/extensions/cornerstone-dicom-sr/src/tools/DICOMSRDisplayTool.ts index 278eed828..eaf3bf6ea 100644 --- a/extensions/cornerstone-dicom-sr/src/tools/DICOMSRDisplayTool.ts +++ b/extensions/cornerstone-dicom-sr/src/tools/DICOMSRDisplayTool.ts @@ -65,7 +65,7 @@ export default class DICOMSRDisplayTool extends AnnotationTool { // Filter toolData to only render the data for the active SR. const filteredAnnotations = annotations.filter(annotation => - trackingUniqueIdentifiers.includes(annotation.data?.cachedStats?.TrackingUniqueIdentifier) + trackingUniqueIdentifiers.includes(annotation.data?.TrackingUniqueIdentifier) ); if (!viewport._actors?.size) { @@ -82,8 +82,7 @@ export default class DICOMSRDisplayTool extends AnnotationTool { for (let i = 0; i < filteredAnnotations.length; i++) { const annotation = filteredAnnotations[i]; const annotationUID = annotation.annotationUID; - const { renderableData } = annotation.data.cachedStats; - const { cachedStats } = annotation.data; + const { renderableData, TrackingUniqueIdentifier } = annotation.data; const { referencedImageId } = annotation.metadata; styleSpecifier.annotationUID = annotationUID; @@ -95,7 +94,7 @@ export default class DICOMSRDisplayTool extends AnnotationTool { const lineWidth = this.getStyle('lineWidth', styleSpecifier, annotation); const lineDash = this.getStyle('lineDash', styleSpecifier, annotation); const color = - cachedStats.TrackingUniqueIdentifier === activeTrackingUniqueIdentifier + TrackingUniqueIdentifier === activeTrackingUniqueIdentifier ? 'rgb(0, 255, 0)' : this.getStyle('color', styleSpecifier, annotation); diff --git a/extensions/cornerstone-dicom-sr/src/utils/addDICOMSRDisplayAnnotation.ts b/extensions/cornerstone-dicom-sr/src/utils/addDICOMSRDisplayAnnotation.ts index fc0eda76c..585a9183a 100644 --- a/extensions/cornerstone-dicom-sr/src/utils/addDICOMSRDisplayAnnotation.ts +++ b/extensions/cornerstone-dicom-sr/src/utils/addDICOMSRDisplayAnnotation.ts @@ -51,10 +51,9 @@ export default function addDICOMSRDisplayAnnotation(measurement, imageId, frameN handles: { textBox: measurement.textBox ?? {}, }, - cachedStats: { - TrackingUniqueIdentifier: measurementData.TrackingUniqueIdentifier, - renderableData: measurementData.renderableData, - }, + cachedStats: {}, + TrackingUniqueIdentifier: measurementData.TrackingUniqueIdentifier, + renderableData: measurementData.renderableData, frameNumber, }, }; diff --git a/extensions/cornerstone-dicom-sr/src/viewports/OHIFCornerstoneSRViewport.tsx b/extensions/cornerstone-dicom-sr/src/viewports/OHIFCornerstoneSRViewport.tsx index a725d6c50..6158df331 100644 --- a/extensions/cornerstone-dicom-sr/src/viewports/OHIFCornerstoneSRViewport.tsx +++ b/extensions/cornerstone-dicom-sr/src/viewports/OHIFCornerstoneSRViewport.tsx @@ -8,6 +8,7 @@ import { setTrackingUniqueIdentifiersForElement } from '../tools/modules/dicomSR import { Icon, Tooltip, useViewportGrid, ViewportActionArrows } from '@ohif/ui'; import hydrateStructuredReport from '../utils/hydrateStructuredReport'; import { useAppConfig } from '@state'; +import createReferencedImageDisplaySet from '../utils/createReferencedImageDisplaySet'; const MEASUREMENT_TRACKING_EXTENSION_ID = '@ohif/extension-measurement-tracking'; @@ -203,7 +204,10 @@ function OHIFCornerstoneSRViewport(props) { // The positionIds for the viewport aren't meaningful for the child display sets positionIds: null, }} - onElementEnabled={onElementEnabled} + onElementEnabled={evt => { + props.onElementEnabled?.(evt); + onElementEnabled(evt); + }} initialImageIndex={initialImageIndex} isJumpToMeasurementDisabled={true} > @@ -378,6 +382,10 @@ async function _getViewportReferencedDisplaySetData( measurementSelected, displaySetService ) { + const { measurements } = displaySet; + const measurement = measurements[measurementSelected]; + + const { displaySetInstanceUID } = measurement; if (!displaySet.keyImageDisplaySet) { // Create a new display set, and preserve a reference to it here, // so that it can be re-displayed and shown inside the SR viewport. diff --git a/extensions/cornerstone-dynamic-volume/package.json b/extensions/cornerstone-dynamic-volume/package.json index 337f58e67..044a3923b 100644 --- a/extensions/cornerstone-dynamic-volume/package.json +++ b/extensions/cornerstone-dynamic-volume/package.json @@ -42,9 +42,9 @@ }, "dependencies": { "@babel/runtime": "^7.20.13", - "@cornerstonejs/core": "^1.70.5", - "@cornerstonejs/streaming-image-volume-loader": "^1.70.5", - "@cornerstonejs/tools": "^1.70.5", + "@cornerstonejs/core": "^1.70.6", + "@cornerstonejs/streaming-image-volume-loader": "^1.70.6", + "@cornerstonejs/tools": "^1.70.6", "classnames": "^2.3.2" } } diff --git a/extensions/cornerstone-dynamic-volume/src/panels/DynamicVolumeControls.tsx b/extensions/cornerstone-dynamic-volume/src/panels/DynamicVolumeControls.tsx index b780669f9..143b55620 100644 --- a/extensions/cornerstone-dynamic-volume/src/panels/DynamicVolumeControls.tsx +++ b/extensions/cornerstone-dynamic-volume/src/panels/DynamicVolumeControls.tsx @@ -88,7 +88,7 @@ const DynamicVolumeControls = ({ className="w-1/2" onClick={() => { setComputedView(false); - onDynamicClick(); + onDynamicClick?.(); }} > 4D diff --git a/extensions/cornerstone-dynamic-volume/src/panels/PanelGenerateImage.tsx b/extensions/cornerstone-dynamic-volume/src/panels/PanelGenerateImage.tsx index f11e6838a..9f8d821fd 100644 --- a/extensions/cornerstone-dynamic-volume/src/panels/PanelGenerateImage.tsx +++ b/extensions/cornerstone-dynamic-volume/src/panels/PanelGenerateImage.tsx @@ -202,7 +202,7 @@ export default function PanelGenerateImage({ servicesManager, commandsManager }) } const { element } = viewportInfo; - cineService.playClip(element, { framesPerSecond: frameRate }); + cineService.playClip(element, { framesPerSecond: frameRate, viewportId: activeViewportId }); }; const handleStop = () => { diff --git a/extensions/cornerstone/package.json b/extensions/cornerstone/package.json index b9f01bf73..1332c6206 100644 --- a/extensions/cornerstone/package.json +++ b/extensions/cornerstone/package.json @@ -38,7 +38,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.70.5", + "@cornerstonejs/dicom-image-loader": "^1.70.6", "@icr/polyseg-wasm": "^0.4.0", "@ohif/core": "3.8.0-beta.80", "@ohif/ui": "3.8.0-beta.80", @@ -55,12 +55,12 @@ }, "dependencies": { "@babel/runtime": "^7.20.13", - "@cornerstonejs/adapters": "^1.70.5", - "@cornerstonejs/core": "^1.70.5", - "@cornerstonejs/streaming-image-volume-loader": "^1.70.5", - "@cornerstonejs/tools": "^1.70.5", + "@cornerstonejs/adapters": "^1.70.6", + "@cornerstonejs/core": "^1.70.6", + "@cornerstonejs/streaming-image-volume-loader": "^1.70.6", + "@cornerstonejs/tools": "^1.70.6", "@icr/polyseg-wasm": "^0.4.0", - "@kitware/vtk.js": "30.3.1", + "@kitware/vtk.js": "30.3.3", "html2canvas": "^1.4.1", "lodash.debounce": "4.0.8", "lodash.merge": "^4.6.2", diff --git a/extensions/cornerstone/src/Viewport/OHIFCornerstoneViewport.tsx b/extensions/cornerstone/src/Viewport/OHIFCornerstoneViewport.tsx index 12577147c..50dfd8c49 100644 --- a/extensions/cornerstone/src/Viewport/OHIFCornerstoneViewport.tsx +++ b/extensions/cornerstone/src/Viewport/OHIFCornerstoneViewport.tsx @@ -114,10 +114,21 @@ const OHIFCornerstoneViewport = React.memo(props => { // of the imageData in the OHIFCornerstoneViewport. This prop is used // to set the initial state of the viewport's first image to render initialImageIndex, + // if the viewport is part of a hanging protocol layout + // we should not really rely on the old synchronizers and + // you see below we only rehydrate the synchronizers if the viewport + // is not part of the hanging protocol layout. HPs should + // define their own synchronizers. Since the synchronizers are + // viewportId dependent and + isHangingProtocolLayout, } = props; const viewportId = viewportOptions.viewportId; + if (!viewportId) { + throw new Error('Viewport ID is required'); + } + // Since we only have support for dynamic data in volume viewports, we should // handle this case here and set the viewportType to volume if any of the // displaySets are dynamic volumes @@ -194,7 +205,7 @@ const OHIFCornerstoneViewport = React.memo(props => { const synchronizersStore = stateSyncService.getState().synchronizersStore; - if (synchronizersStore?.[viewportId]?.length) { + if (synchronizersStore?.[viewportId]?.length && !isHangingProtocolLayout) { // If the viewport used to have a synchronizer, re apply it again _rehydrateSynchronizers(synchronizersStore, viewportId, syncGroupService); } diff --git a/extensions/cornerstone/src/commandsModule.ts b/extensions/cornerstone/src/commandsModule.ts index 0223afa05..f243a0ec7 100644 --- a/extensions/cornerstone/src/commandsModule.ts +++ b/extensions/cornerstone/src/commandsModule.ts @@ -51,6 +51,12 @@ function commandsModule({ function _getActiveViewportEnabledElement() { return getActiveViewportEnabledElement(viewportGridService); } + + function _getActiveViewportToolGroupId() { + const viewport = _getActiveViewportEnabledElement(); + return toolGroupService.getToolGroupForViewport(viewport.id); + } + const actions = { /** * Generates the selector props for the context menu, specific to @@ -300,42 +306,45 @@ function commandsModule({ const renderingEngine = cornerstoneViewportService.getRenderingEngine(); renderingEngine.render(); }, - toggleEnabledDisabledToolbar({ value, itemId, toolGroupIds = [] }) { + toggleEnabledDisabledToolbar({ value, itemId, toolGroupId }) { const toolName = itemId || value; - toolGroupIds = toolGroupIds.length ? toolGroupIds : toolGroupService.getToolGroupIds(); - toolGroupIds.forEach(toolGroupId => { - const toolGroup = toolGroupService.getToolGroup(toolGroupId); - if (!toolGroup || !toolGroup.hasTool(toolName)) { - return; - } + toolGroupId = toolGroupId ?? _getActiveViewportToolGroupId(); - const toolIsEnabled = toolGroup.getToolOptions(toolName).mode === Enums.ToolModes.Enabled; + const toolGroup = toolGroupService.getToolGroup(toolGroupId); + if (!toolGroup || !toolGroup.hasTool(toolName)) { + return; + } - toolIsEnabled ? toolGroup.setToolDisabled(toolName) : toolGroup.setToolEnabled(toolName); - }); + const toolIsEnabled = toolGroup.getToolOptions(toolName).mode === Enums.ToolModes.Enabled; + + toolIsEnabled ? toolGroup.setToolDisabled(toolName) : toolGroup.setToolEnabled(toolName); }, - toggleActiveDisabledToolbar({ value, itemId, toolGroupIds = [] }) { + toggleActiveDisabledToolbar({ value, itemId, toolGroupId }) { const toolName = itemId || value; - toolGroupIds = toolGroupIds.length ? toolGroupIds : toolGroupService.getToolGroupIds(); - toolGroupIds.forEach(toolGroupId => { - const toolGroup = toolGroupService.getToolGroup(toolGroupId); - if (!toolGroup || !toolGroup.hasTool(toolName)) { - return; - } + toolGroupId = toolGroupId ?? _getActiveViewportToolGroupId(); + const toolGroup = toolGroupService.getToolGroup(toolGroupId); + if (!toolGroup || !toolGroup.hasTool(toolName)) { + return; + } - const toolIsActive = toolGroup.getToolOptions(toolName).mode === Enums.ToolModes.Active; + const toolIsActive = [ + Enums.ToolModes.Active, + Enums.ToolModes.Enabled, + Enums.ToolModes.Passive, + ].includes(toolGroup.getToolOptions(toolName).mode); - toolIsActive - ? toolGroup.setToolDisabled(toolName) - : actions.setToolActive({ toolName, toolGroupId }); + toolIsActive + ? toolGroup.setToolDisabled(toolName) + : actions.setToolActive({ toolName, toolGroupId }); - // we should set the previously active tool to active after we set the - // current tool disabled - if (toolIsActive) { - const prevToolName = toolGroup.getPrevActivePrimaryToolName(); + // we should set the previously active tool to active after we set the + // current tool disabled + if (toolIsActive) { + const prevToolName = toolGroup.getPrevActivePrimaryToolName(); + if (prevToolName !== toolName) { actions.setToolActive({ toolName: prevToolName, toolGroupId }); } - }); + } }, setToolActiveToolbar: ({ value, itemId, toolGroupIds = [] }) => { // Sometimes it is passed as value (tools with options), sometimes as itemId (toolbar buttons) @@ -441,11 +450,9 @@ function commandsModule({ const { viewport } = enabledElement; - if (viewport instanceof StackViewport) { - const { flipHorizontal } = viewport.getCamera(); - viewport.setCamera({ flipHorizontal: !flipHorizontal }); - viewport.render(); - } + const { flipHorizontal } = viewport.getCamera(); + viewport.setCamera({ flipHorizontal: !flipHorizontal }); + viewport.render(); }, flipViewportVertical: () => { const enabledElement = _getActiveViewportEnabledElement(); @@ -456,11 +463,9 @@ function commandsModule({ const { viewport } = enabledElement; - if (viewport instanceof StackViewport) { - const { flipVertical } = viewport.getCamera(); - viewport.setCamera({ flipVertical: !flipVertical }); - viewport.render(); - } + const { flipVertical } = viewport.getCamera(); + viewport.setCamera({ flipVertical: !flipVertical }); + viewport.render(); }, invertViewport: ({ element }) => { let enabledElement; @@ -819,7 +824,7 @@ function commandsModule({ } crosshairInstances.forEach(ins => { - ins.resetCrosshairs(); + ins?.resetCrosshairs(); }); }, }; diff --git a/extensions/cornerstone/src/components/CinePlayer/CinePlayer.tsx b/extensions/cornerstone/src/components/CinePlayer/CinePlayer.tsx index 28414877b..795ec5529 100644 --- a/extensions/cornerstone/src/components/CinePlayer/CinePlayer.tsx +++ b/extensions/cornerstone/src/components/CinePlayer/CinePlayer.tsx @@ -21,7 +21,7 @@ function WrappedCinePlayer({ enabledVPElement, viewportId, servicesManager }) { const validFrameRate = Math.max(frameRate, 1); return isPlaying - ? cineService.playClip(enabledVPElement, { framesPerSecond: validFrameRate }) + ? cineService.playClip(enabledVPElement, { framesPerSecond: validFrameRate, viewportId }) : cineService.stopClip(enabledVPElement); }; diff --git a/extensions/cornerstone/src/getToolbarModule.tsx b/extensions/cornerstone/src/getToolbarModule.tsx index 74a116269..2f2de9466 100644 --- a/extensions/cornerstone/src/getToolbarModule.tsx +++ b/extensions/cornerstone/src/getToolbarModule.tsx @@ -108,32 +108,27 @@ export default function getToolbarModule({ commandsManager, servicesManager }) { }; }, }, + { + name: 'evaluate.cornerstoneTool.toggle.ifStrictlyDisabled', + evaluate: ({ viewportId, button, disabledText }) => + _evaluateToggle({ + viewportId, + button, + disabledText, + offModes: [Enums.ToolModes.Disabled], + toolGroupService, + }), + }, { name: 'evaluate.cornerstoneTool.toggle', - evaluate: ({ viewportId, button, disabledText }) => { - const toolGroup = toolGroupService.getToolGroupForViewport(viewportId); - - if (!toolGroup) { - return; - } - const toolName = getToolNameForButton(button); - - if (!toolGroup || !toolGroup.hasTool(toolName)) { - return { - disabled: true, - className: '!text-common-bright ohif-disabled', - disabledText: disabledText ?? 'Not available on the current viewport', - }; - } - - const isOff = [Enums.ToolModes.Disabled, Enums.ToolModes.Passive].includes( - toolGroup.getToolOptions(toolName).mode - ); - - return { - className: getToggledClassName(!isOff), - }; - }, + evaluate: ({ viewportId, button, disabledText }) => + _evaluateToggle({ + viewportId, + button, + disabledText, + offModes: [Enums.ToolModes.Disabled, Enums.ToolModes.Passive], + toolGroupService, + }), }, { name: 'evaluate.cornerstone.synchronizer', @@ -146,7 +141,11 @@ export default function getToolbarModule({ commandsManager, servicesManager }) { }; } - const synchronizerType = button?.commands?.[0]?.commandOptions?.type; + const isArray = Array.isArray(button.commands); + + const synchronizerType = isArray + ? button.commands?.[0].commandOptions.type + : button.commands?.commandOptions.type; synchronizers = syncGroupService.getSynchronizersOfType(synchronizerType); @@ -268,18 +267,38 @@ export default function getToolbarModule({ commandsManager, servicesManager }) { ]; } +function _evaluateToggle({ viewportId, button, disabledText, offModes, toolGroupService }) { + const toolGroup = toolGroupService.getToolGroupForViewport(viewportId); + + if (!toolGroup) { + return; + } + const toolName = getToolNameForButton(button); + + if (!toolGroup.hasTool(toolName)) { + return { + disabled: true, + className: '!text-common-bright ohif-disabled', + disabledText: disabledText ?? 'Not available on the current viewport', + }; + } + + const isOff = offModes.includes(toolGroup.getToolOptions(toolName).mode); + + return { + className: getToggledClassName(!isOff), + }; +} + +// Todo: this is duplicate, we should move it to a shared location function getToolNameForButton(button) { const { props } = button; const commands = props?.commands || button.commands; const commandsArray = Array.isArray(commands) ? commands : [commands]; const firstCommand = commandsArray[0]; - if (typeof firstCommand === 'string') { - // likely not a cornerstone tool - return null; - } - if ('commandOptions' in firstCommand) { + if (firstCommand?.commandOptions) { return firstCommand.commandOptions.toolName ?? props?.id ?? button.id; } diff --git a/extensions/cornerstone/src/index.tsx b/extensions/cornerstone/src/index.tsx index 83e463a2a..a8ef8ac47 100644 --- a/extensions/cornerstone/src/index.tsx +++ b/extensions/cornerstone/src/index.tsx @@ -61,7 +61,8 @@ const cornerstoneExtension: Types.Extensions.Extension = { */ id, - onModeExit: (): void => { + onModeExit: ({ servicesManager }): void => { + const { cineService } = servicesManager.services; // Empty out the image load and retrieval pools to prevent memory leaks // on the mode exits Object.values(cs3DEnums.RequestType).forEach(type => { @@ -69,6 +70,8 @@ const cornerstoneExtension: Types.Extensions.Extension = { imageRetrievalPoolManager.clearRequestStack(type); }); + cineService.setIsCineEnabled(false); + enabledElementReset(); }, diff --git a/extensions/cornerstone/src/init.tsx b/extensions/cornerstone/src/init.tsx index 2282abb5b..b7ec7abde 100644 --- a/extensions/cornerstone/src/init.tsx +++ b/extensions/cornerstone/src/init.tsx @@ -34,6 +34,8 @@ import { CornerstoneServices } from './types'; import initViewTiming from './utils/initViewTiming'; import { colormaps } from './utils/colormaps'; +import { debounce } from 'lodash'; + const { registerColormap } = csUtilities.colormap; // TODO: Cypress tests are currently grabbing this from the window? @@ -291,8 +293,21 @@ export default async function init({ eventTarget.addEventListener(EVENTS.ELEMENT_ENABLED, elementEnabledHandler.bind(null)); eventTarget.addEventListener(EVENTS.ELEMENT_DISABLED, elementDisabledHandler.bind(null)); - colormaps.forEach(registerColormap); + + // Create a debounced function that shows the notification + const debouncedShowNotification = debounce(detail => { + uiNotificationService.show({ + title: detail.type, + message: detail.message, + type: 'error', + }); + }, 300); + + // Event listener + eventTarget.addEventListener(EVENTS.ERROR_EVENT, ({ detail }) => { + debouncedShowNotification(detail); + }); } function CPUModal() { diff --git a/extensions/cornerstone/src/initCineService.ts b/extensions/cornerstone/src/initCineService.ts index bbd04d3df..5e3246135 100644 --- a/extensions/cornerstone/src/initCineService.ts +++ b/extensions/cornerstone/src/initCineService.ts @@ -59,8 +59,8 @@ function initCineService(servicesManager) { return utilities.cine.playClip(element, playClipOptions); }; - const stopClip = element => { - return utilities.cine.stopClip(element); + const stopClip = (element, stopClipOptions) => { + return utilities.cine.stopClip(element, stopClipOptions); }; cineService.setServiceImplementation({ diff --git a/extensions/cornerstone/src/services/CornerstoneCacheService/CornerstoneCacheService.ts b/extensions/cornerstone/src/services/CornerstoneCacheService/CornerstoneCacheService.ts index 63d66fc55..a8d40b3d0 100644 --- a/extensions/cornerstone/src/services/CornerstoneCacheService/CornerstoneCacheService.ts +++ b/extensions/cornerstone/src/services/CornerstoneCacheService/CornerstoneCacheService.ts @@ -45,7 +45,11 @@ class CornerstoneCacheService { // as a reference volume, if so, we should hang a volume viewport // instead of a stack viewport if (this._shouldRenderSegmentation(displaySets)) { - viewportType = 'volume'; + // if the viewport type is volume 3D, we should let it be as it is + // Todo: in future here we should kick start the conversion of the + // segmentation to closed surface + viewportType = + viewportType === Enums.ViewportType.VOLUME_3D ? Enums.ViewportType.VOLUME_3D : 'volume'; // update viewportOptions to reflect the new viewport type viewportOptions.viewportType = viewportType; diff --git a/extensions/cornerstone/src/services/ViewportService/CornerstoneViewportService.ts b/extensions/cornerstone/src/services/ViewportService/CornerstoneViewportService.ts index 319884d62..3f63bcdcd 100644 --- a/extensions/cornerstone/src/services/ViewportService/CornerstoneViewportService.ts +++ b/extensions/cornerstone/src/services/ViewportService/CornerstoneViewportService.ts @@ -183,7 +183,7 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi const { lutPresentation, positionPresentation } = presentations; if (lutPresentation) { const { presentation } = lutPresentation; - if (viewport instanceof VolumeViewport) { + if (viewport instanceof BaseVolumeViewport) { if (presentation instanceof Map) { presentation.forEach((properties, volumeId) => { viewport.setProperties(properties, volumeId); diff --git a/extensions/cornerstone/src/utils/CornerstoneViewportDownloadForm.tsx b/extensions/cornerstone/src/utils/CornerstoneViewportDownloadForm.tsx index 68a6ada3d..f4eaa13e8 100644 --- a/extensions/cornerstone/src/utils/CornerstoneViewportDownloadForm.tsx +++ b/extensions/cornerstone/src/utils/CornerstoneViewportDownloadForm.tsx @@ -27,7 +27,11 @@ const CornerstoneViewportDownloadForm = ({ const activeViewportElement = enabledElement?.element; const activeViewportEnabledElement = getEnabledElement(activeViewportElement); - const { viewportId: activeViewportId, renderingEngineId } = activeViewportEnabledElement; + const { + viewportId: activeViewportId, + renderingEngineId, + viewport: activeViewport, + } = activeViewportEnabledElement; const toolGroup = ToolGroupManager.getToolGroupForViewport(activeViewportId, renderingEngineId); @@ -93,7 +97,7 @@ const CornerstoneViewportDownloadForm = ({ renderingEngine.resize(); // Trigger the render on the viewport to update the on screen - downloadViewport.resetCamera(); + // downloadViewport.resetCamera(); downloadViewport.render(); downloadViewportElement.addEventListener( @@ -120,6 +124,12 @@ const CornerstoneViewportDownloadForm = ({ resolve({ dataUrl, width: newWidth, height: newHeight }); downloadViewportElement.removeEventListener(Enums.Events.IMAGE_RENDERED, updateViewport); + + // for some reason we need a reset camera here, and I don't know why + downloadViewport.resetCamera(); + const presentation = activeViewport.getViewPresentation(); + downloadViewport.setView(activeViewport.getViewReference(), presentation); + downloadViewport.render(); } ); }); @@ -161,7 +171,6 @@ const CornerstoneViewportDownloadForm = ({ downloadViewport.addActor(actor); }); - downloadViewport.setCamera(viewport.getCamera()); downloadViewport.render(); const newWidth = Math.min(width || image.width, MAX_TEXTURE_SIZE); diff --git a/extensions/cornerstone/src/utils/interleaveCenterLoader.ts b/extensions/cornerstone/src/utils/interleaveCenterLoader.ts index d8f64b5d8..16ed7eeeb 100644 --- a/extensions/cornerstone/src/utils/interleaveCenterLoader.ts +++ b/extensions/cornerstone/src/utils/interleaveCenterLoader.ts @@ -51,20 +51,27 @@ export default function interleaveCenterLoader({ * listen to it and as the other viewports are created we can set the volumes for them * since volumes are already started loading. */ - if (matchDetails.size !== viewportIdVolumeInputArrayMap.size) { + const uniqueViewportVolumeDisplaySetUIDs = new Set(); + viewportIdVolumeInputArrayMap.forEach((volumeInputArray, viewportId) => { + volumeInputArray.forEach(volumeInput => { + const { volumeId } = volumeInput; + uniqueViewportVolumeDisplaySetUIDs.add(volumeId); + }); + }); + + const uniqueMatchedDisplaySetUIDs = new Set(); + + matchDetails.forEach(matchDetail => { + const { displaySetsInfo } = matchDetail; + displaySetsInfo.forEach(({ displaySetInstanceUID }) => { + uniqueMatchedDisplaySetUIDs.add(displaySetInstanceUID); + }); + }); + + if (uniqueViewportVolumeDisplaySetUIDs.size !== uniqueMatchedDisplaySetUIDs.size) { return; } - // Check if all the matched volumes are loaded - for (const [_, details] of displaySetsMatchDetails.entries()) { - const { SeriesInstanceUID } = details; - - // HangingProtocol has matched, but don't have all the volumes created yet, so return - if (!Array.from(volumeIdMapsToLoad.values()).includes(SeriesInstanceUID)) { - return; - } - } - const volumeIds = Array.from(volumeIdMapsToLoad.keys()).slice(); // get volumes from cache const volumes = volumeIds.map(volumeId => { diff --git a/extensions/cornerstone/src/utils/interleaveTopToBottom.ts b/extensions/cornerstone/src/utils/interleaveTopToBottom.ts index a0d1e4fb6..fc5447a42 100644 --- a/extensions/cornerstone/src/utils/interleaveTopToBottom.ts +++ b/extensions/cornerstone/src/utils/interleaveTopToBottom.ts @@ -75,23 +75,27 @@ export default function interleaveTopToBottom({ * listen to it and as the other viewports are created we can set the volumes for them * since volumes are already started loading. */ - if (filteredMatchDetails.length !== viewportIdVolumeInputArrayMap.size) { + const uniqueViewportVolumeDisplaySetUIDs = new Set(); + viewportIdVolumeInputArrayMap.forEach((volumeInputArray, viewportId) => { + volumeInputArray.forEach(volumeInput => { + const { volumeId } = volumeInput; + uniqueViewportVolumeDisplaySetUIDs.add(volumeId); + }); + }); + + const uniqueMatchedDisplaySetUIDs = new Set(); + + matchDetails.forEach(matchDetail => { + const { displaySetsInfo } = matchDetail; + displaySetsInfo.forEach(({ displaySetInstanceUID }) => { + uniqueMatchedDisplaySetUIDs.add(displaySetInstanceUID); + }); + }); + + if (uniqueViewportVolumeDisplaySetUIDs.size !== uniqueMatchedDisplaySetUIDs.size) { return; } - // Check if all the matched volumes are loaded - for (const [_, details] of displaySetsMatchDetails.entries()) { - const { SeriesInstanceUID, displaySetInstanceUID } = details; - - // HangingProtocol has matched, but don't have all the volumes created yet, so return - if ( - displaySetsToLoad.has(displaySetInstanceUID) && - !Array.from(volumeIdMapsToLoad.values()).includes(SeriesInstanceUID) - ) { - return; - } - } - const volumeIds = Array.from(volumeIdMapsToLoad.keys()).slice(); // get volumes from cache const volumes = volumeIds.map(volumeId => { diff --git a/extensions/default/src/CustomizableContextMenu/defaultContextMenu.ts b/extensions/default/src/CustomizableContextMenu/defaultContextMenu.ts index 29a760c79..486530a09 100644 --- a/extensions/default/src/CustomizableContextMenu/defaultContextMenu.ts +++ b/extensions/default/src/CustomizableContextMenu/defaultContextMenu.ts @@ -12,6 +12,9 @@ const defaultContextMenu = { commands: [ { commandName: 'deleteMeasurement', + // we only have support for cornerstoneTools context menu since + // they are svg based + context: 'CORNERSTONE', }, ], }, diff --git a/extensions/default/src/Panels/PanelMeasurementTable.tsx b/extensions/default/src/Panels/PanelMeasurementTable.tsx index 57e8decb8..7cb491660 100644 --- a/extensions/default/src/Panels/PanelMeasurementTable.tsx +++ b/extensions/default/src/Panels/PanelMeasurementTable.tsx @@ -227,7 +227,7 @@ export default function PanelMeasurementTable({
{ const canvas = document.createElement('canvas'); - // Note: the default width and height of the canvas is 300x150 - // but we need to set the width and height to the same number since - // the thumbnails are usually square and we want to maintain the aspect ratio - canvas.width = 128 / window.devicePixelRatio; - canvas.height = 128 / window.devicePixelRatio; cornerstone.utilities - .loadImageToCanvas({ canvas, imageId }) + .loadImageToCanvas({ canvas, imageId, thumbnail: true }) .then(imageId => { resolve(canvas.toDataURL()); }) diff --git a/extensions/default/src/SOPClassHandlers/chartSOPClassHandler.ts b/extensions/default/src/SOPClassHandlers/chartSOPClassHandler.ts index 7b5a44953..58f561e99 100644 --- a/extensions/default/src/SOPClassHandlers/chartSOPClassHandler.ts +++ b/extensions/default/src/SOPClassHandlers/chartSOPClassHandler.ts @@ -68,7 +68,6 @@ function getSopClassUids(instances) { } function _getDisplaySetsFromSeries(instances) { - debugger; // If the series has no instances, stop here if (!instances || !instances.length) { throw new Error('No instances were provided'); diff --git a/extensions/default/src/Toolbar/ToolbarLayoutSelector.tsx b/extensions/default/src/Toolbar/ToolbarLayoutSelector.tsx index f286ce305..e39066d21 100644 --- a/extensions/default/src/Toolbar/ToolbarLayoutSelector.tsx +++ b/extensions/default/src/Toolbar/ToolbarLayoutSelector.tsx @@ -34,19 +34,47 @@ const defaultCommonPresets = [ }, ]; -const generateAdvancedPresets = hangingProtocolService => { +const _areSelectorsValid = (hp, displaySets, hangingProtocolService) => { + if (!hp.displaySetSelectors || Object.values(hp.displaySetSelectors).length === 0) { + return true; + } + + return hangingProtocolService.areRequiredSelectorsValid( + Object.values(hp.displaySetSelectors), + displaySets[0] + ); +}; + +const generateAdvancedPresets = ({ servicesManager }) => { + const { hangingProtocolService, viewportGridService, displaySetService } = + servicesManager.services; + const hangingProtocols = Array.from(hangingProtocolService.protocols.values()); + + const viewportId = viewportGridService.getActiveViewportId(); + + if (!viewportId) { + return []; + } + const displaySetInsaneUIDs = viewportGridService.getDisplaySetsUIDsForViewport(viewportId); + + const displaySets = displaySetInsaneUIDs.map(uid => displaySetService.getDisplaySetByUID(uid)); + return hangingProtocols .map(hp => { if (!hp.isPreset) { return null; } + + const areValid = _areSelectorsValid(hp, displaySets, hangingProtocolService); + return { icon: hp.icon, title: hp.name, commandOptions: { protocolId: hp.id, }, + disabled: !areValid, }; }) .filter(preset => preset !== null); @@ -100,10 +128,10 @@ function LayoutSelector({ }) { const [isOpen, setIsOpen] = useState(false); - const { customizationService, hangingProtocolService } = servicesManager.services; + const { customizationService } = servicesManager.services; const commonPresets = customizationService.get('commonPresets') || defaultCommonPresets; const advancedPresets = - customizationService.get('advancedPresets') || generateAdvancedPresets(hangingProtocolService); + customizationService.get('advancedPresets') || generateAdvancedPresets({ servicesManager }); const closeOnOutsideClick = () => { if (isOpen) { @@ -161,6 +189,7 @@ function LayoutSelector({ classNames="hover:bg-primary-dark group flex gap-2 p-1 cursor-pointer" icon={preset.icon} title={preset.title} + disabled={preset.disabled} commandOptions={preset.commandOptions} onSelection={onSelectionPreset} /> diff --git a/extensions/default/src/commandsModule.ts b/extensions/default/src/commandsModule.ts index 04fd54029..7e498726e 100644 --- a/extensions/default/src/commandsModule.ts +++ b/extensions/default/src/commandsModule.ts @@ -271,7 +271,7 @@ const commandsModule = ({ /** * Changes the viewport grid layout in terms of the MxN layout. */ - setViewportGridLayout: ({ numRows, numCols }) => { + setViewportGridLayout: ({ numRows, numCols, isHangingProtocolLayout = false }) => { const { protocol } = hangingProtocolService.getActiveProtocol(); const onLayoutChange = protocol.callbacks?.onLayoutChange; if (commandsManager.run(onLayoutChange, { numRows, numCols }) === false) { @@ -293,6 +293,7 @@ const commandsModule = ({ numRows, numCols, findOrCreateViewport, + isHangingProtocolLayout, }); stateSyncService.store(stateReduce); }; @@ -366,6 +367,7 @@ const commandsModule = ({ activeViewportId: viewportIdToUpdate, layoutOptions, findOrCreateViewport, + isHangingProtocolLayout: true, }); } else { // We are not in one-up, so toggle to one up. @@ -390,6 +392,7 @@ const commandsModule = ({ numRows: 1, numCols: 1, findOrCreateViewport, + isHangingProtocolLayout: true, }); // Subscribe to ANY (i.e. manual and hanging protocol) layout changes so that diff --git a/extensions/measurement-tracking/package.json b/extensions/measurement-tracking/package.json index 75b89eea2..794487b82 100644 --- a/extensions/measurement-tracking/package.json +++ b/extensions/measurement-tracking/package.json @@ -32,8 +32,8 @@ "start": "yarn run dev" }, "peerDependencies": { - "@cornerstonejs/core": "^1.70.5", - "@cornerstonejs/tools": "^1.70.5", + "@cornerstonejs/core": "^1.70.6", + "@cornerstonejs/tools": "^1.70.6", "@ohif/core": "3.8.0-beta.80", "@ohif/extension-cornerstone-dicom-sr": "3.8.0-beta.80", "@ohif/ui": "3.8.0-beta.80", diff --git a/extensions/measurement-tracking/src/panels/PanelStudyBrowserTracking/getImageSrcFromImageId.js b/extensions/measurement-tracking/src/panels/PanelStudyBrowserTracking/getImageSrcFromImageId.js index 1fdf18497..8b5f74d84 100644 --- a/extensions/measurement-tracking/src/panels/PanelStudyBrowserTracking/getImageSrcFromImageId.js +++ b/extensions/measurement-tracking/src/panels/PanelStudyBrowserTracking/getImageSrcFromImageId.js @@ -5,14 +5,8 @@ function getImageSrcFromImageId(cornerstone, imageId) { return new Promise((resolve, reject) => { const canvas = document.createElement('canvas'); - // Note: the default width and height of the canvas is 300x150 - // but we need to set the width and height to the same number since - // the thumbnails are usually square and we want to maintain the aspect ratio - canvas.width = 128 / window.devicePixelRatio; - canvas.height = 128 / window.devicePixelRatio; - cornerstone.utilities - .loadImageToCanvas({ canvas, imageId }) + .loadImageToCanvas({ canvas, imageId, thumbnail: true }) .then(imageId => { resolve(canvas.toDataURL()); }) diff --git a/extensions/measurement-tracking/src/viewports/TrackedCornerstoneViewport.tsx b/extensions/measurement-tracking/src/viewports/TrackedCornerstoneViewport.tsx index ce99022d2..94ca843bb 100644 --- a/extensions/measurement-tracking/src/viewports/TrackedCornerstoneViewport.tsx +++ b/extensions/measurement-tracking/src/viewports/TrackedCornerstoneViewport.tsx @@ -219,7 +219,10 @@ function TrackedCornerstoneViewport(props) { return ( { + props.onElementEnabled?.(evt); + onElementEnabled(evt); + }} onElementDisabled={onElementDisabled} /> ); diff --git a/extensions/tmtv/src/Panels/PanelROIThresholdSegmentation/PanelROIThresholdExport.tsx b/extensions/tmtv/src/Panels/PanelROIThresholdSegmentation/PanelROIThresholdExport.tsx index 181240e6c..05fa48cb1 100644 --- a/extensions/tmtv/src/Panels/PanelROIThresholdSegmentation/PanelROIThresholdExport.tsx +++ b/extensions/tmtv/src/Panels/PanelROIThresholdSegmentation/PanelROIThresholdExport.tsx @@ -47,8 +47,8 @@ export default function PanelRoiThresholdSegmentation({ servicesManager, command if (Number.isNaN(suvPeak)) { uiNotificationService.show({ - title: 'Unable to calculate SUV Peak', - message: 'The resulting threshold is not big enough.', + title: 'SUV Peak', + message: 'Segmented volume does not allow SUV Peak calculation', type: 'warning', }); } diff --git a/modes/basic-test-mode/src/initToolGroups.ts b/modes/basic-test-mode/src/initToolGroups.ts index 5feb3214b..db956dd55 100644 --- a/modes/basic-test-mode/src/initToolGroups.ts +++ b/modes/basic-test-mode/src/initToolGroups.ts @@ -50,7 +50,7 @@ function initDefaultToolGroup(extensionManager, toolGroupService, commandsManage { toolName: toolNames.Angle }, { toolName: toolNames.Magnify }, { toolName: toolNames.SegmentationDisplay }, - { toolName: toolNames.AdvancedMagnify }, + { toolName: toolNames.UltrasoundDirectional }, { toolName: toolNames.PlanarFreehandROI }, { toolName: toolNames.SplineROI }, @@ -59,7 +59,7 @@ function initDefaultToolGroup(extensionManager, toolGroupService, commandsManage // enabled enabled: [{ toolName: toolNames.ImageOverlayViewer }], // disabled - disabled: [{ toolName: toolNames.ReferenceLines }], + disabled: [{ toolName: toolNames.ReferenceLines }, { toolName: toolNames.AdvancedMagnify }], }; toolGroupService.createToolGroupAndAddTools(toolGroupId, tools); diff --git a/modes/basic-test-mode/src/moreTools.ts b/modes/basic-test-mode/src/moreTools.ts index 5708c2a17..d1f34ec09 100644 --- a/modes/basic-test-mode/src/moreTools.ts +++ b/modes/basic-test-mode/src/moreTools.ts @@ -11,13 +11,6 @@ const ReferenceLinesListeners: RunCommand = [ }, ]; -export const toggleEnabledDisabledToolbar = { - commandName: 'toggleEnabledDisabledToolbar', - commandOptions: { - toolGroupIds: ['default', 'mpr', 'SRToolGroup', 'volume3d'], - }, -}; - const moreTools = [ { id: 'MoreTools', @@ -87,7 +80,7 @@ const moreTools = [ icon: 'tool-referenceLines', label: 'Reference Lines', tooltip: 'Show Reference Lines', - commands: toggleEnabledDisabledToolbar, + commands: 'toggleEnabledDisabledToolbar', listeners: { [ViewportGridService.EVENTS.ACTIVE_VIEWPORT_ID_CHANGED]: ReferenceLinesListeners, [ViewportGridService.EVENTS.VIEWPORTS_READY]: ReferenceLinesListeners, @@ -99,7 +92,7 @@ const moreTools = [ icon: 'toggle-dicom-overlay', label: 'Image Overlay', tooltip: 'Toggle Image Overlay', - commands: toggleEnabledDisabledToolbar, + commands: 'toggleEnabledDisabledToolbar', evaluate: 'evaluate.cornerstoneTool.toggle', }), createButton({ @@ -178,8 +171,8 @@ const moreTools = [ icon: 'icon-tool-loupe', label: 'Loupe', tooltip: 'Loupe', - commands: setToolActiveToolbar, - evaluate: 'evaluate.cornerstoneTool', + commands: 'toggleActiveDisabledToolbar', + evaluate: 'evaluate.cornerstoneTool.toggle.ifStrictlyDisabled', }), createButton({ id: 'UltrasoundDirectionalTool', diff --git a/modes/longitudinal/src/initToolGroups.js b/modes/longitudinal/src/initToolGroups.js index 329d047b5..983f1f56a 100644 --- a/modes/longitudinal/src/initToolGroups.js +++ b/modes/longitudinal/src/initToolGroups.js @@ -65,19 +65,18 @@ function initDefaultToolGroup( { toolName: toolNames.Magnify }, { toolName: toolNames.SegmentationDisplay }, { toolName: toolNames.CalibrationLine }, - { - toolName: toolNames.AdvancedMagnify, - configuration: { - disableOnPassive: true, - }, - }, + { toolName: toolNames.UltrasoundDirectional }, { toolName: toolNames.PlanarFreehandROI }, { toolName: toolNames.SplineROI }, { toolName: toolNames.LivewireContour }, ], - // enabled enabled: [{ toolName: toolNames.ImageOverlayViewer }, { toolName: toolNames.ReferenceLines }], + disabled: [ + { + toolName: toolNames.AdvancedMagnify, + }, + ], }; toolGroupService.createToolGroupAndAddTools(toolGroupId, tools); @@ -224,11 +223,11 @@ function initMPRToolGroup(extensionManager, toolGroupService, commandsManager, m }, }, }, + { + toolName: toolNames.AdvancedMagnify, + }, { toolName: toolNames.ReferenceLines }, ], - - // enabled - // disabled }; toolGroupService.createToolGroupAndAddTools('mpr', tools); diff --git a/modes/longitudinal/src/moreTools.ts b/modes/longitudinal/src/moreTools.ts index 70ead4860..101aebf80 100644 --- a/modes/longitudinal/src/moreTools.ts +++ b/modes/longitudinal/src/moreTools.ts @@ -11,20 +11,6 @@ const ReferenceLinesListeners: RunCommand = [ }, ]; -export const toggleEnabledDisabledToolbar = { - commandName: 'toggleEnabledDisabledToolbar', - commandOptions: { - toolGroupIds: ['default', 'mpr', 'SRToolGroup', 'volume3d'], - }, -}; - -export const toggleActiveDisabledToolbar = { - commandName: 'toggleActiveDisabledToolbar', - commandOptions: { - toolGroupIds: ['default', 'mpr', 'SRToolGroup'], - }, -}; - const moreTools = [ { id: 'MoreTools', @@ -94,7 +80,7 @@ const moreTools = [ icon: 'tool-referenceLines', label: 'Reference Lines', tooltip: 'Show Reference Lines', - commands: toggleEnabledDisabledToolbar, + commands: 'toggleEnabledDisabledToolbar', listeners: { [ViewportGridService.EVENTS.ACTIVE_VIEWPORT_ID_CHANGED]: ReferenceLinesListeners, [ViewportGridService.EVENTS.VIEWPORTS_READY]: ReferenceLinesListeners, @@ -106,7 +92,7 @@ const moreTools = [ icon: 'toggle-dicom-overlay', label: 'Image Overlay', tooltip: 'Toggle Image Overlay', - commands: toggleEnabledDisabledToolbar, + commands: 'toggleEnabledDisabledToolbar', evaluate: 'evaluate.cornerstoneTool.toggle', }), createButton({ @@ -177,8 +163,8 @@ const moreTools = [ icon: 'icon-tool-loupe', label: 'Loupe', tooltip: 'Loupe', - commands: toggleActiveDisabledToolbar, - evaluate: 'evaluate.cornerstoneTool.toggle', + commands: 'toggleActiveDisabledToolbar', + evaluate: 'evaluate.cornerstoneTool.toggle.ifStrictlyDisabled', }), createButton({ id: 'UltrasoundDirectionalTool', diff --git a/modes/longitudinal/src/toolbarButtons.ts b/modes/longitudinal/src/toolbarButtons.ts index 62e33a679..9b98db3fa 100644 --- a/modes/longitudinal/src/toolbarButtons.ts +++ b/modes/longitudinal/src/toolbarButtons.ts @@ -1,6 +1,6 @@ // TODO: torn, can either bake this here; or have to create a whole new button type // Only ways that you can pass in a custom React component for render :l -import { defaults, ToolbarService } from '@ohif/core'; +import { ToolbarService } from '@ohif/core'; import type { Button } from '@ohif/core/types'; const { createButton } = ToolbarService; diff --git a/modes/preclinical-4d/src/index.tsx b/modes/preclinical-4d/src/index.tsx index c74fb985c..213a5f618 100644 --- a/modes/preclinical-4d/src/index.tsx +++ b/modes/preclinical-4d/src/index.tsx @@ -79,7 +79,7 @@ function modeFactory({ modeConfiguration }) { () => { const viewportId = viewportGridService.getActiveViewportId(); const csViewport = cornerstoneViewportService.getCornerstoneViewport(viewportId); - cineService.playClip(csViewport.element); + cineService.playClip(csViewport.element, { viewportId }); // cineService.setIsCineEnabled(true); unsubscribe(); diff --git a/modes/preclinical-4d/src/segmentationButtons.ts b/modes/preclinical-4d/src/segmentationButtons.ts index b4efbe04d..330cdcf48 100644 --- a/modes/preclinical-4d/src/segmentationButtons.ts +++ b/modes/preclinical-4d/src/segmentationButtons.ts @@ -24,7 +24,7 @@ const toolbarButtons: Button[] = [ label: 'Brush', evaluate: { name: 'evaluate.cornerstone.segmentation', - options: { toolNames: ['CircularBrush', 'SphereBrush'] }, + toolNames: ['CircularBrush', 'SphereBrush'], }, commands: _createSetToolActiveCommands('CircularBrush'), options: [ @@ -60,9 +60,7 @@ const toolbarButtons: Button[] = [ label: 'Eraser', evaluate: { name: 'evaluate.cornerstone.segmentation', - options: { - toolNames: ['CircularEraser', 'SphereEraser'], - }, + toolNames: ['CircularEraser', 'SphereEraser'], }, commands: _createSetToolActiveCommands('CircularEraser'), options: [ @@ -98,7 +96,7 @@ const toolbarButtons: Button[] = [ label: 'Eraser', evaluate: { name: 'evaluate.cornerstone.segmentation', - options: { toolNames: ['ThresholdCircularBrush', 'ThresholdSphereBrush'] }, + toolNames: ['ThresholdCircularBrush', 'ThresholdSphereBrush'], }, commands: _createSetToolActiveCommands('ThresholdCircularBrush'), options: [ @@ -155,7 +153,7 @@ const toolbarButtons: Button[] = [ label: 'Shapes', evaluate: { name: 'evaluate.cornerstone.segmentation', - options: { toolNames: ['CircleScissor', 'SphereScissor', 'RectangleScissor'] }, + toolNames: ['CircleScissor', 'SphereScissor', 'RectangleScissor'], }, icon: 'icon-tool-shape', commands: _createSetToolActiveCommands('CircleScissor'), diff --git a/modes/segmentation/src/initToolGroups.ts b/modes/segmentation/src/initToolGroups.ts index f6d7556e0..8b2c28da9 100644 --- a/modes/segmentation/src/initToolGroups.ts +++ b/modes/segmentation/src/initToolGroups.ts @@ -41,7 +41,6 @@ function createTools(utilityModule) { parentTool: 'Brush', configuration: { activeStrategy: 'THRESHOLD_INSIDE_CIRCLE', - dynamicRadius: 3, }, }, { @@ -49,7 +48,22 @@ function createTools(utilityModule) { parentTool: 'Brush', configuration: { activeStrategy: 'THRESHOLD_INSIDE_SPHERE', - dynamicRadius: 3, + }, + }, + { + toolName: 'ThresholdCircularBrushDynamic', + parentTool: 'Brush', + configuration: { + activeStrategy: 'THRESHOLD_INSIDE_CIRCLE', + preview: { + enabled: true, + }, + strategySpecificConfiguration: { + THRESHOLD: { + isDynamic: true, + dynamicRadius: 3, + }, + }, }, }, { toolName: toolNames.CircleScissors }, @@ -58,10 +72,10 @@ function createTools(utilityModule) { { toolName: toolNames.StackScroll }, { toolName: toolNames.Magnify }, { toolName: toolNames.SegmentationDisplay }, - { toolName: toolNames.AdvancedMagnify }, + { toolName: toolNames.UltrasoundDirectional }, ], - disabled: [{ toolName: toolNames.ReferenceLines }], + disabled: [{ toolName: toolNames.ReferenceLines }, { toolName: toolNames.AdvancedMagnify }], }; } diff --git a/modes/segmentation/src/segmentationButtons.ts b/modes/segmentation/src/segmentationButtons.ts index 51de3487d..cb096a9c6 100644 --- a/modes/segmentation/src/segmentationButtons.ts +++ b/modes/segmentation/src/segmentationButtons.ts @@ -24,7 +24,7 @@ const toolbarButtons: Button[] = [ label: 'Brush', evaluate: { name: 'evaluate.cornerstone.segmentation', - options: { toolNames: ['CircularBrush', 'SphereBrush'] }, + toolNames: ['CircularBrush', 'SphereBrush'], disabledText: 'Create new segmentation to enable this tool.', }, commands: _createSetToolActiveCommands('CircularBrush'), @@ -61,9 +61,7 @@ const toolbarButtons: Button[] = [ label: 'Eraser', evaluate: { name: 'evaluate.cornerstone.segmentation', - options: { - toolNames: ['CircularEraser', 'SphereEraser'], - }, + toolNames: ['CircularEraser', 'SphereEraser'], }, commands: _createSetToolActiveCommands('CircularEraser'), options: [ @@ -99,7 +97,7 @@ const toolbarButtons: Button[] = [ label: 'Threshold Tool', evaluate: { name: 'evaluate.cornerstone.segmentation', - options: { toolNames: ['ThresholdCircularBrush', 'ThresholdSphereBrush'] }, + toolNames: ['ThresholdCircularBrush', 'ThresholdSphereBrush'], }, commands: _createSetToolActiveCommands('ThresholdCircularBrush'), options: [ @@ -138,8 +136,16 @@ const toolbarButtons: Button[] = [ { value: 'ThresholdDynamic', label: 'Dynamic' }, { value: 'ThresholdRange', label: 'Range' }, ], - commands: { - commandName: 'toggleThresholdRangeAndDynamic', + commands: ({ value, commandsManager }) => { + if (value === 'ThresholdDynamic') { + commandsManager.run('setToolActive', { + toolName: 'ThresholdCircularBrushDynamic', + }); + } else { + commandsManager.run('setToolActive', { + toolName: 'ThresholdCircularBrush', + }); + } }, }, { @@ -171,7 +177,7 @@ const toolbarButtons: Button[] = [ label: 'Shapes', evaluate: { name: 'evaluate.cornerstone.segmentation', - options: { toolNames: ['CircleScissor', 'SphereScissor', 'RectangleScissor'] }, + toolNames: ['CircleScissor', 'SphereScissor', 'RectangleScissor'], }, icon: 'icon-tool-shape', commands: _createSetToolActiveCommands('CircleScissor'), diff --git a/modes/segmentation/src/toolbarButtons.ts b/modes/segmentation/src/toolbarButtons.ts index 9d53484f7..1d1b445be 100644 --- a/modes/segmentation/src/toolbarButtons.ts +++ b/modes/segmentation/src/toolbarButtons.ts @@ -13,21 +13,7 @@ const ReferenceLinesListeners: RunCommand = [ export const setToolActiveToolbar = { commandName: 'setToolActiveToolbar', commandOptions: { - toolGroupIds: ['default', 'mpr', 'SRToolGroup'], - }, -}; - -export const toggleEnabledDisabledToolbar = { - commandName: 'toggleEnabledDisabledToolbar', - commandOptions: { - toolGroupIds: ['default', 'mpr', 'SRToolGroup'], - }, -}; - -export const toggleActiveDisabledToolbar = { - commandName: 'toggleActiveDisabledToolbar', - commandOptions: { - toolGroupIds: ['default', 'mpr', 'SRToolGroup'], + toolGroupIds: ['default', 'mpr', 'SRToolGroup', 'volume3d'], }, }; @@ -163,7 +149,7 @@ const toolbarButtons: Button[] = [ icon: 'tool-referenceLines', label: 'Reference Lines', tooltip: 'Show Reference Lines', - commands: toggleEnabledDisabledToolbar, + commands: 'toggleEnabledDisabledToolbar', listeners: { [ViewportGridService.EVENTS.ACTIVE_VIEWPORT_ID_CHANGED]: ReferenceLinesListeners, [ViewportGridService.EVENTS.VIEWPORTS_READY]: ReferenceLinesListeners, @@ -175,7 +161,7 @@ const toolbarButtons: Button[] = [ icon: 'toggle-dicom-overlay', label: 'Image Overlay', tooltip: 'Toggle Image Overlay', - commands: toggleEnabledDisabledToolbar, + commands: 'toggleEnabledDisabledToolbar', evaluate: 'evaluate.cornerstoneTool.toggle', }), createButton({ @@ -254,8 +240,8 @@ const toolbarButtons: Button[] = [ icon: 'icon-tool-loupe', label: 'Loupe', tooltip: 'Loupe', - commands: toggleActiveDisabledToolbar, - evaluate: 'evaluate.cornerstoneTool', + commands: 'toggleActiveDisabledToolbar', + evaluate: 'evaluate.cornerstoneTool.toggle.ifStrictlyDisabled', }), createButton({ id: 'UltrasoundDirectionalTool', diff --git a/modes/tmtv/src/index.js b/modes/tmtv/src/index.js index b1d6373ab..7acca7c92 100644 --- a/modes/tmtv/src/index.js +++ b/modes/tmtv/src/index.js @@ -184,6 +184,7 @@ function modeFactory({ modeConfiguration }) { const isValid = modalities_list.includes('CT') && + study.mrn !== 'M1' && modalities_list.includes('PT') && !invalidModalities.some(modality => modalities_list.includes(modality)) && // This is study is a 4D study with PT and CT and not a 3D study for the tmtv diff --git a/package.json b/package.json index 1c82d2442..199db41f3 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ }, "dependencies": { "@babel/runtime": "^7.20.13", - "@kitware/vtk.js": "30.3.1", + "@kitware/vtk.js": "30.3.3", "core-js": "^3.2.1" }, "peerDependencies": { diff --git a/platform/app/package.json b/platform/app/package.json index 0b40bd882..92a83f83e 100644 --- a/platform/app/package.json +++ b/platform/app/package.json @@ -54,7 +54,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.70.5", + "@cornerstonejs/dicom-image-loader": "^1.70.6", "@emotion/serialize": "^1.1.3", "@ohif/core": "3.8.0-beta.80", "@ohif/extension-cornerstone": "3.8.0-beta.80", diff --git a/platform/app/src/components/ViewportGrid.tsx b/platform/app/src/components/ViewportGrid.tsx index 74730b0e9..ab0e09112 100644 --- a/platform/app/src/components/ViewportGrid.tsx +++ b/platform/app/src/components/ViewportGrid.tsx @@ -12,7 +12,7 @@ function ViewerViewportGrid(props) { const [viewportGrid, viewportGridService] = useViewportGrid(); const [appConfig] = useAppConfig(); - const { layout, activeViewportId, viewports } = viewportGrid; + const { layout, activeViewportId, viewports, isHangingProtocolLayout } = viewportGrid; const { numCols, numRows } = layout; const elementRef = useRef(null); const layoutHash = useRef(null); @@ -97,11 +97,21 @@ function ViewerViewportGrid(props) { layoutType, layoutOptions, findOrCreateViewport, + isHangingProtocolLayout: true, }); }; const _getUpdatedViewports = useCallback( (viewportId, displaySetInstanceUID) => { + if (!isHangingProtocolLayout) { + return [ + { + viewportId, + displaySetInstanceUIDs: [displaySetInstanceUID], + }, + ]; + } + let updatedViewports = []; try { updatedViewports = hangingProtocolService.getViewportsRequireUpdate( @@ -121,7 +131,7 @@ function ViewerViewportGrid(props) { return updatedViewports; }, - [hangingProtocolService, uiNotificationService] + [hangingProtocolService, uiNotificationService, isHangingProtocolLayout] ); // Using Hanging protocol engine to match the displaySets @@ -340,6 +350,7 @@ function ViewerViewportGrid(props) { viewportOptions={viewportOptions} displaySetOptions={displaySetOptions} needsRerendering={displaySetsNeedsRerendering} + isHangingProtocolLayout={isHangingProtocolLayout} onElementEnabled={() => { viewportGridService.setViewportIsReady(viewportId, true); }} diff --git a/platform/cli/src/questions.js b/platform/cli/src/questions.js index 26f207d7c..03aeec632 100644 --- a/platform/cli/src/questions.js +++ b/platform/cli/src/questions.js @@ -18,7 +18,9 @@ function getPathQuestions(packageType) { { type: 'input', name: 'baseDir', - message: `What is the target path to create your ${packageType} (we recommend you do not use the OHIF ${packageType} folder (./${packageType}s) unless you are developing a core ${packageType}):`, + message: `What is the target path to create your ${packageType}?`, + suffix: `\n(we recommend you do not use the OHIF ${packageType} folder (./${packageType}s) unless you are developing a core ${packageType})`, + maxLength: 40, validate: input => { if (!input) { console.log('Please provide a valid target directory path'); diff --git a/platform/cli/templates/mode/src/index.tsx b/platform/cli/templates/mode/src/index.tsx index 5efbe0a2a..b607e921a 100644 --- a/platform/cli/templates/mode/src/index.tsx +++ b/platform/cli/templates/mode/src/index.tsx @@ -1,5 +1,5 @@ import { hotkeys } from '@ohif/core'; -import { initToolGroups, moreTools, toolbarButtons } from '@ohif/mode-longitudinal'; +import { initToolGroups, toolbarButtons } from '@ohif/mode-longitudinal'; import { id } from './id'; const ohif = { @@ -64,7 +64,6 @@ function modeFactory({ modeConfiguration }) { const { toolGroupService, syncGroupService, - toolbarService, segmentationService, cornerstoneViewportService, uiDialogService, @@ -87,7 +86,9 @@ function modeFactory({ modeConfiguration }) { * A boolean return value that indicates whether the mode is valid for the * modalities of the selected studies. For instance a PET/CT mode should be */ - isValidMode: ({ modalities }) => true, + isValidMode: ({ modalities }) => { + return { valid: true }; + }, /** * Mode Routes are used to define the mode's behavior. A list of Mode Route * that includes the mode's path and the layout to be used. The layout will diff --git a/platform/core/package.json b/platform/core/package.json index de44e55fd..8697c026e 100644 --- a/platform/core/package.json +++ b/platform/core/package.json @@ -37,7 +37,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.70.5", + "@cornerstonejs/dicom-image-loader": "^1.70.6", "@ohif/ui": "3.8.0-beta.80", "cornerstone-math": "0.1.9", "dicom-parser": "^1.8.21" diff --git a/platform/core/src/services/CineService/CineService.ts b/platform/core/src/services/CineService/CineService.ts index d7f054b82..334187d62 100644 --- a/platform/core/src/services/CineService/CineService.ts +++ b/platform/core/src/services/CineService/CineService.ts @@ -14,6 +14,7 @@ class CineService extends PubSubService { }; serviceImplementation = {}; + startedClips = new Map(); constructor() { super(CineService.EVENTS); @@ -41,21 +42,26 @@ class CineService extends PubSubService { public playClip(element, playClipOptions) { const res = this.serviceImplementation._playClip(element, playClipOptions); + this.startedClips.set(element, playClipOptions); + this._broadcastEvent(this.EVENTS.CINE_STATE_CHANGED, { isPlaying: true }); return res; } - public stopClip(element) { - const res = this.serviceImplementation._stopClip(element); + public stopClip(element, stopClipOptions) { + const res = this.serviceImplementation._stopClip(element, stopClipOptions); this._broadcastEvent(this.EVENTS.CINE_STATE_CHANGED, { isPlaying: false }); return res; } - public _onModeExit() { + public onModeExit() { this.setIsCineEnabled(false); + this.startedClips.forEach((value, key) => { + this.stopClip(key, value); + }); } public getSyncedViewports(viewportId) { diff --git a/platform/core/src/services/HangingProtocolService/HangingProtocolService.ts b/platform/core/src/services/HangingProtocolService/HangingProtocolService.ts index 0246a28e9..90c19c458 100644 --- a/platform/core/src/services/HangingProtocolService/HangingProtocolService.ts +++ b/platform/core/src/services/HangingProtocolService/HangingProtocolService.ts @@ -1388,6 +1388,22 @@ export default class HangingProtocolService extends PubSubService { }); } + public areRequiredSelectorsValid( + displaySetSelectors: HangingProtocol.DisplaySetSelector, + displaySet: any + ): boolean { + let pass = true; + for (const displaySetSelector of displaySetSelectors) { + try { + this._validateRequiredSelectors(displaySetSelector, displaySet); + } catch (error) { + pass = false; + break; + } + } + return pass; + } + private _validateRequiredSelectors( displaySetSelector: HangingProtocol.DisplaySetSelector, displaySet: any diff --git a/platform/core/src/services/PanelService/PanelService.tsx b/platform/core/src/services/PanelService/PanelService.tsx index b7e0b13f4..06795f4f2 100644 --- a/platform/core/src/services/PanelService/PanelService.tsx +++ b/platform/core/src/services/PanelService/PanelService.tsx @@ -49,9 +49,19 @@ export default class PanelService extends PubSubService { const entry = this._extensionManager.getModuleEntry(panelId); if (!entry) { - throw new Error( - `${panelId} is not a valid entry for an extension module, please check your configuration or make sure the extension is registered.` - ); + // Check for similar panel names + const similarPanels = this._getSimilarPanels(panelId); + + if (similarPanels.length > 0) { + const suggestion = `Did you mean: ${similarPanels.join(', ')}?`; + throw new Error( + `${panelId} is not a valid entry for an extension module. ${suggestion} Please check your configuration or make sure the extension is registered.` + ); + } else { + throw new Error( + `${panelId} is not a valid entry for an extension module, please check your configuration or make sure the extension is registered.` + ); + } } if (!entry?.component) { @@ -65,6 +75,27 @@ export default class PanelService extends PubSubService { return { entry, content }; } + private _getSimilarPanels(panelId: string, threshold = 0.8): string[] { + const registeredPanels = Object.keys(this._extensionManager.modulesMap).filter(name => + name.includes('panelModule') + ); + + const similarPanels = registeredPanels.filter(registeredPanelId => { + const similarity = this._calculateSimilarity(panelId, registeredPanelId); + return similarity >= threshold; + }); + + return similarPanels; + } + + private _calculateSimilarity(str1: string, str2: string): number { + const set1 = new Set(str1.toLowerCase().split('')); + const set2 = new Set(str2.toLowerCase().split('')); + const intersection = new Set([...set1].filter(x => set2.has(x))); + const union = new Set([...set1, ...set2]); + return intersection.size / union.size; + } + public getPanelData(panelId): PanelData { let content, entry; if (Array.isArray(panelId)) { diff --git a/platform/core/src/services/ViewportGridService/ViewportGridService.ts b/platform/core/src/services/ViewportGridService/ViewportGridService.ts index 1d2837347..60309eb09 100644 --- a/platform/core/src/services/ViewportGridService/ViewportGridService.ts +++ b/platform/core/src/services/ViewportGridService/ViewportGridService.ts @@ -150,6 +150,7 @@ class ViewportGridService extends PubSubService { layoutType = 'grid', activeViewportId = undefined, findOrCreateViewport = undefined, + isHangingProtocolLayout = false, }) { this.serviceImplementation._setLayout({ numCols, @@ -158,6 +159,7 @@ class ViewportGridService extends PubSubService { layoutType, activeViewportId, findOrCreateViewport, + isHangingProtocolLayout, }); this._broadcastEvent(this.EVENTS.LAYOUT_CHANGED, { numCols, diff --git a/platform/core/src/services/ViewportGridService/getPresentationIds.ts b/platform/core/src/services/ViewportGridService/getPresentationIds.ts index 47771c300..835442879 100644 --- a/platform/core/src/services/ViewportGridService/getPresentationIds.ts +++ b/platform/core/src/services/ViewportGridService/getPresentationIds.ts @@ -116,6 +116,10 @@ const getPresentationIds = (viewport, viewports): PresentationIds => { positionPresentationArr.push(id); } + if (displaySetOptions.some(ds => ds.options?.blendMode || ds.options?.displayPreset)) { + positionPresentationArr.push(`custom`); + } + for (const uid of displaySetInstanceUIDs) { positionPresentationArr.push(uid); lutPresentationArr.push(uid); @@ -124,7 +128,7 @@ const getPresentationIds = (viewport, viewports): PresentationIds => { // only add unique index if the viewport is getting inserted and not updated const isUpdatingSameViewport = Array.from(viewports.values()).some(v => { return ( - v.displaySetInstanceUIDs.toString() === viewport.displaySetInstanceUIDs.toString() && + v.displaySetInstanceUIDs?.toString() === viewport.displaySetInstanceUIDs?.toString() && v.viewportId === viewport.viewportId ); }); diff --git a/platform/docs/docs/conformance.md b/platform/docs/docs/conformance.md new file mode 100644 index 000000000..62c9c40f8 --- /dev/null +++ b/platform/docs/docs/conformance.md @@ -0,0 +1,7 @@ +--- +sidebar_position: 10 +sidebar_label: DICOM Conformance Statement (NEW) +title: DICOM Conformance Statement +--- + +You can find a version that has been open sourced by Radical Imaging [in this link](https://docs.google.com/document/d/1hbDlUApX4svX33gAUGxGfD7fXXZNaBsX0hSePbc-hNA/edit?usp=sharing) diff --git a/platform/docs/docs/faq.md b/platform/docs/docs/faq.md index 8746e5d98..5064899db 100644 --- a/platform/docs/docs/faq.md +++ b/platform/docs/docs/faq.md @@ -10,7 +10,9 @@ sidebar_label: FAQ - [Who should I contact about Academic Collaborations?](#who-should-i-contact-about-academic-collaborations) - [Does OHIF offer support?](#does-ohif-offer-support) - [Does The OHIF Viewer have 510(k) Clearance from the U.S. F.D.A or CE Marking from the European Commission?](#does-the-ohif-viewer-have-510k-clearance-from-the-us-fda-or-ce-marking-from-the-european-commission) + - [Is there a DICOM Conformance Statement for the OHIF Viewer?](#is-there-a-dicom-conformance-statement-for-the-ohif-viewer) - [Is The OHIF Viewer HIPAA Compliant?](#is-the-ohif-viewer-hipaa-compliant) + - [Could you provide me with a particular study from the OHIF Viewer Demo?](#could-you-provide-me-with-a-particular-study-from-the-ohif-viewer-demo) - [Technical FAQ](#technical-faq) - [Why do I keep seeing a Cross Origin Isolation warning](#why-do-i-keep-seeing-a-cross-origin-isolation-warning) - [What if my setup does not support the Shared Array Buffers API?](#what-if-my-setup-does-not-support-the-shared-array-buffers-api) @@ -65,14 +67,24 @@ for a product built using the platform. If you have gone this route (or are going there), please let us know because we would be interested to hear about your experience. +## Is there a DICOM Conformance Statement for the OHIF Viewer? + +Yes, check it here [DICOM Conformance Statement](https://docs.google.com/document/d/1hbDlUApX4svX33gAUGxGfD7fXXZNaBsX0hSePbc-hNA/edit?usp=sharing) + ## Is The OHIF Viewer [HIPAA][hipaa-def] Compliant? **NO.** The OHIF Viewer **DOES NOT** fulfill all of the criteria to become HIPAA Compliant. It is the users' responsibility to ensure compliance with applicable rules and regulations. +## Could you provide me with a particular study from the OHIF Viewer Demo? + +You can check out the studies that we have put in this [Dropbox link](https://www.dropbox.com/scl/fo/66xidsx13pn0zf3b9cbfq/ADaCgn7aT29WMlnTdT_WRXM?rlkey=rratvx6g4kfxnswjdbupewjye&dl=0) + # Technical FAQ + + ## Why do I keep seeing a Cross Origin Isolation warning If you encounter a warning while running OHIF indicating that your application is not cross-origin isolated, it implies that volume rendering, such as MPR, will not function properly since they depend on Shared Array Buffers. To resolve this issue, we recommend referring to our comprehensive guide on Cross Origin Isolation available at [our dedicated cors page](./deployment/cors.md). diff --git a/platform/docs/docs/migration-guide/_category_.json b/platform/docs/docs/migration-guide/_category_.json new file mode 100644 index 000000000..e4b82ff55 --- /dev/null +++ b/platform/docs/docs/migration-guide/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Migration Guides", + "position": 11 +} diff --git a/platform/docs/docs/migration-guide/from-3p7-to-3p8.md b/platform/docs/docs/migration-guide/from-3p7-to-3p8.md new file mode 100644 index 000000000..48ea73890 --- /dev/null +++ b/platform/docs/docs/migration-guide/from-3p7-to-3p8.md @@ -0,0 +1,137 @@ +--- +sidebar_position: 1 +sidebar_label: 3.7 -> 3.8 +--- + +# Migration Guide + +There are two main things that need to be taken care of. + + +## New Toolbar Button definitions + +### Update Active Tool Handling +The concept of `activeTool` and its associated getter and setter has been removed. The active tool should now be derived from the toolGroup and the viewport. + + +**Action Needed** + +Remove any code that sets the default tool using `toolbarService.setDefaultTool()` and activates the tool using +`toolbarService.recordInteraction()`. For example, the following code should be removed: + +```javascript +let unsubscribe; +toolbarService.setDefaultTool({ + groupId: "WindowLevel", + itemId: "WindowLevel", + interactionType: "tool", + commands: [ + { + commandName: "setToolActive", + commandOptions: { + toolName: "WindowLevel", + }, + context: "CORNERSTONE", + }, + ], +}); + +const activateTool = () => { + toolbarService.recordInteraction(toolbarService.getDefaultTool()); + + unsubscribe(); +}; + +({ unsubscribe } = toolGroupService.subscribe( + toolGroupService.EVENTS.VIEWPORT_ADDED, + activateTool +)); +``` + + + +Instead, focus on defining the buttons and their placement in the toolbar using `toolbarService.addButtons()` and `toolbarService.createButtonSection()`. For example: + +```javascript +toolbarService.addButtons([...toolbarButtons, ...moreTools]); +toolbarService.createButtonSection("primary", [ + "MeasurementTools", + "Zoom", + "WindowLevel", + "Pan", + "Capture", + "Layout", + "MPR", + "Crosshairs", + "MoreTools", +]); +``` + + +### Update Button Definitions +The concept of button types (toggle, action, tool) has been removed. Buttons are now defined using a simplified object-based definition. + +**Action Needed** + +Update your button definitions to use the new object-based format and remove the `type` property. Use the `uiType` property for the top-level UI type definition. For example: + +```javascript +// Old Implementation +{ + id: 'Capture', + type: 'ohif.action', + props: { + icon: 'tool-capture', + label: 'Capture', + type: 'action', + commands: [ + { + commandName: 'showDownloadViewportModal', + commandOptions: {}, + context: 'CORNERSTONE', + }, + ], + }, +}, +``` + +is now + +```javascript +// New Implementation +{ + id: 'Capture', + uiType: 'ohif.radioGroup', + props: { + icon: 'tool-capture', + label: 'Capture', + commands: [ + { + commandName: 'showDownloadViewportModal', + context: 'CORNERSTONE', + }, + ], + evaluate: 'evaluate.action', + }, +}, +``` + +### Add Evaluators to Button Definitions +Introduce the evaluate property in your button definitions to determine the state of the button based on the app context. + +**Action Needed** + +Add the appropriate `evaluate` property to each button definition. For example: + - Use `evaluate.cornerstoneTool` if the button should be highlighted only when it is the active primary tool (left mouse). + - Use `evaluate.cornerstoneTool.toggle` if the tool is a toggle tool (like reference lines or image overlay). + +Refer to the `modes/longitudinal/src/toolbarButtons.ts` file for examples of using the `evaluate` property. + +Additional Resources + + - For more information on the new toolbar module and its usage, refer to the [Toolbar documentation](../platform/extensions/modules/toolbar.md). + - Consult the updated button definitions in `modes/longitudinal/src/toolbarButtons.ts` for examples of the new object-based button definition format and the usage of evaluators. + +## leftPanelDefaultClosed and rightPanelDefaultClosed + +Now they are renamed to `leftPanelClosed` and `rightPanelClosed` respectively. diff --git a/platform/docs/docs/migration-guide.md b/platform/docs/docs/migration-guide/from-v2.md similarity index 97% rename from platform/docs/docs/migration-guide.md rename to platform/docs/docs/migration-guide/from-v2.md index 9f93828a5..81f70806f 100644 --- a/platform/docs/docs/migration-guide.md +++ b/platform/docs/docs/migration-guide/from-v2.md @@ -1,6 +1,6 @@ --- -sidebar_position: 10 -sidebar_label: Migration Guide +sidebar_position: 2 +sidebar_label: 2.x -> 3.5 --- # Migration Guide @@ -57,7 +57,7 @@ easier to maintain. The main differences are: - platform/viewer (@ohif/viewer) has been renamed to platform/app (@ohif/app) (explanation below) - Extensions are available to be used by modes on request, but are still injected as module components. -- To use the modules provided by the extensions, you need to write a [Mode](./platform/modes/index.md). Modes +- To use the modules provided by the extensions, you need to write a [Mode](../platform/modes/index.md). Modes are configuration objects that will be used by the viewer to load the modules. This lets users to be able to use common extensions with different configurations, and enhances the customizability of the viewer. - App configuration structure is different, mainly the `servers` is renamed to `dataSources`. - Apps can be customized significantly more than previously by providing configuration code int he customizationModule section. @@ -70,14 +70,14 @@ are configuration objects that will be used by the viewer to load the modules. T - redux store has been removed and replaced with a simpler state management system via React Context API. New significant additions that might be useful for you that weren't available in OHIF v2: -- [OHIF CLI](./development/ohif-cli.md) +- [OHIF CLI](../development/ohif-cli.md) - [New Rendering Engine and Toolings](https://www.cornerstonejs.org/) -- [Modes](./platform/modes/index.md) +- [Modes](../platform/modes/index.md) - [Mode Gallery](https://ohif.org/modes) -- [Layouts](./platform/extensions/modules/layout-template.md) -- [Data Sources](./platform/extensions/modules/data-source.md) -- [Hanging Protocols](./platform/services/data/HangingProtocolService.md) -- [URL Params](./configuration/url.md) +- [Layouts](../platform/extensions/modules/layout-template.md) +- [Data Sources](../platform/extensions/modules/data-source.md) +- [Hanging Protocols](../platform/services/data/HangingProtocolService.md) +- [URL Params](../configuration/url.md) ## Platform/viewer (@ohif/viewer) -> platform/app (@ohif/app) @@ -90,7 +90,7 @@ Since the platform/viewer (@ohif/viewer) is already at v4.12.51, we opted to ren ## Configuration :::tip -There are various configurations available to customize the viewer. Each configuration is represented by a custom-tailored object that should be used with the viewer to work effectively with a specific server. Here are some examples of configuration files found in the platform/app/public/config directory. Some server-specific configurations that you should be aware are: `supportsWildcard`, `bulkDataURI`, `omitQuotationForMultipartRequest`, `staticWado` (Read more about them [here](./configuration/configurationFiles.md)). +There are various configurations available to customize the viewer. Each configuration is represented by a custom-tailored object that should be used with the viewer to work effectively with a specific server. Here are some examples of configuration files found in the platform/app/public/config directory. Some server-specific configurations that you should be aware are: `supportsWildcard`, `bulkDataURI`, `omitQuotationForMultipartRequest`, `staticWado` (Read more about them [here](../configuration/configurationFiles.md)). - default.js: This is our default configuration designed for our main server, which uses a Static WADO datasource hosted on Amazon S3. - local_orthanc.js: Use this configuration when working with our local Orthanc server. @@ -100,11 +100,11 @@ There are various configurations available to customize the viewer. Each configu ::: OHIF v3 has a new configuration structure. The main difference is that the `servers` is renamed to `dataSources` and the configuration is now asynchronous. Datasources are more abstract and -far more capable than servers. Read more about dataSources [here](./platform/extensions/modules/data-source.md). +far more capable than servers. Read more about dataSources [here](../platform/extensions/modules/data-source.md). - `StudyPrefetcher` is not currently supported in OHIF v3. - The `servers` object has been replaced with a `dataSources` array containing objects representing different data sources. -- The cornerstoneExtensionConfig property has been removed, you should use `customizationService` instead (you can read more [here](./platform/services/ui/customization-service.md)) +- The cornerstoneExtensionConfig property has been removed, you should use `customizationService` instead (you can read more [here](../platform/services/ui/customization-service.md)) - The maxConcurrentMetadataRequests property has been removed in favor of `maxNumRequests` - The hotkeys array has been updated with different command names and options, and some keys have been removed. - New properties have been added, including `maxNumberOfWebWorkers`, `omitQuotationForMultipartRequest`, `showWarningMessageForCrossOrigin`, `showCPUFallbackMessage`, `showLoadingIndicator`, `strictZSpacingForVolumeViewport`. @@ -118,7 +118,7 @@ you as the user can focus on creating modes having your own use case and configu Separating the configuration from the extensions also makes it so that you can have multiple modes in a single application each focusing on certain tasks. For example, you can have a mode for segmentation which uses specific panels and tools which you don't need -for a mode that will be used for reading (read more about modes [here](./platform/modes/index.md)) +for a mode that will be used for reading (read more about modes [here](../platform/modes/index.md)) :::info Previously, the viewer was designed around registered extensions. If you had a specific use case, you had to duplicate the viewer code and incorporate your customizations through extensions. However, with the introduction of a new layer of abstraction called Modes, you no longer need to fork the viewer. @@ -184,7 +184,7 @@ for this mode. The `tmtv` mode is using the `cs3d` extension for rendering and t Below you can see a screen shot from the demo showcasing 3 modes for the opened study. -![Alt text](assets/img/migration-modes.png) +![Alt text](../assets/img/migration-modes.png) :::tip How do I decide certain thing should go inside a mode or extension, Here are some considerations to help you make the decision: @@ -222,7 +222,7 @@ Can I register a custom route to OHIF v3? Yes, you can take advantage of the customizationService and register your own routes. -see [custom routes](./platform/services/ui/customization-service.md#customroutes) +see [custom routes](../platform/services/ui/customization-service.md#customroutes) @@ -364,7 +364,7 @@ How to remove an "core" extension/mode? You can use the OHIF cli tool to add/remove/link and unlink extensions and modes. You can find more information -about the cli tool [here](./development/ohif-cli.md) +about the cli tool [here](../development/ohif-cli.md) @@ -514,7 +514,7 @@ modules exported via `get{ModuleName}Module` (e.g., `getViewportModule`). :::info There are new types of modules that can be exported from extensions (such as `HangingProtocolModule`, `LayoutModule`, read more about -modules in v3 [here](platform/extensions/index.md)). +modules in v3 [here](../platform/extensions/index.md)). ::: The main difference between v3 and v2 is that exported modules were represented as a single object, whereas in OHIF v3, they are @@ -667,7 +667,7 @@ By using the updated toolbarModule in OHIF v3, you can define and add toolbar bu An example of split button icon in v3 is shown below -![Alt text](assets/img/migration-split-button.png) +![Alt text](../assets/img/migration-split-button.png)
@@ -874,7 +874,7 @@ We have recently transitioned from bundling all the extensions and the viewer in - Smaller bundle size: By loading extensions on-demand, the initial bundle size is reduced, resulting in faster page load times for users. - Faster reload for development: During development, the incremental build process allows for faster reloads, improving developer productivity. -This new approach does not impact the deployment process of the viewer. You can continue to follow our deployment guides, such as the [Build for Production](./deployment/build-for-production.md) guide, to deploy the viewer effectively. +This new approach does not impact the deployment process of the viewer. You can continue to follow our deployment guides, such as the [Build for Production](../deployment/build-for-production.md) guide, to deploy the viewer effectively. ### Script tag usage of the OHIF viewer diff --git a/platform/docs/docs/platform/extensions/index.md b/platform/docs/docs/platform/extensions/index.md index ec8f48d18..d9c630ecb 100644 --- a/platform/docs/docs/platform/extensions/index.md +++ b/platform/docs/docs/platform/extensions/index.md @@ -233,7 +233,7 @@ differently. - LayoutTemplate (NEW) + LayoutTemplate Control Layout of a route @@ -241,7 +241,7 @@ differently. - DataSource (NEW) + DataSource Control the mapping from DICOM metadata to OHIF-metadata diff --git a/platform/docs/docs/platform/extensions/modules/toolbar.md b/platform/docs/docs/platform/extensions/modules/toolbar.md index cf8ba27ea..4ef1fe3ec 100644 --- a/platform/docs/docs/platform/extensions/modules/toolbar.md +++ b/platform/docs/docs/platform/extensions/modules/toolbar.md @@ -125,7 +125,7 @@ The following evaluators are provided by us: Sometime you want to use the same `evaluator` for different purposes, in that case you can use an object -with `name` and `options` properties. For example, in `'evaluate.cornerstone.segmentation'` we use +with `name` and other properties. For example, in `'evaluate.cornerstone.segmentation'` we use this pattern, where multiple toolbar buttons are using the same evaluator but with different options ( in this case `toolNames` ) @@ -133,9 +133,7 @@ this pattern, where multiple toolbar buttons are using the same evaluator but wi ```js { name: 'evaluate.cornerstone.segmentation', - options: { - toolNames: ['CircleBrush' , 'SphereBrush'] - }, + toolNames: ['CircleBrush' , 'SphereBrush'] }, ``` @@ -392,7 +390,7 @@ three different modes label: 'Shapes', evaluate: { name: 'evaluate.cornerstone.segmentation', - options: { toolNames: ['CircleScissor', 'SphereScissor', 'RectangleScissor'] }, + toolNames: ['CircleScissor', 'SphereScissor', 'RectangleScissor'], }, icon: 'icon-tool-shape', commands: _createSetToolActiveCommands('CircleScissor'), @@ -425,7 +423,7 @@ We use this for brush radius change label: 'Brush', evaluate: { name: 'evaluate.cornerstone.segmentation', - options: { toolNames: ['CircularBrush', 'SphereBrush'] }, + toolNames: ['CircularBrush', 'SphereBrush'], disabledText: 'Create new segmentation to enable this tool.', }, commands: _createSetToolActiveCommands('CircularBrush'), diff --git a/platform/docs/docs/platform/services/index.md b/platform/docs/docs/platform/services/index.md index c4a11b1ed..4fecc0ee4 100644 --- a/platform/docs/docs/platform/services/index.md +++ b/platform/docs/docs/platform/services/index.md @@ -40,7 +40,7 @@ The following services is available in the `OHIF-v3`. - DicomMetadataStore (NEW) + DicomMetadataStore Data Service @@ -51,7 +51,7 @@ The following services is available in the `OHIF-v3`. - DisplaySetService (NEW) + DisplaySetService Data Service @@ -62,7 +62,7 @@ The following services is available in the `OHIF-v3`. - segmentationService (NEW) + segmentationService Segmentation Service @@ -73,7 +73,7 @@ The following services is available in the `OHIF-v3`. - HangingProtocolService (NEW) + HangingProtocolService Data Service @@ -95,7 +95,7 @@ The following services is available in the `OHIF-v3`. - ToolBarService (NEW) + ToolBarService Data Service @@ -106,7 +106,7 @@ The following services is available in the `OHIF-v3`. - ViewportGridService (NEW) + ViewportGridService UI Service @@ -117,7 +117,7 @@ The following services is available in the `OHIF-v3`. - Cine Service (NEW) + Cine Service UI Service @@ -133,7 +133,7 @@ The following services is available in the `OHIF-v3`. UI Service - customizationService (NEW) + customizationService @@ -172,7 +172,7 @@ The following services is available in the `OHIF-v3`. - UIViewportDialogService (NEW) + UIViewportDialogService UI Service diff --git a/platform/docs/docs/resources.md b/platform/docs/docs/resources.md index 9ff2e7a9d..1fad4361f 100644 --- a/platform/docs/docs/resources.md +++ b/platform/docs/docs/resources.md @@ -11,6 +11,16 @@ and other resources that we have provided to the community in the past: ## 2023 +### IMNO 2024 - March 19-20, 2024 + +We participated in the Imaging Network Ontario (ImNO) 2024 symposium, presenting three posters. One of our presentations received the best talk award during the session. + + +- Advancing Medical Imaging on the Web: Implementation of Hanging Protocols for Automated Image Display Configuration in OHIF V3 [Poster](https://www.dropbox.com/scl/fi/z4h86bmsxi0c62e1n6h9l/P7-9-Alireza-Sedghi-Final.pdf?rlkey=v5pm0p5ygkbq41x9bz3hr5yi8&dl=0) +- Advancing Medical Imaging on the Web: Optimizing the Dicomweb Server Architecture with Static Dicomweb [Poster](https://www.dropbox.com/scl/fi/ep0lxjp90kbxhjoffe4kh/P7-10-Bill-Wallace-Final.pdf?rlkey=xl2u6tdnh9j9hgvkajxv3b02o&dl=0) +- (**🏆🏆 BEST PRESENTATION AWARD in the Session 7 Pitches: Devices, HW, SW Development 🏆🏆**) Advancing Medical Imaging on the Web: Integrating High Throughput JPEG 2000 (HTJ2K) in Cornerstone3D for Streamlined Progressive Loading and Visualization [Poster](https://www.dropbox.com/scl/fi/srs2rxgtv2r69ver9ub1j/P7-8-Bill-Wallace-Final.pdf?rlkey=k9mmraw76r9q2s3b9w9s0793w&dl=0) + + ### ITCR 2023 Conference | September 11-13, 2023 Dr. Gordon Harris presented an update on OHIF in [NCI Informatics Technology for Cancer Research Annual Meeting](https://www.itcr2023.org/). You can find the slides and poster here: diff --git a/platform/docs/src/css/custom.css b/platform/docs/src/css/custom.css index ee583b616..445d20759 100644 --- a/platform/docs/src/css/custom.css +++ b/platform/docs/src/css/custom.css @@ -284,7 +284,7 @@ html[data-theme='dark'] .docusaurus-highlight-code-line { } .new-badge::after { - content: ' (NEW)'; + content: ''; @apply bg-red-300 text-red-500; @apply dark:bg-blue-900 dark:text-blue-100; } diff --git a/platform/ui/src/components/LayoutPreset/LayoutPreset.tsx b/platform/ui/src/components/LayoutPreset/LayoutPreset.tsx index 79ba6be15..9113cc0ea 100644 --- a/platform/ui/src/components/LayoutPreset/LayoutPreset.tsx +++ b/platform/ui/src/components/LayoutPreset/LayoutPreset.tsx @@ -1,11 +1,19 @@ import React from 'react'; import PropTypes from 'prop-types'; +import classNames from 'classnames'; import Icon from '../Icon/Icon'; -function LayoutPreset({ onSelection, title, icon, commandOptions, classNames }) { +function LayoutPreset({ + onSelection, + title, + icon, + commandOptions, + classNames: classNameProps, + disabled, +}) { return (
{ onSelection(commandOptions); }} @@ -29,6 +37,7 @@ LayoutPreset.propTypes = { icon: PropTypes.string.isRequired, commandOptions: PropTypes.object.isRequired, classNames: PropTypes.string, + disabled: PropTypes.bool, }; export default LayoutPreset; diff --git a/platform/ui/src/components/SegmentationGroupTable/AddSegmentRow.tsx b/platform/ui/src/components/SegmentationGroupTable/AddSegmentRow.tsx index 817a9fba2..d3ba1a708 100644 --- a/platform/ui/src/components/SegmentationGroupTable/AddSegmentRow.tsx +++ b/platform/ui/src/components/SegmentationGroupTable/AddSegmentRow.tsx @@ -7,7 +7,7 @@ function AddSegmentRow({ onClick, onToggleSegmentationVisibility = null, segment return (
diff --git a/platform/ui/src/components/SegmentationGroupTable/NoSegmentationRow.tsx b/platform/ui/src/components/SegmentationGroupTable/NoSegmentationRow.tsx index 5e6b74e19..85e1acd28 100644 --- a/platform/ui/src/components/SegmentationGroupTable/NoSegmentationRow.tsx +++ b/platform/ui/src/components/SegmentationGroupTable/NoSegmentationRow.tsx @@ -2,11 +2,11 @@ import React from 'react'; import Icon from '../Icon'; import { useTranslation } from 'react-i18next'; -function NoSegmentationRow({ onSegmentationAdd }) { +function NoSegmentationRow({ onSegmentationAdd, addSegmentationClassName }) { const { t } = useTranslation('SegmentationTable'); return (
diff --git a/platform/ui/src/components/SegmentationGroupTable/SegmentationDropDownRow.tsx b/platform/ui/src/components/SegmentationGroupTable/SegmentationDropDownRow.tsx index 8db52a5e1..ff909483a 100644 --- a/platform/ui/src/components/SegmentationGroupTable/SegmentationDropDownRow.tsx +++ b/platform/ui/src/components/SegmentationGroupTable/SegmentationDropDownRow.tsx @@ -15,6 +15,7 @@ function SegmentationDropDownRow({ storeSegmentation, onSegmentationDelete, onSegmentationAdd, + addSegmentationClassName, }) { const handleChange = option => { onActiveSegmentationChange(option.value); // Notify the parent @@ -41,7 +42,7 @@ function SegmentationDropDownRow({ id="segmentation-dropdown" showDropdownIcon={false} alignment="left" - itemsClassName="text-primary-active" + itemsClassName={`text-primary-active ${addSegmentationClassName}`} showBorders={false} maxCharactersPerLine={30} list={[ diff --git a/platform/ui/src/components/SegmentationGroupTable/SegmentationGroupTable.tsx b/platform/ui/src/components/SegmentationGroupTable/SegmentationGroupTable.tsx index e28d42965..58b6d763e 100644 --- a/platform/ui/src/components/SegmentationGroupTable/SegmentationGroupTable.tsx +++ b/platform/ui/src/components/SegmentationGroupTable/SegmentationGroupTable.tsx @@ -42,6 +42,7 @@ const SegmentationGroupTable = ({ setRenderFill, setRenderInactiveSegmentations, setRenderOutline, + addSegmentationClassName, }) => { const [isConfigOpen, setIsConfigOpen] = useState(false); const [activeSegmentationId, setActiveSegmentationId] = useState(null); @@ -100,9 +101,12 @@ const SegmentationGroupTable = ({ )}
{segmentations?.length === 0 ? ( -
+
{showAddSegmentation && !disableEditing && ( - + )}
) : ( @@ -118,6 +122,7 @@ const SegmentationGroupTable = ({ onSegmentationDownloadRTSS={onSegmentationDownloadRTSS} storeSegmentation={storeSegmentation} onSegmentationAdd={onSegmentationAdd} + addSegmentationClassName={addSegmentationClassName} onToggleSegmentationVisibility={onToggleSegmentationVisibility} /> {!disableEditing && showAddSegment && ( diff --git a/platform/ui/src/components/Thumbnail/Thumbnail.tsx b/platform/ui/src/components/Thumbnail/Thumbnail.tsx index 38d773f7f..578f4a73f 100644 --- a/platform/ui/src/components/Thumbnail/Thumbnail.tsx +++ b/platform/ui/src/components/Thumbnail/Thumbnail.tsx @@ -51,7 +51,7 @@ const Thumbnail = ({
) : ( diff --git a/platform/ui/src/components/ThumbnailList/ThumbnailList.tsx b/platform/ui/src/components/ThumbnailList/ThumbnailList.tsx index cf949d202..1ec7e593e 100644 --- a/platform/ui/src/components/ThumbnailList/ThumbnailList.tsx +++ b/platform/ui/src/components/ThumbnailList/ThumbnailList.tsx @@ -16,7 +16,7 @@ const ThumbnailList = ({ return (
{thumbnails.map( ({ diff --git a/platform/ui/src/components/ThumbnailTracked/ThumbnailTracked.tsx b/platform/ui/src/components/ThumbnailTracked/ThumbnailTracked.tsx index e1bd9acb3..91f1a344d 100644 --- a/platform/ui/src/components/ThumbnailTracked/ThumbnailTracked.tsx +++ b/platform/ui/src/components/ThumbnailTracked/ThumbnailTracked.tsx @@ -32,10 +32,7 @@ function ThumbnailTracked({ return (
diff --git a/platform/ui/src/components/Toolbox/Toolbox.tsx b/platform/ui/src/components/Toolbox/Toolbox.tsx index 66f93e989..84e388281 100644 --- a/platform/ui/src/components/Toolbox/Toolbox.tsx +++ b/platform/ui/src/components/Toolbox/Toolbox.tsx @@ -65,6 +65,7 @@ function Toolbox({ servicesManager, buttonSectionId, commandsManager, title, ... cmds.forEach(command => { const isString = typeof command === 'string'; const isObject = typeof command === 'object'; + const isFunction = typeof command === 'function'; if (isString) { commandsManager.run(command, { value }); @@ -73,6 +74,8 @@ function Toolbox({ servicesManager, buttonSectionId, commandsManager, title, ... ...command, commandOptions: { ...command.commandOptions, ...option, value }, }); + } else if (isFunction) { + command({ value, commandsManager, servicesManager }); } }); }, diff --git a/platform/ui/src/contextProviders/CineProvider.tsx b/platform/ui/src/contextProviders/CineProvider.tsx index 5946698f4..97a568823 100644 --- a/platform/ui/src/contextProviders/CineProvider.tsx +++ b/platform/ui/src/contextProviders/CineProvider.tsx @@ -92,7 +92,7 @@ export default function CineProvider({ children, service }) { setCine, setIsCineEnabled: isCineEnabled => service.setIsCineEnabled(isCineEnabled), playClip: (element, playClipOptions) => service.playClip(element, playClipOptions), - stopClip: element => service.stopClip(element), + stopClip: (element, stopClipOptions) => service.stopClip(element, stopClipOptions), }; return {children}; diff --git a/platform/ui/src/contextProviders/ViewportGridProvider.tsx b/platform/ui/src/contextProviders/ViewportGridProvider.tsx index 93319613d..72fc67fb4 100644 --- a/platform/ui/src/contextProviders/ViewportGridProvider.tsx +++ b/platform/ui/src/contextProviders/ViewportGridProvider.tsx @@ -28,6 +28,7 @@ interface Layout { interface DefaultState { activeViewportId: string | null; layout: Layout; + isHangingProtocolLayout: boolean; viewports: Map; } @@ -38,6 +39,16 @@ const DEFAULT_STATE: DefaultState = { numCols: 0, layoutType: 'grid', }, + // this flag is used to determine if the hanging protocol layout is active + // so that we can inherit the viewport options from the previous state + // otherwise we will not allow that. Basically the issue is that we need + // to be able to come out of the hanging protocol layout and go back to the + // regular layout e.g., if we are in the MPR hanging protocol, and someone use + // 1x1 layout by custom layout selector, there is no way to drag and drop + // a non-reconstructible series to the viewport since it will always + // inherit the hanging protocol layout options (volume viewport), + // so we need to be able to switch back to the regular layout. + isHangingProtocolLayout: false, // Viewports structure has been changed to Map (previously it was // tied to the viewportIndex which caused multiple issues. Now we have // moved completely to viewportId which is unique for each viewport. @@ -152,7 +163,7 @@ export function ViewportGridProvider({ children, service }) { // Use the newly provide viewportOptions and display set options // when provided, and otherwise fall back to the previous ones. // That allows for easy updates of just the display set. - const viewportOptions = merge( + let viewportOptions = merge( {}, previousViewport?.viewportOptions, updatedViewport?.viewportOptions @@ -161,18 +172,29 @@ export function ViewportGridProvider({ children, service }) { const displaySetOptions = updatedViewport.displaySetOptions || []; if (!displaySetOptions.length) { // Copy all the display set options, assuming a full set of displaySet UID's is provided. - displaySetOptions.push(...previousViewport.displaySetOptions); + if (state.isHangingProtocolLayout) { + displaySetOptions.push(...(previousViewport.displaySetOptions || [])); + } if (!displaySetOptions.length) { displaySetOptions.push({}); } } + // if it is not part of the hanging protocol layout, we should remove the toolGroupId + // and viewportType from the viewportOptions so that it doesn't + // inherit the hanging protocol layout options + if (!state.isHangingProtocolLayout) { + viewportOptions = { + viewportId: viewportOptions.viewportId, + }; + } + const newViewport = { ...previousViewport, displaySetInstanceUIDs, viewportOptions, displaySetOptions, - viewportLabel: getViewportLabel(viewports, viewportId), + // viewportLabel: getViewportLabel(viewports, viewportId), }; viewportOptions.presentationIds = ViewportGridService.getPresentationIds( @@ -196,6 +218,7 @@ export function ViewportGridProvider({ children, service }) { layoutType = 'grid', activeViewportId, findOrCreateViewport, + isHangingProtocolLayout, } = action.payload; // If empty viewportOptions, we use numRow and numCols to calculate number of viewports @@ -283,6 +306,7 @@ export function ViewportGridProvider({ children, service }) { layoutType, }, viewports, + isHangingProtocolLayout, }; return ret; } @@ -373,6 +397,7 @@ export function ViewportGridProvider({ children, service }) { layoutOptions = [], activeViewportId, findOrCreateViewport, + isHangingProtocolLayout, }) => dispatch({ type: 'SET_LAYOUT', @@ -383,6 +408,7 @@ export function ViewportGridProvider({ children, service }) { layoutOptions, activeViewportId, findOrCreateViewport, + isHangingProtocolLayout, }, }), [dispatch] diff --git a/yarn.lock b/yarn.lock index ea7c96fd1..4945f80e8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8,9 +8,9 @@ integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== "@adobe/css-tools@^4.0.1": - version "4.3.2" - resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.3.2.tgz#a6abc715fb6884851fca9dad37fc34739a04fd11" - integrity sha512-DA5a1C0gD/pLOvhv33YMrbf2FK3oUzwNl9oOJqE4XVjuEtt6XIakRcsd7eLiOSPkp1kTRQGICTA8cKra/vFbjw== + version "4.3.3" + resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.3.3.tgz#90749bde8b89cd41764224f5aac29cd4138f75ff" + integrity sha512-rE0Pygv0sEZ4vBWHlAgJLGDU7Pm8xoO6p3wsEceb7GYAjScrOHpEo8KK/eVkAcnSM+slAEtXjA2JpdjLp4fJQQ== "@algolia/autocomplete-core@1.9.3": version "1.9.3" @@ -39,139 +39,139 @@ resolved "https://registry.yarnpkg.com/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz#2e22e830d36f0a9cf2c0ccd3c7f6d59435b77dfa" integrity sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ== -"@algolia/cache-browser-local-storage@4.23.2": - version "4.23.2" - resolved "https://registry.yarnpkg.com/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.23.2.tgz#060d15e89588fcac18e73643201fce0f4f7d5ca0" - integrity sha512-PvRQdCmtiU22dw9ZcTJkrVKgNBVAxKgD0/cfiqyxhA5+PHzA2WDt6jOmZ9QASkeM2BpyzClJb/Wr1yt2/t78Kw== +"@algolia/cache-browser-local-storage@4.23.3": + version "4.23.3" + resolved "https://registry.yarnpkg.com/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.23.3.tgz#0cc26b96085e1115dac5fcb9d826651ba57faabc" + integrity sha512-vRHXYCpPlTDE7i6UOy2xE03zHF2C8MEFjPN2v7fRbqVpcOvAUQK81x3Kc21xyb5aSIpYCjWCZbYZuz8Glyzyyg== dependencies: - "@algolia/cache-common" "4.23.2" + "@algolia/cache-common" "4.23.3" -"@algolia/cache-common@4.23.2": - version "4.23.2" - resolved "https://registry.yarnpkg.com/@algolia/cache-common/-/cache-common-4.23.2.tgz#c68706ce34b18377e56e71ac13cce2dd5662dcee" - integrity sha512-OUK/6mqr6CQWxzl/QY0/mwhlGvS6fMtvEPyn/7AHUx96NjqDA4X4+Ju7aXFQKh+m3jW9VPB0B9xvEQgyAnRPNw== +"@algolia/cache-common@4.23.3": + version "4.23.3" + resolved "https://registry.yarnpkg.com/@algolia/cache-common/-/cache-common-4.23.3.tgz#3bec79092d512a96c9bfbdeec7cff4ad36367166" + integrity sha512-h9XcNI6lxYStaw32pHpB1TMm0RuxphF+Ik4o7tcQiodEdpKK+wKufY6QXtba7t3k8eseirEMVB83uFFF3Nu54A== -"@algolia/cache-in-memory@4.23.2": - version "4.23.2" - resolved "https://registry.yarnpkg.com/@algolia/cache-in-memory/-/cache-in-memory-4.23.2.tgz#94cd828275d7a12186959bf1b95a13247e103b23" - integrity sha512-rfbi/SnhEa3MmlqQvgYz/9NNJ156NkU6xFxjbxBtLWnHbpj+qnlMoKd+amoiacHRITpajg6zYbLM9dnaD3Bczw== +"@algolia/cache-in-memory@4.23.3": + version "4.23.3" + resolved "https://registry.yarnpkg.com/@algolia/cache-in-memory/-/cache-in-memory-4.23.3.tgz#3945f87cd21ffa2bec23890c85305b6b11192423" + integrity sha512-yvpbuUXg/+0rbcagxNT7un0eo3czx2Uf0y4eiR4z4SD7SiptwYTpbuS0IHxcLHG3lq22ukx1T6Kjtk/rT+mqNg== dependencies: - "@algolia/cache-common" "4.23.2" + "@algolia/cache-common" "4.23.3" -"@algolia/client-account@4.23.2": - version "4.23.2" - resolved "https://registry.yarnpkg.com/@algolia/client-account/-/client-account-4.23.2.tgz#b53cb14e730fd8e0a0a227cf650b287b570a08bc" - integrity sha512-VbrOCLIN/5I7iIdskSoSw3uOUPF516k4SjDD4Qz3BFwa3of7D9A0lzBMAvQEJJEPHWdVraBJlGgdJq/ttmquJQ== +"@algolia/client-account@4.23.3": + version "4.23.3" + resolved "https://registry.yarnpkg.com/@algolia/client-account/-/client-account-4.23.3.tgz#8751bbf636e6741c95e7c778488dee3ee430ac6f" + integrity sha512-hpa6S5d7iQmretHHF40QGq6hz0anWEHGlULcTIT9tbUssWUriN9AUXIFQ8Ei4w9azD0hc1rUok9/DeQQobhQMA== dependencies: - "@algolia/client-common" "4.23.2" - "@algolia/client-search" "4.23.2" - "@algolia/transporter" "4.23.2" + "@algolia/client-common" "4.23.3" + "@algolia/client-search" "4.23.3" + "@algolia/transporter" "4.23.3" -"@algolia/client-analytics@4.23.2": - version "4.23.2" - resolved "https://registry.yarnpkg.com/@algolia/client-analytics/-/client-analytics-4.23.2.tgz#7fdcf1cb27f0ae93e5da6beb4e612fc06a880b0c" - integrity sha512-lLj7irsAztGhMoEx/SwKd1cwLY6Daf1Q5f2AOsZacpppSvuFvuBrmkzT7pap1OD/OePjLKxicJS8wNA0+zKtuw== +"@algolia/client-analytics@4.23.3": + version "4.23.3" + resolved "https://registry.yarnpkg.com/@algolia/client-analytics/-/client-analytics-4.23.3.tgz#f88710885278fe6fb6964384af59004a5a6f161d" + integrity sha512-LBsEARGS9cj8VkTAVEZphjxTjMVCci+zIIiRhpFun9jGDUlS1XmhCW7CTrnaWeIuCQS/2iPyRqSy1nXPjcBLRA== dependencies: - "@algolia/client-common" "4.23.2" - "@algolia/client-search" "4.23.2" - "@algolia/requester-common" "4.23.2" - "@algolia/transporter" "4.23.2" + "@algolia/client-common" "4.23.3" + "@algolia/client-search" "4.23.3" + "@algolia/requester-common" "4.23.3" + "@algolia/transporter" "4.23.3" -"@algolia/client-common@4.23.2": - version "4.23.2" - resolved "https://registry.yarnpkg.com/@algolia/client-common/-/client-common-4.23.2.tgz#e5f86fc2de707eb6bf9f1109b70187dae179c72c" - integrity sha512-Q2K1FRJBern8kIfZ0EqPvUr3V29ICxCm/q42zInV+VJRjldAD9oTsMGwqUQ26GFMdFYmqkEfCbY4VGAiQhh22g== +"@algolia/client-common@4.23.3": + version "4.23.3" + resolved "https://registry.yarnpkg.com/@algolia/client-common/-/client-common-4.23.3.tgz#891116aa0db75055a7ecc107649f7f0965774704" + integrity sha512-l6EiPxdAlg8CYhroqS5ybfIczsGUIAC47slLPOMDeKSVXYG1n0qGiz4RjAHLw2aD0xzh2EXZ7aRguPfz7UKDKw== dependencies: - "@algolia/requester-common" "4.23.2" - "@algolia/transporter" "4.23.2" + "@algolia/requester-common" "4.23.3" + "@algolia/transporter" "4.23.3" -"@algolia/client-personalization@4.23.2": - version "4.23.2" - resolved "https://registry.yarnpkg.com/@algolia/client-personalization/-/client-personalization-4.23.2.tgz#0472d9c207402eefcc9c98f7ffba5d26fe8e2fd0" - integrity sha512-vwPsgnCGhUcHhhQG5IM27z8q7dWrN9itjdvgA6uKf2e9r7vB+WXt4OocK0CeoYQt3OGEAExryzsB8DWqdMK5wg== +"@algolia/client-personalization@4.23.3": + version "4.23.3" + resolved "https://registry.yarnpkg.com/@algolia/client-personalization/-/client-personalization-4.23.3.tgz#35fa8e5699b0295fbc400a8eb211dc711e5909db" + integrity sha512-3E3yF3Ocr1tB/xOZiuC3doHQBQ2zu2MPTYZ0d4lpfWads2WTKG7ZzmGnsHmm63RflvDeLK/UVx7j2b3QuwKQ2g== dependencies: - "@algolia/client-common" "4.23.2" - "@algolia/requester-common" "4.23.2" - "@algolia/transporter" "4.23.2" + "@algolia/client-common" "4.23.3" + "@algolia/requester-common" "4.23.3" + "@algolia/transporter" "4.23.3" -"@algolia/client-search@4.23.2": - version "4.23.2" - resolved "https://registry.yarnpkg.com/@algolia/client-search/-/client-search-4.23.2.tgz#9b2741f0a209596459f06a44583118207ea287f7" - integrity sha512-CxSB29OVGSE7l/iyoHvamMonzq7Ev8lnk/OkzleODZ1iBcCs3JC/XgTIKzN/4RSTrJ9QybsnlrN/bYCGufo7qw== +"@algolia/client-search@4.23.3": + version "4.23.3" + resolved "https://registry.yarnpkg.com/@algolia/client-search/-/client-search-4.23.3.tgz#a3486e6af13a231ec4ab43a915a1f318787b937f" + integrity sha512-P4VAKFHqU0wx9O+q29Q8YVuaowaZ5EM77rxfmGnkHUJggh28useXQdopokgwMeYw2XUht49WX5RcTQ40rZIabw== dependencies: - "@algolia/client-common" "4.23.2" - "@algolia/requester-common" "4.23.2" - "@algolia/transporter" "4.23.2" + "@algolia/client-common" "4.23.3" + "@algolia/requester-common" "4.23.3" + "@algolia/transporter" "4.23.3" "@algolia/events@^4.0.1": version "4.0.1" resolved "https://registry.yarnpkg.com/@algolia/events/-/events-4.0.1.tgz#fd39e7477e7bc703d7f893b556f676c032af3950" integrity sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ== -"@algolia/logger-common@4.23.2": - version "4.23.2" - resolved "https://registry.yarnpkg.com/@algolia/logger-common/-/logger-common-4.23.2.tgz#5441a828f0fad1ceaae3a27caec7b663d40dd27f" - integrity sha512-jGM49Q7626cXZ7qRAWXn0jDlzvoA1FvN4rKTi1g0hxKsTTSReyYk0i1ADWjChDPl3Q+nSDhJuosM2bBUAay7xw== +"@algolia/logger-common@4.23.3": + version "4.23.3" + resolved "https://registry.yarnpkg.com/@algolia/logger-common/-/logger-common-4.23.3.tgz#35c6d833cbf41e853a4f36ba37c6e5864920bfe9" + integrity sha512-y9kBtmJwiZ9ZZ+1Ek66P0M68mHQzKRxkW5kAAXYN/rdzgDN0d2COsViEFufxJ0pb45K4FRcfC7+33YB4BLrZ+g== -"@algolia/logger-console@4.23.2": - version "4.23.2" - resolved "https://registry.yarnpkg.com/@algolia/logger-console/-/logger-console-4.23.2.tgz#fda4252bb02df7c52a92c63f1e357bf7370cc8db" - integrity sha512-oo+lnxxEmlhTBTFZ3fGz1O8PJ+G+8FiAoMY2Qo3Q4w23xocQev6KqDTA1JQAGPDxAewNA2VBwWOsVXeXFjrI/Q== +"@algolia/logger-console@4.23.3": + version "4.23.3" + resolved "https://registry.yarnpkg.com/@algolia/logger-console/-/logger-console-4.23.3.tgz#30f916781826c4db5f51fcd9a8a264a06e136985" + integrity sha512-8xoiseoWDKuCVnWP8jHthgaeobDLolh00KJAdMe9XPrWPuf1by732jSpgy2BlsLTaT9m32pHI8CRfrOqQzHv3A== dependencies: - "@algolia/logger-common" "4.23.2" + "@algolia/logger-common" "4.23.3" -"@algolia/recommend@4.23.2": - version "4.23.2" - resolved "https://registry.yarnpkg.com/@algolia/recommend/-/recommend-4.23.2.tgz#02bf57f836ced2c850633239d493a0414be76a7f" - integrity sha512-Q75CjnzRCDzgIlgWfPnkLtrfF4t82JCirhalXkSSwe/c1GH5pWh4xUyDOR3KTMo+YxxX3zTlrL/FjHmUJEWEcg== +"@algolia/recommend@4.23.3": + version "4.23.3" + resolved "https://registry.yarnpkg.com/@algolia/recommend/-/recommend-4.23.3.tgz#53d4f194d22d9c72dc05f3f7514c5878f87c5890" + integrity sha512-9fK4nXZF0bFkdcLBRDexsnGzVmu4TSYZqxdpgBW2tEyfuSSY54D4qSRkLmNkrrz4YFvdh2GM1gA8vSsnZPR73w== dependencies: - "@algolia/cache-browser-local-storage" "4.23.2" - "@algolia/cache-common" "4.23.2" - "@algolia/cache-in-memory" "4.23.2" - "@algolia/client-common" "4.23.2" - "@algolia/client-search" "4.23.2" - "@algolia/logger-common" "4.23.2" - "@algolia/logger-console" "4.23.2" - "@algolia/requester-browser-xhr" "4.23.2" - "@algolia/requester-common" "4.23.2" - "@algolia/requester-node-http" "4.23.2" - "@algolia/transporter" "4.23.2" + "@algolia/cache-browser-local-storage" "4.23.3" + "@algolia/cache-common" "4.23.3" + "@algolia/cache-in-memory" "4.23.3" + "@algolia/client-common" "4.23.3" + "@algolia/client-search" "4.23.3" + "@algolia/logger-common" "4.23.3" + "@algolia/logger-console" "4.23.3" + "@algolia/requester-browser-xhr" "4.23.3" + "@algolia/requester-common" "4.23.3" + "@algolia/requester-node-http" "4.23.3" + "@algolia/transporter" "4.23.3" -"@algolia/requester-browser-xhr@4.23.2": - version "4.23.2" - resolved "https://registry.yarnpkg.com/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.23.2.tgz#2d0a6b642e2a2bbfb2e2ff3d1e82158e3e143def" - integrity sha512-TO9wLlp8+rvW9LnIfyHsu8mNAMYrqNdQ0oLF6eTWFxXfxG3k8F/Bh7nFYGk2rFAYty4Fw4XUtrv/YjeNDtM5og== +"@algolia/requester-browser-xhr@4.23.3": + version "4.23.3" + resolved "https://registry.yarnpkg.com/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.23.3.tgz#9e47e76f60d540acc8b27b4ebc7a80d1b41938b9" + integrity sha512-jDWGIQ96BhXbmONAQsasIpTYWslyjkiGu0Quydjlowe+ciqySpiDUrJHERIRfELE5+wFc7hc1Q5hqjGoV7yghw== dependencies: - "@algolia/requester-common" "4.23.2" + "@algolia/requester-common" "4.23.3" -"@algolia/requester-common@4.23.2": - version "4.23.2" - resolved "https://registry.yarnpkg.com/@algolia/requester-common/-/requester-common-4.23.2.tgz#9c2e5da4dc15e65f9b9bbe5bedb419cf23092ef1" - integrity sha512-3EfpBS0Hri0lGDB5H/BocLt7Vkop0bTTLVUBB844HH6tVycwShmsV6bDR7yXbQvFP1uNpgePRD3cdBCjeHmk6Q== +"@algolia/requester-common@4.23.3": + version "4.23.3" + resolved "https://registry.yarnpkg.com/@algolia/requester-common/-/requester-common-4.23.3.tgz#7dbae896e41adfaaf1d1fa5f317f83a99afb04b3" + integrity sha512-xloIdr/bedtYEGcXCiF2muajyvRhwop4cMZo+K2qzNht0CMzlRkm8YsDdj5IaBhshqfgmBb3rTg4sL4/PpvLYw== -"@algolia/requester-node-http@4.23.2": - version "4.23.2" - resolved "https://registry.yarnpkg.com/@algolia/requester-node-http/-/requester-node-http-4.23.2.tgz#718ae71f58949eab3b5fcfc440be42af41bd640f" - integrity sha512-SVzgkZM/malo+2SB0NWDXpnT7nO5IZwuDTaaH6SjLeOHcya1o56LSWXk+3F3rNLz2GVH+I/rpYKiqmHhSOjerw== +"@algolia/requester-node-http@4.23.3": + version "4.23.3" + resolved "https://registry.yarnpkg.com/@algolia/requester-node-http/-/requester-node-http-4.23.3.tgz#c9f94a5cb96a15f48cea338ab6ef16bbd0ff989f" + integrity sha512-zgu++8Uj03IWDEJM3fuNl34s746JnZOWn1Uz5taV1dFyJhVM/kTNw9Ik7YJWiUNHJQXcaD8IXD1eCb0nq/aByA== dependencies: - "@algolia/requester-common" "4.23.2" + "@algolia/requester-common" "4.23.3" -"@algolia/transporter@4.23.2": - version "4.23.2" - resolved "https://registry.yarnpkg.com/@algolia/transporter/-/transporter-4.23.2.tgz#61e7b9288d4f561b2015ddde689ba31e08c21644" - integrity sha512-GY3aGKBy+8AK4vZh8sfkatDciDVKad5rTY2S10Aefyjh7e7UGBP4zigf42qVXwU8VOPwi7l/L7OACGMOFcjB0Q== +"@algolia/transporter@4.23.3": + version "4.23.3" + resolved "https://registry.yarnpkg.com/@algolia/transporter/-/transporter-4.23.3.tgz#545b045b67db3850ddf0bbecbc6c84ff1f3398b7" + integrity sha512-Wjl5gttqnf/gQKJA+dafnD0Y6Yw97yvfY8R9h0dQltX1GXTgNs1zWgvtWW0tHl1EgMdhAyw189uWiZMnL3QebQ== dependencies: - "@algolia/cache-common" "4.23.2" - "@algolia/logger-common" "4.23.2" - "@algolia/requester-common" "4.23.2" + "@algolia/cache-common" "4.23.3" + "@algolia/logger-common" "4.23.3" + "@algolia/requester-common" "4.23.3" "@ampproject/remapping@^2.2.0": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" - integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== + version "2.3.0" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4" + integrity sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw== dependencies: - "@jridgewell/gen-mapping" "^0.3.0" - "@jridgewell/trace-mapping" "^0.3.9" + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.24" "@apideck/better-ajv-errors@^0.3.1": version "0.3.6" @@ -196,15 +196,7 @@ dependencies: "@babel/highlight" "^7.10.4" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.0", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.23.5", "@babel/code-frame@^7.8.3": - version "7.23.5" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.23.5.tgz#9009b69a8c602293476ad598ff53e4562e15c244" - integrity sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA== - dependencies: - "@babel/highlight" "^7.23.4" - chalk "^2.4.2" - -"@babel/code-frame@^7.24.1", "@babel/code-frame@^7.24.2": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.0", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.23.5", "@babel/code-frame@^7.24.1", "@babel/code-frame@^7.24.2", "@babel/code-frame@^7.8.3": version "7.24.2" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.2.tgz#718b4b19841809a58b29b68cde80bc5e1aa6d9ae" integrity sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ== @@ -212,15 +204,10 @@ "@babel/highlight" "^7.24.2" picocolors "^1.0.0" -"@babel/compat-data@^7.20.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.23.2", "@babel/compat-data@^7.23.5": - version "7.23.5" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.5.tgz#ffb878728bb6bdcb6f4510aa51b1be9afb8cfd98" - integrity sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw== - -"@babel/compat-data@^7.24.1": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.24.1.tgz#31c1f66435f2a9c329bb5716a6d6186c516c3742" - integrity sha512-Pc65opHDliVpRHuKfzI+gSA4zcgr65O4cl64fFJIWEEh8JoHIHh0Oez1Eo8Arz8zq/JhgKodQaxEwUPRtZylVA== +"@babel/compat-data@^7.20.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.23.2", "@babel/compat-data@^7.23.5", "@babel/compat-data@^7.24.4": + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.24.4.tgz#6f102372e9094f25d908ca0d34fc74c74606059a" + integrity sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ== "@babel/core@7.12.9": version "7.12.9" @@ -244,39 +231,18 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/core@^7.11.1", "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.18.6", "@babel/core@^7.19.6", "@babel/core@^7.23.2": - version "7.23.6" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.6.tgz#8be77cd77c55baadcc1eae1c33df90ab6d2151d4" - integrity sha512-FxpRyGjrMJXh7X3wGLGhNDCRiwpWEF74sKjTLDJSG5Kyvow3QZaG0Adbqzi9ZrVjTWpsX+2cxWXD71NMg93kdw== - dependencies: - "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.23.5" - "@babel/generator" "^7.23.6" - "@babel/helper-compilation-targets" "^7.23.6" - "@babel/helper-module-transforms" "^7.23.3" - "@babel/helpers" "^7.23.6" - "@babel/parser" "^7.23.6" - "@babel/template" "^7.22.15" - "@babel/traverse" "^7.23.6" - "@babel/types" "^7.23.6" - convert-source-map "^2.0.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.2.3" - semver "^6.3.1" - -"@babel/core@^7.18.9", "@babel/core@^7.23.0": - version "7.24.3" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.24.3.tgz#568864247ea10fbd4eff04dda1e05f9e2ea985c3" - integrity sha512-5FcvN1JHw2sHJChotgx8Ek0lyuh4kCKelgMTTqhYJJtloNvUfpAFMeNQUtdlIaktwrSV9LtCdqwk48wL2wBacQ== +"@babel/core@^7.11.1", "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.18.6", "@babel/core@^7.18.9", "@babel/core@^7.19.6", "@babel/core@^7.23.0", "@babel/core@^7.23.2", "@babel/core@^7.23.9": + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.24.4.tgz#1f758428e88e0d8c563874741bc4ffc4f71a4717" + integrity sha512-MBVlMXP+kkl5394RBLSxxk/iLTeVGuXTV3cIDXavPpMMqnSnt6apKgan/U8O3USWZCWZT/TbgfEpKa4uMgN4Dg== dependencies: "@ampproject/remapping" "^2.2.0" "@babel/code-frame" "^7.24.2" - "@babel/generator" "^7.24.1" + "@babel/generator" "^7.24.4" "@babel/helper-compilation-targets" "^7.23.6" "@babel/helper-module-transforms" "^7.23.3" - "@babel/helpers" "^7.24.1" - "@babel/parser" "^7.24.1" + "@babel/helpers" "^7.24.4" + "@babel/parser" "^7.24.4" "@babel/template" "^7.24.0" "@babel/traverse" "^7.24.1" "@babel/types" "^7.24.0" @@ -286,41 +252,10 @@ json5 "^2.2.3" semver "^6.3.1" -"@babel/core@^7.23.9": - version "7.24.0" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.24.0.tgz#56cbda6b185ae9d9bed369816a8f4423c5f2ff1b" - integrity sha512-fQfkg0Gjkza3nf0c7/w6Xf34BW4YvzNfACRLmmb7XRLa6XHdR+K9AlJlxneFfWYf6uhOzuzZVTjF/8KfndZANw== - dependencies: - "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.23.5" - "@babel/generator" "^7.23.6" - "@babel/helper-compilation-targets" "^7.23.6" - "@babel/helper-module-transforms" "^7.23.3" - "@babel/helpers" "^7.24.0" - "@babel/parser" "^7.24.0" - "@babel/template" "^7.24.0" - "@babel/traverse" "^7.24.0" - "@babel/types" "^7.24.0" - convert-source-map "^2.0.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.2.3" - semver "^6.3.1" - -"@babel/generator@^7.12.5", "@babel/generator@^7.18.7", "@babel/generator@^7.23.0", "@babel/generator@^7.23.6", "@babel/generator@^7.7.2": - version "7.23.6" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.6.tgz#9e1fca4811c77a10580d17d26b57b036133f3c2e" - integrity sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw== - dependencies: - "@babel/types" "^7.23.6" - "@jridgewell/gen-mapping" "^0.3.2" - "@jridgewell/trace-mapping" "^0.3.17" - jsesc "^2.5.1" - -"@babel/generator@^7.24.1": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.24.1.tgz#e67e06f68568a4ebf194d1c6014235344f0476d0" - integrity sha512-DfCRfZsBcrPEHUfuBMgbJ1Ut01Y/itOs+hY2nFLgqsqXd52/iSiVq5TITtUasIUgm+IIKdY2/1I7auiQOEeC9A== +"@babel/generator@^7.12.5", "@babel/generator@^7.18.7", "@babel/generator@^7.23.0", "@babel/generator@^7.24.1", "@babel/generator@^7.24.4", "@babel/generator@^7.7.2": + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.24.4.tgz#1fc55532b88adf952025d5d2d1e71f946cb1c498" + integrity sha512-Xd6+v6SnjWVx/nus+y0l1sxMOTOMBkyL4+BIdbALyatQnAe/SRVjANeDPSCYaX+i1iJmuGSKf3Z+E+V/va1Hvw== dependencies: "@babel/types" "^7.24.0" "@jridgewell/gen-mapping" "^0.3.5" @@ -352,25 +287,10 @@ lru-cache "^5.1.1" semver "^6.3.1" -"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.21.0": - version "7.23.9" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.9.tgz#fddfdf51fca28f23d16b9e3935a4732690acfad6" - integrity sha512-B2L9neXTIyPQoXDm+NtovPvG6VOLWnaXu3BIeVDWwdKFgG30oNa6CqVGiJPDWQwIAK49t9gnQI9c6K6RzabiKw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-function-name" "^7.23.0" - "@babel/helper-member-expression-to-functions" "^7.23.0" - "@babel/helper-optimise-call-expression" "^7.22.5" - "@babel/helper-replace-supers" "^7.22.20" - "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.6" - semver "^6.3.1" - -"@babel/helper-create-class-features-plugin@^7.24.1": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.1.tgz#db58bf57137b623b916e24874ab7188d93d7f68f" - integrity sha512-1yJa9dX9g//V6fDebXoEfEsxkZHk3Hcbm+zLhyu6qVgYFLvmTALTeV+jNU9e5RnYtioBrGEOdoI2joMSNQ/+aA== +"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.21.0", "@babel/helper-create-class-features-plugin@^7.24.1", "@babel/helper-create-class-features-plugin@^7.24.4": + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.4.tgz#c806f73788a6800a5cfbbc04d2df7ee4d927cce3" + integrity sha512-lG75yeuUSVu0pIcbhiYMXBXANHrpUPaOfu7ryAzskCgKUHuAxRQI5ssrtmF0X9UXldPlvT0XM/A4F44OXRt6iQ== dependencies: "@babel/helper-annotate-as-pure" "^7.22.5" "@babel/helper-environment-visitor" "^7.22.20" @@ -495,7 +415,7 @@ "@babel/helper-environment-visitor" "^7.22.20" "@babel/helper-wrap-function" "^7.22.20" -"@babel/helper-replace-supers@^7.22.20", "@babel/helper-replace-supers@^7.24.1": +"@babel/helper-replace-supers@^7.24.1": version "7.24.1" resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.24.1.tgz#7085bd19d4a0b7ed8f405c1ed73ccb70f323abc1" integrity sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ== @@ -549,16 +469,16 @@ "@babel/template" "^7.22.15" "@babel/types" "^7.22.19" -"@babel/helpers@^7.12.5", "@babel/helpers@^7.23.6", "@babel/helpers@^7.24.0", "@babel/helpers@^7.24.1": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.24.1.tgz#183e44714b9eba36c3038e442516587b1e0a1a94" - integrity sha512-BpU09QqEe6ZCHuIHFphEFgvNSrubve1FtyMton26ekZ85gRGi6LrTF7zArARp2YvyFxloeiRmtSCq5sjh1WqIg== +"@babel/helpers@^7.12.5", "@babel/helpers@^7.24.4": + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.24.4.tgz#dc00907fd0d95da74563c142ef4cd21f2cb856b6" + integrity sha512-FewdlZbSiwaVGlgT1DPANDuCHaDMiOo+D/IDYRFYjHOuv66xMSJ7fQwwODwRNAPkADIO/z1EoF/l2BCWlWABDw== dependencies: "@babel/template" "^7.24.0" "@babel/traverse" "^7.24.1" "@babel/types" "^7.24.0" -"@babel/highlight@^7.10.4", "@babel/highlight@^7.23.4", "@babel/highlight@^7.24.2": +"@babel/highlight@^7.10.4", "@babel/highlight@^7.24.2": version "7.24.2" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.24.2.tgz#3f539503efc83d3c59080a10e6634306e0370d26" integrity sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA== @@ -568,10 +488,18 @@ js-tokens "^4.0.0" picocolors "^1.0.0" -"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.12.7", "@babel/parser@^7.14.7", "@babel/parser@^7.18.8", "@babel/parser@^7.20.7", "@babel/parser@^7.23.0", "@babel/parser@^7.23.6", "@babel/parser@^7.23.9", "@babel/parser@^7.24.0", "@babel/parser@^7.24.1", "@babel/parser@^7.7.0": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.1.tgz#1e416d3627393fab1cb5b0f2f1796a100ae9133a" - integrity sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg== +"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.12.7", "@babel/parser@^7.14.7", "@babel/parser@^7.18.8", "@babel/parser@^7.20.7", "@babel/parser@^7.23.0", "@babel/parser@^7.23.9", "@babel/parser@^7.24.0", "@babel/parser@^7.24.1", "@babel/parser@^7.24.4", "@babel/parser@^7.7.0": + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.4.tgz#234487a110d89ad5a3ed4a8a566c36b9453e8c88" + integrity sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg== + +"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.24.4": + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.4.tgz#6125f0158543fb4edf1c22f322f3db67f21cb3e1" + integrity sha512-qpl6vOOEEzTLLcsuqYYo8yDtrTocmu2xkGvgNebvPjT9DTtfFYGmgDqY+rBYXNlqL4s9qLDn6xkrJv4RxAPiTA== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-plugin-utils" "^7.24.0" "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.22.15", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.24.1": version "7.24.1" @@ -843,10 +771,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-transform-block-scoping@^7.23.0", "@babel/plugin-transform-block-scoping@^7.24.1": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.1.tgz#27af183d7f6dad890531256c7a45019df768ac1f" - integrity sha512-h71T2QQvDgM2SmT29UYU6ozjMlAt7s7CSs5Hvy8f8cf/GM/Z4a2zMfN+fjVGaieeCrXR3EdQl6C4gQG+OgmbKw== +"@babel/plugin-transform-block-scoping@^7.23.0", "@babel/plugin-transform-block-scoping@^7.24.4": + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.4.tgz#28f5c010b66fbb8ccdeef853bef1935c434d7012" + integrity sha512-nIFUZIpGKDf9O9ttyRXpHFpKC+X3Y5mtshZONuEUYBomAKoM4y029Jr+uB1bHGPhNmK8YXHevDtKDOLmtRrp6g== dependencies: "@babel/helper-plugin-utils" "^7.24.0" @@ -858,12 +786,12 @@ "@babel/helper-create-class-features-plugin" "^7.24.1" "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-transform-class-static-block@^7.22.11", "@babel/plugin-transform-class-static-block@^7.24.1": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.1.tgz#4e37efcca1d9f2fcb908d1bae8b56b4b6e9e1cb6" - integrity sha512-FUHlKCn6J3ERiu8Dv+4eoz7w8+kFLSyeVG4vDAikwADGjUCoHw/JHokyGtr8OR4UjpwPVivyF+h8Q5iv/JmrtA== +"@babel/plugin-transform-class-static-block@^7.22.11", "@babel/plugin-transform-class-static-block@^7.24.4": + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.4.tgz#1a4653c0cf8ac46441ec406dece6e9bc590356a4" + integrity sha512-B8q7Pz870Hz/q9UgP8InNpY01CSLDSCyqX7zcRuv3FcPl87A2G17lASroHWaCtbdIcbYzOZ7kWmXFKbijMSmFg== dependencies: - "@babel/helper-create-class-features-plugin" "^7.24.1" + "@babel/helper-create-class-features-plugin" "^7.24.4" "@babel/helper-plugin-utils" "^7.24.0" "@babel/plugin-syntax-class-static-block" "^7.14.5" @@ -1227,12 +1155,12 @@ "@babel/helper-plugin-utils" "^7.24.0" "@babel/plugin-transform-typescript@^7.13.0", "@babel/plugin-transform-typescript@^7.24.1": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.24.1.tgz#5c05e28bb76c7dfe7d6c5bed9951324fd2d3ab07" - integrity sha512-liYSESjX2fZ7JyBFkYG78nfvHlMKE6IpNdTVnxmlYUR+j5ZLsitFbaAE+eJSK2zPPkNWNw4mXL51rQ8WrvdK0w== + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.24.4.tgz#03e0492537a4b953e491f53f2bc88245574ebd15" + integrity sha512-79t3CQ8+oBGk/80SQ8MN3Bs3obf83zJ0YZjDmDaEZN8MqhMI760apl5z6a20kFeMXBwJX99VpKT8CKxEBp5H1g== dependencies: "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-create-class-features-plugin" "^7.24.1" + "@babel/helper-create-class-features-plugin" "^7.24.4" "@babel/helper-plugin-utils" "^7.24.0" "@babel/plugin-syntax-typescript" "^7.24.1" @@ -1354,14 +1282,15 @@ semver "^6.3.1" "@babel/preset-env@^7.11.0", "@babel/preset-env@^7.12.1", "@babel/preset-env@^7.18.6", "@babel/preset-env@^7.19.4", "@babel/preset-env@^7.23.2": - version "7.24.3" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.24.3.tgz#f3f138c844ffeeac372597b29c51b5259e8323a3" - integrity sha512-fSk430k5c2ff8536JcPvPWK4tZDwehWLGlBp0wrsBUjZVdeQV6lePbwKWZaZfK2vnh/1kQX1PzAJWsnBmVgGJA== + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.24.4.tgz#46dbbcd608771373b88f956ffb67d471dce0d23b" + integrity sha512-7Kl6cSmYkak0FK/FXjSEnLJ1N9T/WA2RkMhu17gZ/dsxKJUuTYNIylahPTzqpLyJN4WhDif8X0XK1R8Wsguo/A== dependencies: - "@babel/compat-data" "^7.24.1" + "@babel/compat-data" "^7.24.4" "@babel/helper-compilation-targets" "^7.23.6" "@babel/helper-plugin-utils" "^7.24.0" "@babel/helper-validator-option" "^7.23.5" + "@babel/plugin-bugfix-firefox-class-in-computed-class-key" "^7.24.4" "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.24.1" "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.24.1" "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.24.1" @@ -1388,9 +1317,9 @@ "@babel/plugin-transform-async-generator-functions" "^7.24.3" "@babel/plugin-transform-async-to-generator" "^7.24.1" "@babel/plugin-transform-block-scoped-functions" "^7.24.1" - "@babel/plugin-transform-block-scoping" "^7.24.1" + "@babel/plugin-transform-block-scoping" "^7.24.4" "@babel/plugin-transform-class-properties" "^7.24.1" - "@babel/plugin-transform-class-static-block" "^7.24.1" + "@babel/plugin-transform-class-static-block" "^7.24.4" "@babel/plugin-transform-classes" "^7.24.1" "@babel/plugin-transform-computed-properties" "^7.24.1" "@babel/plugin-transform-destructuring" "^7.24.1" @@ -1497,25 +1426,25 @@ integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== "@babel/runtime-corejs2@^7.17.8": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/runtime-corejs2/-/runtime-corejs2-7.24.1.tgz#2799e168a20a54a4029d162278aca26c719e726f" - integrity sha512-De0q0utpUPiXnc7+B7Ku86mJ0eDItC/v3uFa/lQkq63XnHyZiytDHeCIvechlnVwwpU2ChjGF7c3I+mBrTudwg== + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/runtime-corejs2/-/runtime-corejs2-7.24.4.tgz#3dac044ea9989e46b99b5f5ac038dbdd12e20e10" + integrity sha512-ZCKqyUKt/Coimg+3Kafu43yNetgYnTXzNbEGAgxc81J5sI0qFNbQ613w7PNny+SmijAmGVroL0GDvx5rG/JI5Q== dependencies: core-js "^2.6.12" regenerator-runtime "^0.14.0" "@babel/runtime-corejs3@^7.18.6", "@babel/runtime-corejs3@^7.22.5": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.24.1.tgz#f39707b213441dec645ce8285ae14f281a5077c6" - integrity sha512-T9ko/35G+Bkl+win48GduaPlhSlOjjE5s1TeiEcD+QpxlLQnoEfb/nO/T+TQqkm+ipFwORn+rB8w14iJ/uD0bg== + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.24.4.tgz#b9ebe728087cfbb22bbaccc6f9a70d69834124a0" + integrity sha512-VOQOexSilscN24VEY810G/PqtpFvx/z6UqDIjIWbDe2368HhDLkYN5TYwaEz/+eRCUkhJ2WaNLLmQAlxzfWj4w== dependencies: core-js-pure "^3.30.2" regenerator-runtime "^0.14.0" "@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.24.1" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.1.tgz#431f9a794d173b53720e69a6464abc6f0e2a5c57" - integrity sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ== + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.4.tgz#de795accd698007a66ba44add6cc86542aff1edd" + integrity sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA== dependencies: regenerator-runtime "^0.14.0" @@ -1528,7 +1457,7 @@ "@babel/parser" "^7.24.0" "@babel/types" "^7.24.0" -"@babel/traverse@^7.0.0", "@babel/traverse@^7.12.9", "@babel/traverse@^7.18.8", "@babel/traverse@^7.18.9", "@babel/traverse@^7.23.2", "@babel/traverse@^7.23.6", "@babel/traverse@^7.24.0", "@babel/traverse@^7.24.1", "@babel/traverse@^7.7.0": +"@babel/traverse@^7.0.0", "@babel/traverse@^7.12.9", "@babel/traverse@^7.18.8", "@babel/traverse@^7.18.9", "@babel/traverse@^7.23.2", "@babel/traverse@^7.24.1", "@babel/traverse@^7.7.0": version "7.24.1" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.24.1.tgz#d65c36ac9dd17282175d1e4a3c49d5b7988f530c" integrity sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ== @@ -1544,7 +1473,7 @@ debug "^4.3.1" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.12.6", "@babel/types@^7.12.7", "@babel/types@^7.18.9", "@babel/types@^7.20.0", "@babel/types@^7.20.7", "@babel/types@^7.22.15", "@babel/types@^7.22.19", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.23.4", "@babel/types@^7.23.6", "@babel/types@^7.24.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4", "@babel/types@^7.7.0": +"@babel/types@^7.0.0", "@babel/types@^7.12.6", "@babel/types@^7.12.7", "@babel/types@^7.18.9", "@babel/types@^7.20.0", "@babel/types@^7.20.7", "@babel/types@^7.22.15", "@babel/types@^7.22.19", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.23.4", "@babel/types@^7.24.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4", "@babel/types@^7.7.0": version "7.24.0" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.24.0.tgz#3b951f435a92e7333eba05b7566fd297960ea1bf" integrity sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w== @@ -1568,13 +1497,13 @@ resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== -"@cornerstonejs/adapters@^1.70.5": - version "1.70.5" - resolved "https://registry.yarnpkg.com/@cornerstonejs/adapters/-/adapters-1.70.5.tgz#aa1e706a18b1e5d597b1b95bac928ee85b400a33" - integrity sha512-Jmxqz8crNx37jSBmlsfAKxKHi4wj0vICPzvCQ3c5F4+rSaEswD3JefHfzrNCk1xMaAGE7hkA7szWNDVCoovDBQ== +"@cornerstonejs/adapters@^1.70.6": + version "1.70.6" + resolved "https://registry.yarnpkg.com/@cornerstonejs/adapters/-/adapters-1.70.6.tgz#9e04d70af0f69c722a04d55dbe8daaf3023c6d70" + integrity sha512-V5exbaXTcy+jyoCA8IhajEwUMu0QJWjioDZyE6jHtUlL/wlB4cKx5CjD1rSzAnuLPKIcf6mX8MbUsAfsTOj+/g== dependencies: "@babel/runtime-corejs2" "^7.17.8" - "@cornerstonejs/tools" "^1.70.5" + "@cornerstonejs/tools" "^1.70.6" buffer "^6.0.3" dcmjs "^0.29.8" gl-matrix "^3.4.3" @@ -1621,45 +1550,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.70.5": - version "1.70.5" - resolved "https://registry.yarnpkg.com/@cornerstonejs/core/-/core-1.70.5.tgz#4667c018a22f06e83548d230c55a4c8d6b6630ea" - integrity sha512-cqSRLA3V6C1MAQ+S5EQoNdxuTG0c/c8bULZ9XKiZYd9YIY26wDsboDJ9a+vzJWNxw9ZFDW0H0F+zJsIu64a3ig== +"@cornerstonejs/core@^1.70.6": + version "1.70.6" + resolved "https://registry.yarnpkg.com/@cornerstonejs/core/-/core-1.70.6.tgz#8a78696b1b2a79909d034a223988844e805a8154" + integrity sha512-XOEVS9qK2gQHwuKZJc21I2ImcFNFHIyDXGQjYLOTe6reUlWow9y1ZqvLMF+dVhRs7WVNAwJNPibe5ky8759dkw== dependencies: - "@kitware/vtk.js" "30.3.1" + "@kitware/vtk.js" "30.3.3" comlink "^4.4.1" detect-gpu "^5.0.22" gl-matrix "^3.4.3" lodash.clonedeep "4.5.0" -"@cornerstonejs/dicom-image-loader@^1.70.5": - version "1.70.5" - resolved "https://registry.yarnpkg.com/@cornerstonejs/dicom-image-loader/-/dicom-image-loader-1.70.5.tgz#6d41e3ee1df8ba659bb5bc69f660b421cd38d0ad" - integrity sha512-j8kNnzv5bE2A8jVEXdDFY1ZXoowNGRRAFCO1FlO0aU7yA3YwRXNAeAerJCRJROxl6E//Bsj2WbjRd+mPXE4JVg== +"@cornerstonejs/dicom-image-loader@^1.70.6": + version "1.70.6" + resolved "https://registry.yarnpkg.com/@cornerstonejs/dicom-image-loader/-/dicom-image-loader-1.70.6.tgz#ce16e2a4544768a55fbcb916391850908276a606" + integrity sha512-KZNR+i9CdjWvzPxWzhUon2H9IAsvg9Axdzj2qQgM/8+sVz2yKa6TPxlnLKFlW8QEwuZsP/AHkVQuqzJ92PVnlw== 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.70.5" + "@cornerstonejs/core" "^1.70.6" dicom-parser "^1.8.9" pako "^2.0.4" uuid "^9.0.0" -"@cornerstonejs/streaming-image-volume-loader@^1.70.5": - version "1.70.5" - resolved "https://registry.yarnpkg.com/@cornerstonejs/streaming-image-volume-loader/-/streaming-image-volume-loader-1.70.5.tgz#d6044b4258e28b38c00e8463afef064af85bd3ec" - integrity sha512-p7NZBixKRmQtZ4/auUvGEsX78/Xcdb6D5gG+hjk1ScF3d9kX5uafgBMj1aBQuO9WlcU6r7AGdIRy4hfGW+s/2w== +"@cornerstonejs/streaming-image-volume-loader@^1.70.6": + version "1.70.6" + resolved "https://registry.yarnpkg.com/@cornerstonejs/streaming-image-volume-loader/-/streaming-image-volume-loader-1.70.6.tgz#00c6ba40e9a5fc14409d56b08f1512d3e24df6d5" + integrity sha512-A78awLgJh1bl6zq7SbjeXjn/vIFX3Q5rb4hAlk09/rFwmNJtJbxH4z6/gUnVBh/rLSDnpyxzie4VgJje3/WPRQ== dependencies: - "@cornerstonejs/core" "^1.70.5" + "@cornerstonejs/core" "^1.70.6" comlink "^4.4.1" -"@cornerstonejs/tools@^1.70.5": - version "1.70.5" - resolved "https://registry.yarnpkg.com/@cornerstonejs/tools/-/tools-1.70.5.tgz#ebf7700516169c8283d44d146e5e995ed42dd1a2" - integrity sha512-gIo+JfcduvmxpQSXj3BX0N7IwkQZg9yGhexTToSDPo/kpAs5ju2rbnEK++y7kT5zn+G9blDzz9q1clS+++q90w== +"@cornerstonejs/tools@^1.70.6": + version "1.70.6" + resolved "https://registry.yarnpkg.com/@cornerstonejs/tools/-/tools-1.70.6.tgz#6e4fe7872dd9aed32062cc76d59c9b567012b408" + integrity sha512-Su3bzD6y0k9VjxDGkyh6QM6HHW/QJ4PzfpfE5fYpGeQzHJnpjmUpM5/YTBnRMxlqtI8IW8EJuKUgMMjnzvsQfw== dependencies: - "@cornerstonejs/core" "^1.70.5" + "@cornerstonejs/core" "^1.70.6" "@icr/polyseg-wasm" "0.4.0" "@types/offscreencanvas" "2019.7.3" comlink "^4.4.1" @@ -2386,9 +2315,9 @@ hoist-non-react-statics "^3.3.1" "@emotion/serialize@^1.1.2", "@emotion/serialize@^1.1.3": - version "1.1.3" - resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.3.tgz#84b77bfcfe3b7bb47d326602f640ccfcacd5ffb0" - integrity sha512-iD4D6QVZFDhcbH0RAG1uVu1CwVLMWUkCvAqqlewO/rxf8+87yIBAlt4+AxMiiKPLs5hFc0owNk/sLLAOROw3cA== + version "1.1.4" + resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.4.tgz#fc8f6d80c492cfa08801d544a05331d1cc7cd451" + integrity sha512-RIN04MBT8g+FnDwgvIUi8czvr1LU1alUMI05LekWB5DGyTm8cCBMCRpq3GqaiyEDRptEXOyXnvZ58GZYu4kBxQ== dependencies: "@emotion/hash" "^0.9.1" "@emotion/memoize" "^0.8.1" @@ -2870,7 +2799,7 @@ "@types/yargs" "^17.0.8" chalk "^4.0.0" -"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2", "@jridgewell/gen-mapping@^0.3.5": +"@jridgewell/gen-mapping@^0.3.5": version "0.3.5" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36" integrity sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg== @@ -2902,7 +2831,7 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== -"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.20", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25", "@jridgewell/trace-mapping@^0.3.9": +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.20", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": version "0.3.25" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== @@ -2915,10 +2844,10 @@ 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@30.3.1": - version "30.3.1" - resolved "https://registry.yarnpkg.com/@kitware/vtk.js/-/vtk.js-30.3.1.tgz#0ded19add5b8a5b9b0fb41063a58ec1b6b46c9db" - integrity sha512-nM3cyTSfQKqpVtdBPk/Gt2ZJfYW5v3swNUFzXFw2OyC+QW1aAHhAfXmUDayasoCZox3yvo3Lnx3V4ztScEYybQ== +"@kitware/vtk.js@30.3.3": + version "30.3.3" + resolved "https://registry.yarnpkg.com/@kitware/vtk.js/-/vtk.js-30.3.3.tgz#348e17fdc896c912eca7036f607d21ef6128bca1" + integrity sha512-es9I5LLlg+TpaIXk5aHSPzyI/YnCI4egHA1cbG98IP7t9W4KODUcJjyrXFAa7aSvfXZ8y2jhD9qrsaEnstEkJA== dependencies: "@babel/runtime" "7.22.11" "@types/webxr" "^0.5.5" @@ -4840,74 +4769,74 @@ "@svgr/plugin-jsx" "^6.5.1" "@svgr/plugin-svgo" "^6.5.1" -"@swc/core-darwin-arm64@1.4.11": - version "1.4.11" - resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.4.11.tgz#91ef40816e10495a4038a98dc6c8dfcc85d9c59b" - integrity sha512-C1j1Qp/IHSelVWdEnT7f0iONWxQz6FAqzjCF2iaL+0vFg4V5f2nlgrueY8vj5pNNzSGhrAlxsMxEIp4dj1MXkg== +"@swc/core-darwin-arm64@1.4.13": + version "1.4.13" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.4.13.tgz#9b1ff4477a9b9eb76275e1dd1af52fbe8d11a0d3" + integrity sha512-36P72FLpm5iq85IvoEjBvi22DiqkkEIanJ1M0E8bkxcFHUbjBrYfPY9T6cpPyK5oQqkaTBvNAc3j1BlVD6IH6w== -"@swc/core-darwin-x64@1.4.11": - version "1.4.11" - resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.4.11.tgz#6f71e3cd4687ef5df226ba0b8a20adc52fa7dc9e" - integrity sha512-0TTy3Ni8ncgaMCchSQ7FK8ZXQLlamy0FXmGWbR58c+pVZWYZltYPTmheJUvVcR0H2+gPAymRKyfC0iLszDALjg== +"@swc/core-darwin-x64@1.4.13": + version "1.4.13" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.4.13.tgz#a293492337e337404742988897f7d3befce83d4b" + integrity sha512-ye7OgKpDdyA8AMIVVdmD1ICDaFXgoEXORnVO8bBHyul0WN71yUBZMX+YxEx2lpWtiftA2vY/1MAuOR80vHkBCw== -"@swc/core-linux-arm-gnueabihf@1.4.11": - version "1.4.11" - resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.4.11.tgz#08521822b5510cb506bc49e728f416636ff0306f" - integrity sha512-XJLB71uw0rog4DjYAPxFGAuGCBQpgJDlPZZK6MTmZOvI/1t0+DelJ24IjHIxk500YYM26Yv47xPabqFPD7I2zQ== +"@swc/core-linux-arm-gnueabihf@1.4.13": + version "1.4.13" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.4.13.tgz#685016a0b2ed7195e2aa78d92a0aea0dc2567610" + integrity sha512-+x593Jlmu4c3lJtZUKRejWpV2MAij1Js5nmQLLdjo6ChR2D4B2rzj3iMiKn5gITew7fraF9t3fvXALdWh7HmUg== -"@swc/core-linux-arm64-gnu@1.4.11": - version "1.4.11" - resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.4.11.tgz#9485bc591aa573b282d08b168b80a60badb8df9b" - integrity sha512-vYQwzJvm/iu052d5Iw27UFALIN5xSrGkPZXxLNMHPySVko2QMNNBv35HLatkEQHbQ3X+VKSW9J9SkdtAvAVRAQ== +"@swc/core-linux-arm64-gnu@1.4.13": + version "1.4.13" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.4.13.tgz#ef4fd6552c508e2196bad152330123205d34dca7" + integrity sha512-0x8OVw4dfyNerrs/9eZX9wNnmvwbwXSMCi+LbE6Xt1pXOIwvoLtFIXcV3NsrlkFboO3sr5UAQIwDxKqbIZA9pQ== -"@swc/core-linux-arm64-musl@1.4.11": - version "1.4.11" - resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.4.11.tgz#85eecad7aaab7e94b1ff15ab9d95e80a1e95f356" - integrity sha512-eV+KduiRYUFjPsvbZuJ9aknQH9Tj0U2/G9oIZSzLx/18WsYi+upzHbgxmIIHJ2VJgfd7nN40RI/hMtxNsUzR/g== +"@swc/core-linux-arm64-musl@1.4.13": + version "1.4.13" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.4.13.tgz#214b7d3469366e880a3d69b23846ad217203b798" + integrity sha512-Z9c4JiequtZvngPcxbCuAOkmWBxi2vInZbjjhD5I+Q9oiJdXUz1t2USGwsGPS41Xvk1BOA3ecK2Sn1ilY3titg== -"@swc/core-linux-x64-gnu@1.4.11": - version "1.4.11" - resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.4.11.tgz#16259de893489b4699045e36bf52b2afe5d10f6d" - integrity sha512-WA1iGXZ2HpqM1OR9VCQZJ8sQ1KP2or9O4bO8vWZo6HZJIeoQSo7aa9waaCLRpkZvkng1ct/TF/l6ymqSNFXIzQ== +"@swc/core-linux-x64-gnu@1.4.13": + version "1.4.13" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.4.13.tgz#f165ab1baa4cc7eea997ee58db7eb860608f4b1d" + integrity sha512-ChatHtk+vX0Ke5QG+jO+rIapw/KwZsi9MedCBHFXHH6iWF4z8d51cJeN68ykcn+vAXzjNeFNdlNy5Vbkd1zAqg== -"@swc/core-linux-x64-musl@1.4.11": - version "1.4.11" - resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.4.11.tgz#0f4e644fc2b62c8c966072389d354337a22b4dde" - integrity sha512-UkVJToKf0owwQYRnGvjHAeYVDfeimCEcx0VQSbJoN7Iy0ckRZi7YPlmWJU31xtKvikE2bQWCOVe0qbSDqqcWXA== +"@swc/core-linux-x64-musl@1.4.13": + version "1.4.13" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.4.13.tgz#18c3748ca0aa50a4062ee61de7b41af92c3753c7" + integrity sha512-0Pz39YR530mXpsztwQkmEKdkkZy4fY4Smdh4pkm6Ly8Nndyo0te/l4bcAGqN24Jp7aVwF/QSy14SAtw4HRjU9g== -"@swc/core-win32-arm64-msvc@1.4.11": - version "1.4.11" - resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.4.11.tgz#d836b79d8730bf83e6b38a5b888e83944d6fb233" - integrity sha512-35khwkyly7lF5NDSyvIrukBMzxPorgc5iTSDfVO/LvnmN5+fm4lTlrDr4tUfTdOhv3Emy7CsKlsNAeFRJ+Pm+w== +"@swc/core-win32-arm64-msvc@1.4.13": + version "1.4.13" + resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.4.13.tgz#89f60481ad06b39ca6b9e56593564fb9bd86b886" + integrity sha512-LVZfhlD+jHcAbz5NN+gAJ1BEasB0WpcvUzcsJt0nQSRsojgzPzFjJ+fzEBnvT7SMtqKkrnVJ0OmDYeh88bDRpw== -"@swc/core-win32-ia32-msvc@1.4.11": - version "1.4.11" - resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.4.11.tgz#bc60bbdc65134aaa5b214e2aaf209acfce401d17" - integrity sha512-Wx8/6f0ufgQF2pbVPsJ2dAmFLwIOW+xBE5fxnb7VnEbGkTgP1qMDWiiAtD9rtvDSuODG3i1AEmAak/2HAc6i6A== +"@swc/core-win32-ia32-msvc@1.4.13": + version "1.4.13" + resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.4.13.tgz#8f4bff548e3eae7b7ef0667f31866c5b5ee4dbfa" + integrity sha512-78hxHWUvUZtWsnhcf8DKwhBcNFJw+j4y4fN2B9ioXmBWX2tIyw+BqUHOrismOtjPihaZmwe/Ok2e4qmkawE2fw== -"@swc/core-win32-x64-msvc@1.4.11": - version "1.4.11" - resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.4.11.tgz#92fd6d4e2d70bbd4fda438f02310d998db8c7b7c" - integrity sha512-0xRFW6K9UZQH2NVC/0pVB0GJXS45lY24f+6XaPBF1YnMHd8A8GoHl7ugyM5yNUTe2AKhSgk5fJV00EJt/XBtdQ== +"@swc/core-win32-x64-msvc@1.4.13": + version "1.4.13" + resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.4.13.tgz#57fb58f6c81526b17c432db3159bf540bd977a12" + integrity sha512-WSfy1u2Xde6jU7UpHIInCUMW98Zw9iZglddKUAvmr1obkZji5U6EX0Oca3asEJdZPFb+2lMLjt0Mh5a1YisROg== "@swc/core@^1.3.82": - version "1.4.11" - resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.4.11.tgz#e91f488df9242584cc6f1b034419f8302aeb0c85" - integrity sha512-WKEakMZxkVwRdgMN4AMJ9K5nysY8g8npgQPczmjBeNK5In7QEAZAJwnyccrWwJZU0XjVeHn2uj+XbOKdDW17rg== + version "1.4.13" + resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.4.13.tgz#c679664cae722fc404a59fc6d687e80bf7dbae99" + integrity sha512-rOtusBE+2gaeRkAJn5E4zp5yzZekZOypzSOz5ZG6P1hFbd+Cc26fWEdK6sUSnrkkvTd0Oj33KXLB/4UkbK/UHA== dependencies: "@swc/counter" "^0.1.2" "@swc/types" "^0.1.5" optionalDependencies: - "@swc/core-darwin-arm64" "1.4.11" - "@swc/core-darwin-x64" "1.4.11" - "@swc/core-linux-arm-gnueabihf" "1.4.11" - "@swc/core-linux-arm64-gnu" "1.4.11" - "@swc/core-linux-arm64-musl" "1.4.11" - "@swc/core-linux-x64-gnu" "1.4.11" - "@swc/core-linux-x64-musl" "1.4.11" - "@swc/core-win32-arm64-msvc" "1.4.11" - "@swc/core-win32-ia32-msvc" "1.4.11" - "@swc/core-win32-x64-msvc" "1.4.11" + "@swc/core-darwin-arm64" "1.4.13" + "@swc/core-darwin-x64" "1.4.13" + "@swc/core-linux-arm-gnueabihf" "1.4.13" + "@swc/core-linux-arm64-gnu" "1.4.13" + "@swc/core-linux-arm64-musl" "1.4.13" + "@swc/core-linux-x64-gnu" "1.4.13" + "@swc/core-linux-x64-musl" "1.4.13" + "@swc/core-win32-arm64-msvc" "1.4.13" + "@swc/core-win32-ia32-msvc" "1.4.13" + "@swc/core-win32-x64-msvc" "1.4.13" "@swc/counter@^0.1.2", "@swc/counter@^0.1.3": version "0.1.3" @@ -5082,9 +5011,9 @@ "@types/estree" "*" "@types/eslint@*": - version "8.56.6" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.56.6.tgz#d5dc16cac025d313ee101108ba5714ea10eb3ed0" - integrity sha512-ymwc+qb1XkjT/gfoQwxIeHZ6ixH23A+tCT2ADSA/DPVKzAjwYkTXBMCQ/f6fe4wEa85Lhp26VPeUxI7wMhAi7A== + version "8.56.8" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.56.8.tgz#e927fdc742a98fc3195a9d047631e6ab95029b50" + integrity sha512-LdDdQVDzDXf3ijhhMnE27C5vc0QEknD8GiMR/Hi+fVbdZNfAfCy2j69m0LjUd2MAy0+kIgnOtd5ndTmDk/VWCA== dependencies: "@types/estree" "*" "@types/json-schema" "*" @@ -5120,9 +5049,9 @@ "@types/node" "*" "@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.33": - version "4.17.43" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz#10d8444be560cb789c4735aea5eac6e5af45df54" - integrity sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg== + version "4.19.0" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.19.0.tgz#3ae8ab3767d98d0b682cda063c3339e1e86ccfaa" + integrity sha512-bGyep3JqPCRry1wq+O5n7oiBgGWmeIJXPjXXCo8EK0u8duZGSYar7cGqd3ML2JUsLGeB7fmc06KYo9fLGWqPvQ== dependencies: "@types/node" "*" "@types/qs" "*" @@ -5260,20 +5189,15 @@ "@types/unist" "^2" "@types/mdx@^2.0.0": - version "2.0.12" - resolved "https://registry.yarnpkg.com/@types/mdx/-/mdx-2.0.12.tgz#38db34cc8999b982beaec01399620bee6c65ef2e" - integrity sha512-H9VZ9YqE+H28FQVchC83RCs5xQ2J7mAAv6qdDEaWmXEVl3OpdH+xfrSUzQ1lp7U7oSTRZ0RvW08ASPJsYBi7Cw== + version "2.0.13" + resolved "https://registry.yarnpkg.com/@types/mdx/-/mdx-2.0.13.tgz#68f6877043d377092890ff5b298152b0a21671bd" + integrity sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw== "@types/mime-types@^2.1.0": version "2.1.4" resolved "https://registry.yarnpkg.com/@types/mime-types/-/mime-types-2.1.4.tgz#93a1933e24fed4fb9e4adc5963a63efcbb3317a2" integrity sha512-lfU4b34HOri+kAY5UheuFMWPDOI+OPceBSHZKp69gEyTL/mmJ4cnU6Y/rlme3UL3GyOn6Y42hyIEw0/q8sWx5w== -"@types/mime@*": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.4.tgz#2198ac274de6017b44d941e00261d5bc6a0e0a45" - integrity sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw== - "@types/mime@^1": version "1.3.5" resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" @@ -5315,9 +5239,9 @@ "@types/node" "*" "@types/node@*": - version "20.11.30" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.30.tgz#9c33467fc23167a347e73834f788f4b9f399d66f" - integrity sha512-dHM6ZxwlmuZaRmUPfv1p+KrdD1Dci04FbdEm/9wEMouFqxYoFl5aMkt0VMAUtYRQDyYvD41WJLukhq/ha3YuTw== + version "20.12.7" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.12.7.tgz#04080362fa3dd6c5822061aa3124f5c152cff384" + integrity sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg== dependencies: undici-types "~5.26.4" @@ -5332,9 +5256,9 @@ integrity sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw== "@types/node@^18.0.0": - version "18.19.26" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.26.tgz#18991279d0a0e53675285e8cf4a0823766349729" - integrity sha512-+wiMJsIwLOYCvUqSdKTrfkS8mpTp+MPINe6+Np4TAGFWWRWiBQ5kSq9nZGCSPkzx9mvT+uEukzpX4MOSCydcvw== + version "18.19.31" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.31.tgz#b7d4a00f7cb826b60a543cebdbda5d189aaecdcd" + integrity sha512-ArgCD39YpyyrtFKIqMDvjz79jto5fcI/SVUs2HwB+f0dAzq68yqOdyaSivLiLugSziTpNXLQrVb7RZFmdZzbhA== dependencies: undici-types "~5.26.4" @@ -5424,9 +5348,9 @@ "@types/react" "*" "@types/react@*", "@types/react@>=16": - version "18.2.73" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.73.tgz#0579548ad122660d99e00499d22e33b81e73ed94" - integrity sha512-XcGdod0Jjv84HOC7N5ziY3x+qL0AfmubvKOZ9hJjJ2yd5EE+KYjWhdOjt387e9HPheHkdggF9atTifMRtyAaRA== + version "18.2.75" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.75.tgz#45d18f384939306d35312def1bf532eb38a68562" + integrity sha512-+DNnF7yc5y0bHkBTiLKqXFe+L4B3nvOphiMY3tuA5X10esmjqk7smyBZzbGTy2vsiy/Bnzj8yFIBL8xhRacoOg== dependencies: "@types/prop-types" "*" csstype "^3.0.2" @@ -5490,13 +5414,13 @@ "@types/express" "*" "@types/serve-static@*", "@types/serve-static@^1.13.10": - version "1.15.5" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.5.tgz#15e67500ec40789a1e8c9defc2d32a896f05b033" - integrity sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ== + version "1.15.7" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.7.tgz#22174bbd74fb97fe303109738e9b5c2f3064f714" + integrity sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw== dependencies: "@types/http-errors" "*" - "@types/mime" "*" "@types/node" "*" + "@types/send" "*" "@types/sinonjs__fake-timers@8.1.1": version "8.1.1" @@ -5586,9 +5510,9 @@ source-map "^0.6.0" "@types/webxr@^0.5.5": - version "0.5.14" - resolved "https://registry.yarnpkg.com/@types/webxr/-/webxr-0.5.14.tgz#9a03121a4912ea113b31e5c9c17f164d4fff8a1f" - integrity sha512-UEMMm/Xn3DtEa+gpzUrOcDj+SJS1tk5YodjwOxcqStNhCfPcwgyC5Srg2ToVKyg2Fhq16Ffpb0UWUQHqoT9AMA== + version "0.5.15" + resolved "https://registry.yarnpkg.com/@types/webxr/-/webxr-0.5.15.tgz#21cd63e83a997c14ff91c7c537efabb787d1af09" + integrity sha512-nC9116Gd4N+CqTxqo6gvCfhAMAzgRcfS8ZsciNodHq8uwW4JCVKwhagw8yN0XmC7mHrLnWqniJpoVEiR+72Drw== "@types/ws@^8.2.2", "@types/ws@^8.5.5": version "8.5.10" @@ -6113,32 +6037,32 @@ ajv@^8.0.0, ajv@^8.0.1, ajv@^8.6.0, ajv@^8.9.0: uri-js "^4.2.2" algoliasearch-helper@^3.10.0: - version "3.16.3" - resolved "https://registry.yarnpkg.com/algoliasearch-helper/-/algoliasearch-helper-3.16.3.tgz#38c3a18e278306f565823cc7f3dd706825b4bfb9" - integrity sha512-1OuJT6sONAa9PxcOmWo5WCAT3jQSpCR9/m5Azujja7nhUQwAUDvaaAYrcmUySsrvHh74usZHbE3jFfGnWtZj8w== + version "3.17.0" + resolved "https://registry.yarnpkg.com/algoliasearch-helper/-/algoliasearch-helper-3.17.0.tgz#b8f2f98c9a49d9affb51205f8df116164050a842" + integrity sha512-R5422OiQjvjlK3VdpNQ/Qk7KsTIGeM5ACm8civGifOVWdRRV/3SgXuKmeNxe94Dz6fwj/IgpVmXbHutU4mHubg== dependencies: "@algolia/events" "^4.0.1" algoliasearch@^4.13.1, algoliasearch@^4.19.1: - version "4.23.2" - resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-4.23.2.tgz#3b7bc93d98f3965628c73a06cbf9203531324a9d" - integrity sha512-8aCl055IsokLuPU8BzLjwzXjb7ty9TPcUFFOk0pYOwsE5DMVhE3kwCMFtsCFKcnoPZK7oObm+H5mbnSO/9ioxQ== + version "4.23.3" + resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-4.23.3.tgz#e09011d0a3b0651444916a3e6bbcba064ec44b60" + integrity sha512-Le/3YgNvjW9zxIQMRhUHuhiUjAlKY/zsdZpfq4dlLqg6mEm0nL6yk+7f2hDOtLpxsgE4jSzDmvHL7nXdBp5feg== dependencies: - "@algolia/cache-browser-local-storage" "4.23.2" - "@algolia/cache-common" "4.23.2" - "@algolia/cache-in-memory" "4.23.2" - "@algolia/client-account" "4.23.2" - "@algolia/client-analytics" "4.23.2" - "@algolia/client-common" "4.23.2" - "@algolia/client-personalization" "4.23.2" - "@algolia/client-search" "4.23.2" - "@algolia/logger-common" "4.23.2" - "@algolia/logger-console" "4.23.2" - "@algolia/recommend" "4.23.2" - "@algolia/requester-browser-xhr" "4.23.2" - "@algolia/requester-common" "4.23.2" - "@algolia/requester-node-http" "4.23.2" - "@algolia/transporter" "4.23.2" + "@algolia/cache-browser-local-storage" "4.23.3" + "@algolia/cache-common" "4.23.3" + "@algolia/cache-in-memory" "4.23.3" + "@algolia/client-account" "4.23.3" + "@algolia/client-analytics" "4.23.3" + "@algolia/client-common" "4.23.3" + "@algolia/client-personalization" "4.23.3" + "@algolia/client-search" "4.23.3" + "@algolia/logger-common" "4.23.3" + "@algolia/logger-console" "4.23.3" + "@algolia/recommend" "4.23.3" + "@algolia/requester-browser-xhr" "4.23.3" + "@algolia/requester-common" "4.23.3" + "@algolia/requester-node-http" "4.23.3" + "@algolia/transporter" "4.23.3" ansi-align@^3.0.0, ansi-align@^3.0.1: version "3.0.1" @@ -6849,24 +6773,23 @@ bare-events@^2.0.0, bare-events@^2.2.0: integrity sha512-h7z00dWdG0PYOQEvChhOSWvOfkIKsdZGkWr083FgN/HyoQuebSew/cgirYqh9SCuy/hRvxc5Vy6Fw8xAmYHLkQ== bare-fs@^2.1.1: - version "2.2.2" - resolved "https://registry.yarnpkg.com/bare-fs/-/bare-fs-2.2.2.tgz#286bf54cc6f15f613bee6bb26f0c61c79fb14f06" - integrity sha512-X9IqgvyB0/VA5OZJyb5ZstoN62AzD7YxVGog13kkfYWYqJYcK0kcqLZ6TrmH5qr4/8//ejVcX4x/a0UvaogXmA== + version "2.2.3" + resolved "https://registry.yarnpkg.com/bare-fs/-/bare-fs-2.2.3.tgz#34f8b81b8c79de7ef043383c05e57d4a10392a68" + integrity sha512-amG72llr9pstfXOBOHve1WjiuKKAMnebcmMbPWDZ7BCevAoJLpugjuAPRsDINEyjT0a6tbaVx3DctkXIRbLuJw== dependencies: bare-events "^2.0.0" - bare-os "^2.0.0" bare-path "^2.0.0" streamx "^2.13.0" -bare-os@^2.0.0, bare-os@^2.1.0: +bare-os@^2.1.0: version "2.2.1" resolved "https://registry.yarnpkg.com/bare-os/-/bare-os-2.2.1.tgz#c94a258c7a408ca6766399e44675136c0964913d" integrity sha512-OwPyHgBBMkhC29Hl3O4/YfxW9n7mdTr2+SsO29XBWKKJsbgj3mnorDB80r5TiCQgQstgE5ga1qNYrpes6NvX2w== bare-path@^2.0.0, bare-path@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/bare-path/-/bare-path-2.1.0.tgz#830f17fd39842813ca77d211ebbabe238a88cb4c" - integrity sha512-DIIg7ts8bdRKwJRJrUMy/PICEaQZaPGZ26lsSx9MJSwIhSrcdHn7/C8W+XmnG/rKi6BaRcz+JO00CjZteybDtw== + version "2.1.1" + resolved "https://registry.yarnpkg.com/bare-path/-/bare-path-2.1.1.tgz#111db5bf2db0aed40081aa4ba38b8dfc2bb782eb" + integrity sha512-OHM+iwRDRMDBsSW7kl3dO62JyHdBKO3B25FB9vNQBPcGHMo4+eA8Yj41Lfbk3pS/seDY+siNge0LdRTulAau/A== dependencies: bare-os "^2.1.0" @@ -7152,9 +7075,9 @@ builtins@^1.0.3: integrity sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ== builtins@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/builtins/-/builtins-5.0.1.tgz#87f6db9ab0458be728564fa81d876d8d74552fa9" - integrity sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ== + version "5.1.0" + resolved "https://registry.yarnpkg.com/builtins/-/builtins-5.1.0.tgz#6d85eeb360c4ebc166c3fdef922a15aa7316a5e8" + integrity sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg== dependencies: semver "^7.0.0" @@ -7321,9 +7244,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001587, caniuse-lite@^1.0.30001599: - version "1.0.30001600" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001600.tgz#93a3ee17a35aa6a9f0c6ef1b2ab49507d1ab9079" - integrity sha512-+2S9/2JFhYmYaDpZvo0lKkfvuKIglrx68MwOBqMGHhQsNkLjB5xtc/TGoEPs+MxjSyN/72qer2g97nzR641mOQ== + version "1.0.30001608" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001608.tgz#7ae6e92ffb300e4b4ec2f795e0abab456ec06cc0" + integrity sha512-cjUJTQkk9fQlJR2s4HMuPMvTiRggl0rAVMtthQuyOlDWuqHXqN8azLq+pi8B2TjwKJ32diHjUqRIKeFX4z1FoA== case-sensitive-paths-webpack-plugin@^2.4.0: version "2.4.0" @@ -8269,15 +8192,15 @@ css-line-break@^2.1.0: utrie "^1.0.2" css-loader@^6.7.1, css-loader@^6.8.1: - version "6.10.0" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.10.0.tgz#7c172b270ec7b833951b52c348861206b184a4b7" - integrity sha512-LTSA/jWbwdMlk+rhmElbDR2vbtQoTBPr7fkJE+mxrHj+7ru0hUmHafDRzWIjIHTwpitWVaqY2/UWGRca3yUgRw== + version "6.11.0" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.11.0.tgz#33bae3bf6363d0a7c2cf9031c96c744ff54d85ba" + integrity sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g== dependencies: icss-utils "^5.1.0" postcss "^8.4.33" - postcss-modules-extract-imports "^3.0.0" - postcss-modules-local-by-default "^4.0.4" - postcss-modules-scope "^3.1.1" + postcss-modules-extract-imports "^3.1.0" + postcss-modules-local-by-default "^4.0.5" + postcss-modules-scope "^3.2.0" postcss-modules-values "^4.0.0" postcss-value-parser "^4.2.0" semver "^7.5.4" @@ -8820,9 +8743,9 @@ dedent@0.7.0, dedent@^0.7.0: integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== dedent@^1.0.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.5.1.tgz#4f3fc94c8b711e9bb2800d185cd6ad20f2a90aff" - integrity sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg== + version "1.5.3" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.5.3.tgz#99aee19eb9bae55a67327717b6e848d0bf777e5a" + integrity sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ== deep-equal@^1.0.1: version "1.1.2" @@ -9463,9 +9386,9 @@ ejs@^3.1.6, ejs@^3.1.7, ejs@^3.1.8: jake "^10.8.5" electron-to-chromium@^1.4.668: - version "1.4.721" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.721.tgz#a9ee55ba7e54d9ecbcc19825116f3752e7d60ef2" - integrity sha512-k1x2r6foI8iJOp+1qTxbbrrWMsOiHkzGBYwYigaq+apO1FSqtn44KTo3Sy69qt7CRr7149zTcsDvH7MUKsOuIQ== + version "1.4.733" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.733.tgz#708d51ce01a7ed3b401d5ced85e9f5d504fd4217" + integrity sha512-gUI9nhI2iBGF0OaYYLKOaOtliFMl+Bt1rY7VmEjwxOxqoYLub/D9xmduPEhbw2imE6gYkJKhIE5it+KE2ulVxQ== elegant-spinner@^1.0.1: version "1.0.1" @@ -9574,9 +9497,9 @@ envinfo@7.8.1: integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== envinfo@^7.7.3: - version "7.11.1" - resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.11.1.tgz#2ffef77591057081b0129a8fd8cf6118da1b94e1" - integrity sha512-8PiZgZNIB4q/Lw4AhOvAfB/ityHAd2bli3lESSWmWSzSsl5dKpy5N1d1Rfkd2teq/g9xN90lc6o98DOjMeYHpg== + version "7.12.0" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.12.0.tgz#b56723b39c2053d67ea5714f026d05d4f5cc7acd" + integrity sha512-Iw9rQJBGpJRd3rwXm9ft/JiGoAZmLxxJZELYDQoPRZ4USVhkKtIcNBPw6U+/K2mBpaqM25JSV6Yl4Az9vO2wJg== enzyme-shallow-equal@^1.0.0: version "1.0.7" @@ -9606,9 +9529,9 @@ error-stack-parser@^2.0.6: stackframe "^1.3.4" es-abstract@^1.17.2, es-abstract@^1.22.1, es-abstract@^1.22.3, es-abstract@^1.23.0, es-abstract@^1.23.1, es-abstract@^1.23.2: - version "1.23.2" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.23.2.tgz#693312f3940f967b8dd3eebacb590b01712622e0" - integrity sha512-60s3Xv2T2p1ICykc7c+DNDPLDMm9t4QxCOUU0K9JxiLjM3C1zB9YVdN7tjxrFd4+AkZ8CdX1ovUga4P2+1e+/w== + version "1.23.3" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.23.3.tgz#8f0c5a35cd215312573c5a27c87dfd6c881a0aa0" + integrity sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A== dependencies: array-buffer-byte-length "^1.0.1" arraybuffer.prototype.slice "^1.0.3" @@ -9649,11 +9572,11 @@ es-abstract@^1.17.2, es-abstract@^1.22.1, es-abstract@^1.22.3, es-abstract@^1.23 safe-regex-test "^1.0.3" string.prototype.trim "^1.2.9" string.prototype.trimend "^1.0.8" - string.prototype.trimstart "^1.0.7" + string.prototype.trimstart "^1.0.8" typed-array-buffer "^1.0.2" typed-array-byte-length "^1.0.1" typed-array-byte-offset "^1.0.2" - typed-array-length "^1.0.5" + typed-array-length "^1.0.6" unbox-primitive "^1.0.2" which-typed-array "^1.1.15" @@ -10847,9 +10770,9 @@ flatted@^3.2.9: integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw== flow-parser@0.*: - version "0.232.0" - resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.232.0.tgz#db93a660e7017bd366290944c3328ca506ca7d2b" - integrity sha512-U8vcKyYdM+Kb0tPzfPJ5JyPMU0uXKwHxp0L6BcEc+wBlbTW9qRhOqV5DeGXclgclVvtqQNGEG8Strj/b6c/IxA== + version "0.233.0" + resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.233.0.tgz#b983e65812d5ecae79f08ae3ed8ad2e131a9b966" + integrity sha512-E/mv51GYJfLuRX6fZnw4M52gBxYa8pkHUOgNEZOcQK2RTXS8YXeU5rlalkTcY99UpwbeNVCSUFKaavpOksi/pQ== flux@^4.0.1: version "4.0.4" @@ -13391,9 +13314,9 @@ jju@~1.4.0: integrity sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA== joi@^17.6.0, joi@^17.7.0: - version "17.12.2" - resolved "https://registry.yarnpkg.com/joi/-/joi-17.12.2.tgz#283a664dabb80c7e52943c557aab82faea09f521" - integrity sha512-RonXAIzCiHLc8ss3Ibuz45u28GOsWE1UpfDXLbN/9NKbL4tCJf8TWYVKsoYuuh+sAUt7fsSNpA+r2+TBA6Wjmw== + version "17.12.3" + resolved "https://registry.yarnpkg.com/joi/-/joi-17.12.3.tgz#944646979cd3b460178547b12ba37aca8482f63d" + integrity sha512-2RRziagf555owrm9IRVtdKynOBeITiDpuZqIpgwqXShPncPKNiRQoiGsl/T8SQdq+8ugRzH2LqY67irr2y/d+g== dependencies: "@hapi/hoek" "^9.3.0" "@hapi/topo" "^5.1.0" @@ -14211,9 +14134,9 @@ magic-string@^0.25.0, magic-string@^0.25.1, magic-string@^0.25.2, magic-string@^ sourcemap-codec "^1.4.8" magic-string@^0.30.5: - version "0.30.8" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.8.tgz#14e8624246d2bedba70d5462aa99ac9681844613" - integrity sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ== + version "0.30.9" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.9.tgz#8927ae21bfdd856310e07a1bc8dd5e73cb6c251d" + integrity sha512-S1+hd+dIrC8EZqKyT9DstTH/0Z+f76kmmvZnkfQVmOpDEF9iVgdYif3Q/pIWHmCoo59bQVGW0kVL3e2nl+9+Sw== dependencies: "@jridgewell/sourcemap-codec" "^1.4.15" @@ -14325,9 +14248,9 @@ markdown-table@^3.0.0: integrity sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw== markdown-to-jsx@^7.1.8: - version "7.4.5" - resolved "https://registry.yarnpkg.com/markdown-to-jsx/-/markdown-to-jsx-7.4.5.tgz#e55c27ec54df513d940b6efd314cf9a176823a9e" - integrity sha512-c8NB0H/ig+FOWssE9be0PKsYbCDhcWEkicxMnpdfUuHbFljnen4LAdgUShOyR/PgO3/qKvt9cwfQ0U/zQvZ44A== + version "7.4.6" + resolved "https://registry.yarnpkg.com/markdown-to-jsx/-/markdown-to-jsx-7.4.6.tgz#1ea0018c549bf00c9ce35e8f4ea57e48028d9cf7" + integrity sha512-3cyNxI/PwotvYkjg6KmFaN1uyN/7NqETteD2DobBB8ro/FR9jsHIh4Fi7ywAz0s9QHRKCmGlOUggs5GxSWACKA== material-colors@^1.2.1: version "1.2.6" @@ -15213,7 +15136,7 @@ mute-stream@0.0.8: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== -mute-stream@~1.0.0: +mute-stream@^1.0.0, mute-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-1.0.0.tgz#e31bd9fe62f0aed23520aa4324ea6671531e013e" integrity sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA== @@ -15270,9 +15193,9 @@ no-case@^3.0.4: tslib "^2.0.3" node-abi@^3.3.0: - version "3.56.0" - resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.56.0.tgz#ca807d5ff735ac6bbbd684ae3ff2debc1c2a40a7" - integrity sha512-fZjdhDOeRcaS+rcpve7XuwHBmktS1nS1gzgghwKUQQ8nTy2FdSDr6ZT8k6YhvlJeHmmQMYiT/IH9hfco5zeW2Q== + version "3.57.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.57.0.tgz#d772cb899236c0aa46778d0d25256917cf15eb15" + integrity sha512-Dp+A9JWxRaKuHP35H77I4kCKesDy5HUDEmScia2FyncMTOXASMyg251F5PhFoDA5uqBrDDffiLpbqnrZmNXW+g== dependencies: semver "^7.3.5" @@ -16809,24 +16732,24 @@ postcss-minify-selectors@^5.2.1: dependencies: postcss-selector-parser "^6.0.5" -postcss-modules-extract-imports@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" - integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== +postcss-modules-extract-imports@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz#b4497cb85a9c0c4b5aabeb759bb25e8d89f15002" + integrity sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q== -postcss-modules-local-by-default@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.4.tgz#7cbed92abd312b94aaea85b68226d3dec39a14e6" - integrity sha512-L4QzMnOdVwRm1Qb8m4x8jsZzKAaPAgrUF1r/hjDR2Xj7R+8Zsf97jAlSQzWtKx5YNiNGN8QxmPFIc/sh+RQl+Q== +postcss-modules-local-by-default@^4.0.5: + version "4.0.5" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz#f1b9bd757a8edf4d8556e8d0f4f894260e3df78f" + integrity sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw== dependencies: icss-utils "^5.0.0" postcss-selector-parser "^6.0.2" postcss-value-parser "^4.1.0" -postcss-modules-scope@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.1.1.tgz#32cfab55e84887c079a19bbb215e721d683ef134" - integrity sha512-uZgqzdTleelWjzJY+Fhti6F3C9iF1JR/dODLs/JDefozYcKTBCdD8BIl6nNPbTbcLnGrk56hzwZC2DaGNvYjzA== +postcss-modules-scope@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz#a43d28289a169ce2c15c00c4e64c0858e43457d5" + integrity sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ== dependencies: postcss-selector-parser "^6.0.4" @@ -17262,11 +17185,11 @@ prompts@^2.0.1, prompts@^2.4.0, prompts@^2.4.2: sisteransi "^1.0.5" promzard@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/promzard/-/promzard-1.0.0.tgz#3246f8e6c9895a77c0549cefb65828ac0f6c006b" - integrity sha512-KQVDEubSUHGSt5xLakaToDFrSoZhStB8dXLzk2xvwR67gJktrHFvpR63oZgHyK19WKbHFLXJqCPXdVR3aBP8Ig== + version "1.0.1" + resolved "https://registry.yarnpkg.com/promzard/-/promzard-1.0.1.tgz#3b77251a24f988c0886f5649d4f642bcdd53e558" + integrity sha512-ulDF77aULEHUoJkN5XZgRV5loHXBaqd9eorMvLNLvi2gXMuRAtwH6Gh4zsMHQY1kTt7tyv/YZwZW5C2gtj8F2A== dependencies: - read "^2.0.0" + read "^3.0.1" prop-types-exact@^1.2.0: version "1.2.0" @@ -18133,6 +18056,13 @@ read@^2.0.0: dependencies: mute-stream "~1.0.0" +read@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/read/-/read-3.0.1.tgz#926808f0f7c83fa95f1ef33c0e2c09dbb28fd192" + integrity sha512-SLBrDU/Srs/9EoWhU5GdbAoxG1GzpQHo/6qiGItaoLJ1thmYpcNIM1qISEUvyHBzfGlWIyd6p2DNi1oV1VmAuw== + dependencies: + mute-stream "^1.0.0" + readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.2.2, readable-stream@~2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" @@ -19243,9 +19173,9 @@ socks-proxy-agent@^7.0.0: socks "^2.6.2" socks@^2.6.2: - version "2.8.1" - resolved "https://registry.yarnpkg.com/socks/-/socks-2.8.1.tgz#22c7d9dd7882649043cba0eafb49ae144e3457af" - integrity sha512-B6w7tkwNid7ToxjZ08rQMT8M9BJAf8DKx8Ft4NivzH0zBUfd6jldGcisJn/RLgxcX3FPNDdNQCUEMMT79b+oCQ== + version "2.8.3" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.8.3.tgz#1ebd0f09c52ba95a09750afe3f3f9f724a800cb5" + integrity sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw== dependencies: ip-address "^9.0.5" smart-buffer "^4.2.0" @@ -19684,7 +19614,7 @@ string.prototype.trimend@^1.0.8: define-properties "^1.2.1" es-object-atoms "^1.0.0" -string.prototype.trimstart@^1.0.7: +string.prototype.trimstart@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz#7ee834dda8c7c17eff3118472bb35bfedaa34dde" integrity sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg== @@ -20159,9 +20089,9 @@ terser-webpack-plugin@^5.1.1, terser-webpack-plugin@^5.1.4, terser-webpack-plugi terser "^5.26.0" terser@^5.0.0, terser@^5.10.0, terser@^5.26.0: - version "5.30.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.30.0.tgz#64cb2af71e16ea3d32153f84d990f9be0cdc22bf" - integrity sha512-Y/SblUl5kEyEFzhMAQdsxVHh+utAxd4IuRNJzKywY/4uzSogh3G219jqbDDxYu4MXO9CzY3tSEqmZvW6AoEDJw== + version "5.30.3" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.30.3.tgz#f1bb68ded42408c316b548e3ec2526d7dd03f4d2" + integrity sha512-STdUgOUx8rLbMGO9IOwHLpCqolkDITFFQSMYYwKE1N2lY6MVSaeoi10z/EhWxRc6ybqoVmKSkhKYH/XUpl7vSA== dependencies: "@jridgewell/source-map" "^0.3.3" acorn "^8.8.2" @@ -20494,7 +20424,7 @@ typed-array-byte-offset@^1.0.2: has-proto "^1.0.3" is-typed-array "^1.1.13" -typed-array-length@^1.0.5: +typed-array-length@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.6.tgz#57155207c76e64a3457482dfdc1c9d1d3c4c73a3" integrity sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g== @@ -20529,9 +20459,9 @@ typescript@4.6.4: integrity sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg== "typescript@>=3 < 6": - version "5.4.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.3.tgz#5c6fedd4c87bee01cd7a528a30145521f8e0feff" - integrity sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg== + version "5.4.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.5.tgz#42ccef2c571fdbd0f6718b1d1f5e6e5ef006f611" + integrity sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ== ua-parser-js@^1.0.35: version "1.0.37" @@ -21230,9 +21160,9 @@ webidl-conversions@^7.0.0: integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g== webpack-bundle-analyzer@^4.4.2, webpack-bundle-analyzer@^4.5.0: - version "4.10.1" - resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.1.tgz#84b7473b630a7b8c21c741f81d8fe4593208b454" - integrity sha512-s3P7pgexgT/HTUSYgxJyn28A+99mmLq4HsJepMPzu0R8ImJc52QNqaFYW1Z2z2uIb1/J3eYgaAWVpaC+v/1aAQ== + version "4.10.2" + resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.2.tgz#633af2862c213730be3dbdf40456db171b60d5bd" + integrity sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw== dependencies: "@discoveryjs/json-ext" "0.5.7" acorn "^8.0.4" @@ -21242,7 +21172,6 @@ webpack-bundle-analyzer@^4.4.2, webpack-bundle-analyzer@^4.5.0: escape-string-regexp "^4.0.0" gzip-size "^6.0.0" html-escaper "^2.0.2" - is-plain-object "^5.0.0" opener "^1.5.2" picocolors "^1.0.0" sirv "^2.0.3"