fix(segmentation): failing to render SEG because it was on default tool group (#3222)

* fix: Segmentation service fixes for secondary volumes

* Remove toolgroupID in promptSeg
This commit is contained in:
Bill Wallace 2023-03-10 13:57:23 -05:00 committed by GitHub
parent 3f20b41c17
commit b7fff77e17
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 97 additions and 117 deletions

View File

@ -59,7 +59,7 @@
"babel-eslint": "^8.0.3", "babel-eslint": "^8.0.3",
"babel-loader": "^8.0.0-beta.4", "babel-loader": "^8.0.0-beta.4",
"clean-webpack-plugin": "^4.0.0", "clean-webpack-plugin": "^4.0.0",
"copy-webpack-plugin": "^10.2.0", "copy-webpack-plugin": "^11.0.0",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"dotenv": "^14.1.0", "dotenv": "^14.1.0",
"eslint": "^5.0.1", "eslint": "^5.0.1",

View File

@ -203,7 +203,7 @@ export default function PanelSegmentation({
showAddSegmentation={false} showAddSegmentation={false}
segmentations={segmentations} segmentations={segmentations}
isMinimized={isMinimized} isMinimized={isMinimized}
activeSegmentationId={selectedSegmentationId} activeSegmentationId={selectedSegmentationId || ''}
onSegmentationClick={onSegmentationClick} onSegmentationClick={onSegmentationClick}
onSegmentationDelete={onSegmentationDelete} onSegmentationDelete={onSegmentationDelete}
onSegmentationEdit={onSegmentationEdit} onSegmentationEdit={onSegmentationEdit}

View File

@ -1,7 +1,6 @@
async function _hydrateSEGDisplaySet({ async function _hydrateSEGDisplaySet({
segDisplaySet, segDisplaySet,
viewportIndex, viewportIndex,
toolGroupId,
servicesManager, servicesManager,
}) { }) {
const { const {
@ -55,8 +54,6 @@ async function _hydrateSEGDisplaySet({
viewportIndex: index, viewportIndex: index,
displaySetInstanceUIDs: viewport.displaySetInstanceUIDs, displaySetInstanceUIDs: viewport.displaySetInstanceUIDs,
viewportOptions: { viewportOptions: {
viewportType: 'volume',
toolGroupId,
initialImageOptions: { initialImageOptions: {
preset: 'middle', preset: 'middle',
}, },

View File

@ -10,13 +10,12 @@ function promptHydrateSEG({
servicesManager, servicesManager,
segDisplaySet, segDisplaySet,
viewportIndex, viewportIndex,
toolGroupId = 'default',
}) { }) {
const { UIViewportDialogService } = servicesManager.services; const { uiViewportDialogService } = servicesManager.services;
return new Promise(async function(resolve, reject) { return new Promise(async function(resolve, reject) {
const promptResult = await _askHydrate( const promptResult = await _askHydrate(
UIViewportDialogService, uiViewportDialogService,
viewportIndex viewportIndex
); );
@ -24,7 +23,6 @@ function promptHydrateSEG({
const isHydrated = await hydrateSEGDisplaySet({ const isHydrated = await hydrateSEGDisplaySet({
segDisplaySet, segDisplaySet,
viewportIndex, viewportIndex,
toolGroupId,
servicesManager, servicesManager,
}); });
@ -33,7 +31,7 @@ function promptHydrateSEG({
}); });
} }
function _askHydrate(UIViewportDialogService, viewportIndex) { function _askHydrate(uiViewportDialogService, viewportIndex) {
return new Promise(function(resolve, reject) { return new Promise(function(resolve, reject) {
const message = 'Do you want to open this Segmentation?'; const message = 'Do you want to open this Segmentation?';
const actions = [ const actions = [
@ -49,18 +47,18 @@ function _askHydrate(UIViewportDialogService, viewportIndex) {
}, },
]; ];
const onSubmit = result => { const onSubmit = result => {
UIViewportDialogService.hide(); uiViewportDialogService.hide();
resolve(result); resolve(result);
}; };
UIViewportDialogService.show({ uiViewportDialogService.show({
viewportIndex, viewportIndex,
type: 'info', type: 'info',
message, message,
actions, actions,
onSubmit, onSubmit,
onOutsideClick: () => { onOutsideClick: () => {
UIViewportDialogService.hide(); uiViewportDialogService.hide();
resolve(RESPONSE.CANCEL); resolve(RESPONSE.CANCEL);
}, },
}); });

View File

@ -235,6 +235,8 @@ function OHIFCornerstoneSEGViewport(props) {
return; return;
} }
// This creates a custom tool group which has the lifetime of this view
// only, and does NOT interfere with currently displayed segmentations.
toolGroup = createSEGToolGroupAndAddTools( toolGroup = createSEGToolGroupAndAddTools(
toolGroupService, toolGroupService,
toolGroupId, toolGroupId,
@ -249,6 +251,7 @@ function OHIFCornerstoneSEGViewport(props) {
toolGroupId toolGroupId
); );
// Only destroy the viewport specific implementation
toolGroupService.destroyToolGroup(toolGroupId); toolGroupService.destroyToolGroup(toolGroupId);
}; };
}, []); }, []);
@ -298,14 +301,12 @@ function OHIFCornerstoneSEGViewport(props) {
StudyDate, StudyDate,
SeriesDescription, SeriesDescription,
SpacingBetweenSlices, SpacingBetweenSlices,
SeriesNumber,
} = referencedDisplaySetRef.current.metadata; } = referencedDisplaySetRef.current.metadata;
const onStatusClick = async () => { const onStatusClick = async () => {
const isHydrated = await hydrateSEGDisplaySet({ const isHydrated = await hydrateSEGDisplaySet({
segDisplaySet, segDisplaySet,
viewportIndex, viewportIndex,
toolGroupId,
servicesManager, servicesManager,
}); });

View File

@ -45,8 +45,8 @@
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.13", "@babel/runtime": "^7.20.13",
"classnames": "^2.3.2", "classnames": "^2.3.2",
"@cornerstonejs/adapters": "^0.3.1", "@cornerstonejs/adapters": "^0.4.1",
"@cornerstonejs/core": "^0.32.0", "@cornerstonejs/core": "^0.33.2",
"@cornerstonejs/tools": "^0.48.0" "@cornerstonejs/tools": "^0.50.2"
} }
} }

View File

@ -43,10 +43,10 @@
}, },
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.13", "@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^0.3.1", "@cornerstonejs/adapters": "^0.4.1",
"@cornerstonejs/core": "^0.32.0", "@cornerstonejs/core": "^0.33.2",
"@cornerstonejs/streaming-image-volume-loader": "^0.13.0", "@cornerstonejs/streaming-image-volume-loader": "^0.14.1",
"@cornerstonejs/tools": "^0.48.0", "@cornerstonejs/tools": "^0.50.2",
"@kitware/vtk.js": "26.5.6", "@kitware/vtk.js": "26.5.6",
"html2canvas": "^1.4.1", "html2canvas": "^1.4.1",
"lodash.debounce": "4.0.8", "lodash.debounce": "4.0.8",

View File

@ -32,8 +32,8 @@
"peerDependencies": { "peerDependencies": {
"@ohif/core": "^3.0.0", "@ohif/core": "^3.0.0",
"classnames": "^2.3.2", "classnames": "^2.3.2",
"@cornerstonejs/core": "^0.32.0", "@cornerstonejs/core": "^0.33.2",
"@cornerstonejs/tools": "^0.48.0", "@cornerstonejs/tools": "^0.50.2",
"@ohif/extension-cornerstone-dicom-sr": "^3.0.0", "@ohif/extension-cornerstone-dicom-sr": "^3.0.0",
"dcmjs": "^0.29.4", "dcmjs": "^0.29.4",
"prop-types": "^15.6.2", "prop-types": "^15.6.2",

View File

@ -234,19 +234,16 @@ export default class CustomizationService extends PubSubService {
} }
/** /**
* A single reference is either an an array, or a single customization value, * A single reference is either an string to be loaded from a module,
* whose id is the id in the object, or the parent id. * or a customization itself.
* This allows for general use to register customizationModule entries.
*/ */
addReference( addReference(value?: Obj | string, isGlobal = true, id?: string): void {
value?: Obj | Obj[] | string,
isGlobal = true,
id?: string
): void {
if (!value) return; if (!value) return;
if (typeof value === 'string') { if (typeof value === 'string') {
const extensionValue = this.findExtensionValue(value); const extensionValue = this.findExtensionValue(value);
this.addReferences(extensionValue); // The child of a reference is only a set of references when an array,
// so call the addReference direct. It could be a secondary reference perhaps
this.addReference(extensionValue);
} else if (Array.isArray(value)) { } else if (Array.isArray(value)) {
this.addReferences(value, isGlobal); this.addReferences(value, isGlobal);
} else { } else {
@ -258,10 +255,10 @@ export default class CustomizationService extends PubSubService {
} }
} }
/** References are: /**
* list of customizations, added in order * Customizations can be specified as an array of strings or customizations,
* object containing a customization id and value * or as an object whose key is the reference id, and the value is the string
* This format allows for the original whitelist format. * or customization.
*/ */
addReferences(references?: Obj | Obj[], isGlobal = true): void { addReferences(references?: Obj | Obj[], isGlobal = true): void {
if (!references) return; if (!references) return;

View File

@ -7,7 +7,7 @@
* @property {boolean} [viewportIndex=false] Modal is dismissible via the esc key. * @property {boolean} [viewportIndex=false] Modal is dismissible via the esc key.
*/ */
const name = 'UIViewportDialogService'; const name = 'uiViewportDialogService';
const publicAPI = { const publicAPI = {
name, name,
@ -77,6 +77,7 @@ function setServiceImplementation({
export default { export default {
REGISTRATION: { REGISTRATION: {
name, name,
altName: 'UIViewportDialogService',
create: ({ configuration = {} }) => { create: ({ configuration = {} }) => {
return publicAPI; return publicAPI;
}, },

View File

@ -23,6 +23,7 @@ export default interface Services {
toolGroupService?: Record<string, unknown>; toolGroupService?: Record<string, unknown>;
uiNotificationService?: Record<string, unknown>; uiNotificationService?: Record<string, unknown>;
uiModalService?: Record<string, unknown>; uiModalService?: Record<string, unknown>;
uiViewportDialogService?: Record<string, unknown>;
viewportGridService?: ViewportGridService; viewportGridService?: ViewportGridService;
syncGroupService?: Record<string, unknown>; syncGroupService?: Record<string, unknown>;
cornerstoneCacheService?: Record<string, unknown>; cornerstoneCacheService?: Record<string, unknown>;

View File

@ -82,30 +82,29 @@ const SegmentationGroupTable = ({
activeSegmentIndex, activeSegmentIndex,
} = segmentation; } = segmentation;
return ( return (
<SegmentationGroup <SegmentationGroup
id={id} id={id}
label={label} key={id}
isMinimized={isMinimized[id]} label={label}
segments={segments} isMinimized={isMinimized[id]}
showAddSegment={showAddSegment} segments={segments}
segmentCount={segmentCount} showAddSegment={showAddSegment}
isActive={isActive} segmentCount={segmentCount}
isVisible={isVisible} isActive={isActive}
onSegmentColorClick={onSegmentColorClick} isVisible={isVisible}
onSegmentationClick={() => onSegmentationClick(id)} onSegmentColorClick={onSegmentColorClick}
activeSegmentIndex={activeSegmentIndex} onSegmentationClick={() => onSegmentationClick(id)}
onToggleMinimizeSegmentation={onToggleMinimizeSegmentation} activeSegmentIndex={activeSegmentIndex}
onSegmentationEdit={onSegmentationEdit} onToggleMinimizeSegmentation={onToggleMinimizeSegmentation}
onSegmentationDelete={onSegmentationDelete} onSegmentationEdit={onSegmentationEdit}
onSegmentClick={onSegmentClick} onSegmentationDelete={onSegmentationDelete}
onSegmentEdit={onSegmentEdit} onSegmentClick={onSegmentClick}
onToggleSegmentVisibility={onToggleSegmentVisibility} onSegmentEdit={onSegmentEdit}
onToggleSegmentationVisibility={ onToggleSegmentVisibility={onToggleSegmentVisibility}
onToggleSegmentationVisibility onToggleSegmentationVisibility={onToggleSegmentationVisibility}
} onSegmentAdd={onSegmentAdd}
onSegmentAdd={onSegmentAdd} showSegmentDelete={false}
showSegmentDelete={false} />
/>
); );
})} })}
</div> </div>

View File

@ -35,7 +35,7 @@ const setHeaders = (res, path) => {
} }
if (path.indexOf('.pdf') !== -1) { if (path.indexOf('.pdf') !== -1) {
res.setHeader('Content-Type', 'application/pdf'); res.setHeader('Content-Type', 'application/pdf');
} else if (path.indexOf('/frames') !== -1) { } else if (path.indexOf('frames') !== -1) {
res.setHeader('Content-Type', 'multipart/related'); res.setHeader('Content-Type', 'multipart/related');
} else { } else {
res.setHeader('Content-Type', 'application/json'); res.setHeader('Content-Type', 'application/json');

View File

@ -85,8 +85,13 @@ describe('OHIF Cornerstone Toolbar', () => {
.trigger('mousemove', 'right', { buttons: 1, force: true }) .trigger('mousemove', 'right', { buttons: 1, force: true })
.trigger('mouseup', { buttons: 1 }); .trigger('mouseup', { buttons: 1 });
const expectedText = 'W:1930L:479'; // The exact text is slightly dependent on the viewport resolution, so leave a range
cy.get('@viewportInfoTopLeft').should('have.text', expectedText); cy.get('@viewportInfoTopLeft').should($txt => {
const text = $txt.text();
expect(text)
.to.include('W:193')
.include('L:479');
});
}); });
it('checks if Pan tool will move the image inside the viewport', () => { it('checks if Pan tool will move the image inside the viewport', () => {

View File

@ -14,8 +14,9 @@ describe('OHIF MPR', () => {
}); });
it('should go MPR for reconstructible displaySets and come back', () => { it('should go MPR for reconstructible displaySets and come back', () => {
cy.wait(1000); cy.wait(250);
cy.get(':nth-child(3) > [data-cy="study-browser-thumbnail"]').dblclick(); cy.get(':nth-child(3) > [data-cy="study-browser-thumbnail"]').dblclick();
cy.wait(250);
cy.get('[data-cy="MPR"]').click(); cy.get('[data-cy="MPR"]').click();
@ -94,7 +95,7 @@ describe('OHIF MPR', () => {
}); });
it('should correctly render Crosshairs for MPR', () => { it('should correctly render Crosshairs for MPR', () => {
cy.wait(1000); cy.wait(250);
cy.get('[data-cy="Crosshairs"]').click(); cy.get('[data-cy="Crosshairs"]').click();
cy.window() cy.window()
@ -111,7 +112,7 @@ describe('OHIF MPR', () => {
cy.get('[data-cy="MPR"]').click(); cy.get('[data-cy="MPR"]').click();
cy.get('[data-cy="Crosshairs"]').click(); cy.get('[data-cy="Crosshairs"]').click();
cy.wait(1000); cy.wait(250);
// check cornerstone to see if each has crosshairs // check cornerstone to see if each has crosshairs
// we can later do visual testing to match the images with a baseline // we can later do visual testing to match the images with a baseline

View File

@ -5,6 +5,7 @@ window.config = {
showStudyList: true, showStudyList: true,
// below flag is for performance reasons, but it might not work for all servers // below flag is for performance reasons, but it might not work for all servers
omitQuotationForMultipartRequest: true, omitQuotationForMultipartRequest: true,
maxNumberOfWebWorkers: 3,
showWarningMessageForCrossOrigin: false, showWarningMessageForCrossOrigin: false,
showCPUFallbackMessage: false, showCPUFallbackMessage: false,
// filterQueryParam: false, // filterQueryParam: false,

View File

@ -9,7 +9,7 @@ window.config = {
}, },
], ],
extensions: [], extensions: [],
modes: [], modes: ['@ohif/mode-test'],
showStudyList: true, showStudyList: true,
maxNumberOfWebWorkers: 4, maxNumberOfWebWorkers: 4,
// below flag is for performance reasons, but it might not work for all servers // below flag is for performance reasons, but it might not work for all servers

View File

@ -1407,10 +1407,10 @@
resolved "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" resolved "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9"
integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==
"@cornerstonejs/adapters@^0.3.1": "@cornerstonejs/adapters@^0.4.1":
version "0.3.1" version "0.4.1"
resolved "https://registry.yarnpkg.com/@cornerstonejs/adapters/-/adapters-0.3.1.tgz#50cfaf3de3c5a55f22f7fae1a9f6584a1c343ffa" resolved "https://registry.yarnpkg.com/@cornerstonejs/adapters/-/adapters-0.4.1.tgz#fedab0d9cfea609f5219950c86e546198ad0f3c8"
integrity sha512-+tqMLVYeSZjzwtzbAPqRMq5iI47nrtXz4f3GQ1jKUSmZqQyvgWRzAizcfnl6OEIrgjeg/2MHdSGOEWu12H8M+w== integrity sha512-DQabSBdTN/A5tsncnDLdsb6LI5I/FTG3gSmNpDAkc9fAZY6Ljj0lCLt9KHB5OA1Gbvrlcab/DGJ/2YW6Z7ifRg==
dependencies: dependencies:
"@babel/runtime-corejs2" "^7.17.8" "@babel/runtime-corejs2" "^7.17.8"
dcmjs "^0.29.4" dcmjs "^0.29.4"
@ -1443,28 +1443,36 @@
resolved "https://registry.npmjs.org/@cornerstonejs/codec-openjph/-/codec-openjph-2.4.2.tgz#e96721d56f6ec96f7f95c16321d88cc8467d8d81" resolved "https://registry.npmjs.org/@cornerstonejs/codec-openjph/-/codec-openjph-2.4.2.tgz#e96721d56f6ec96f7f95c16321d88cc8467d8d81"
integrity sha512-lgdvBvvNezleY+4pIe2ceUsJzlZe/0PipdeubQ3vZZOz3xxtHHMR1XFCl4fgd8gosR8COHuD7h6q+MwgrwBsng== integrity sha512-lgdvBvvNezleY+4pIe2ceUsJzlZe/0PipdeubQ3vZZOz3xxtHHMR1XFCl4fgd8gosR8COHuD7h6q+MwgrwBsng==
"@cornerstonejs/core@^0.32.0": "@cornerstonejs/core@^0.33.1":
version "0.32.0" version "0.33.1"
resolved "https://registry.npmjs.org/@cornerstonejs/core/-/core-0.32.0.tgz#75fb782cc30c82642d6085d7900ec91df51aee36" resolved "https://registry.yarnpkg.com/@cornerstonejs/core/-/core-0.33.1.tgz#dfbcad81239141c2702fd2ab0a3edbe408e7bfad"
integrity sha512-Ep7b+jUO5OtRuEYRlb2Q386ZZfndAdgkDApPoTOYR+BzrwVfMF8/BEmP7UagT/bpAFk5lp5PHt/akN0qM2KR/Q== integrity sha512-QXrnKZBEMharA/FIYqtvkTXD8JeEf742yHybNmehB1cJU1hrsjRJ1JuqXXu6IHWJFx3cAsCaWk4oZyA09OB7OQ==
dependencies: dependencies:
detect-gpu "^4.0.45" detect-gpu "^4.0.45"
lodash.clonedeep "4.5.0" lodash.clonedeep "4.5.0"
"@cornerstonejs/streaming-image-volume-loader@^0.13.0": "@cornerstonejs/core@^0.33.2":
version "0.13.0" version "0.33.2"
resolved "https://registry.npmjs.org/@cornerstonejs/streaming-image-volume-loader/-/streaming-image-volume-loader-0.13.0.tgz#0b27bde776585274b6f5ab98eb2366711f8fc878" resolved "https://registry.yarnpkg.com/@cornerstonejs/core/-/core-0.33.2.tgz#63aea3eb9787622be0c75052696119a0e58117e6"
integrity sha512-js+qaw+I5en0FR/SzJVwGY5WKfldPiVfoJvMuZb7/mNoeoi+N/U47W9WzKlCPqM81xb1mlnjXPyhVdxQ78F36Q== integrity sha512-iRHq7WIcZOUxOIMV9KEY7iJjTpcpk7vJPAIZM5tqVvTIbcfaACmxpTlpc2NPqT52o0shRQImIkMFiotUKx0Pug==
dependencies: dependencies:
"@cornerstonejs/core" "^0.32.0" detect-gpu "^4.0.45"
lodash.clonedeep "4.5.0"
"@cornerstonejs/streaming-image-volume-loader@^0.14.1":
version "0.14.1"
resolved "https://registry.yarnpkg.com/@cornerstonejs/streaming-image-volume-loader/-/streaming-image-volume-loader-0.14.1.tgz#9830e1cbb65aa0e050336b7f5cb9c81d23e09fc5"
integrity sha512-4m2efDbv00pFQfL/ZjnWjo4RJ3yo4ibv4J/8oro7ZrzhXUJl9L4mwdA1HYCAkS+rZQndZba138AO6b+g4nrmXQ==
dependencies:
"@cornerstonejs/core" "^0.33.1"
cornerstone-wado-image-loader "^4.10.0" cornerstone-wado-image-loader "^4.10.0"
"@cornerstonejs/tools@^0.48.0": "@cornerstonejs/tools@^0.50.2":
version "0.48.0" version "0.50.2"
resolved "https://registry.npmjs.org/@cornerstonejs/tools/-/tools-0.48.0.tgz#c881866a58dd7fe5338256166630e3de633b14e7" resolved "https://registry.yarnpkg.com/@cornerstonejs/tools/-/tools-0.50.2.tgz#0134b21016ec64290b8f9a43ac1a485654ed86eb"
integrity sha512-uMrfY84m1bzVQ8I6HAkmKjZDuB3cHy9T7SWiOhXqfQGdcftkEJXYzXA6WbXDbsG8LpslnSv79Ovbx1uvH2GrWQ== integrity sha512-MedGsiisDjd2eOewhojwPpWReKM13x1krKIhPNL3hi8rZjV57T8RTpWfztxSjuUpOvapmlJXutrDPuLSUXs01g==
dependencies: dependencies:
"@cornerstonejs/core" "^0.32.0" "@cornerstonejs/core" "^0.33.2"
lodash.clonedeep "4.5.0" lodash.clonedeep "4.5.0"
lodash.get "^4.4.2" lodash.get "^4.4.2"
@ -6438,11 +6446,6 @@ array-union@^2.1.0:
resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d"
integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==
array-union@^3.0.1:
version "3.0.1"
resolved "https://registry.npmjs.org/array-union/-/array-union-3.0.1.tgz#da52630d327f8b88cfbfb57728e2af5cd9b6b975"
integrity sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw==
array-uniq@^1.0.1: array-uniq@^1.0.1:
version "1.0.3" version "1.0.3"
resolved "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" resolved "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6"
@ -8463,18 +8466,6 @@ copy-text-to-clipboard@^3.0.1:
resolved "https://registry.npmjs.org/copy-text-to-clipboard/-/copy-text-to-clipboard-3.0.1.tgz#8cbf8f90e0a47f12e4a24743736265d157bce69c" resolved "https://registry.npmjs.org/copy-text-to-clipboard/-/copy-text-to-clipboard-3.0.1.tgz#8cbf8f90e0a47f12e4a24743736265d157bce69c"
integrity sha512-rvVsHrpFcL4F2P8ihsoLdFHmd404+CMg71S756oRSeQgqk51U3kicGdnvfkrxva0xXH92SjGS62B0XIJsbh+9Q== integrity sha512-rvVsHrpFcL4F2P8ihsoLdFHmd404+CMg71S756oRSeQgqk51U3kicGdnvfkrxva0xXH92SjGS62B0XIJsbh+9Q==
copy-webpack-plugin@^10.2.0:
version "10.2.4"
resolved "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-10.2.4.tgz#6c854be3fdaae22025da34b9112ccf81c63308fe"
integrity sha512-xFVltahqlsRcyyJqQbDY6EYTtyQZF9rf+JPjwHObLdPFMEISqkFkr7mFoVOC6BfYS/dNThyoQKvziugm+OnwBg==
dependencies:
fast-glob "^3.2.7"
glob-parent "^6.0.1"
globby "^12.0.2"
normalize-path "^3.0.0"
schema-utils "^4.0.0"
serialize-javascript "^6.0.0"
copy-webpack-plugin@^11.0.0: copy-webpack-plugin@^11.0.0:
version "11.0.0" version "11.0.0"
resolved "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz#96d4dbdb5f73d02dd72d0528d1958721ab72e04a" resolved "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz#96d4dbdb5f73d02dd72d0528d1958721ab72e04a"
@ -12013,18 +12004,6 @@ globby@^11.0.1, globby@^11.0.2, globby@^11.0.3, globby@^11.0.4, globby@^11.1.0:
merge2 "^1.4.1" merge2 "^1.4.1"
slash "^3.0.0" slash "^3.0.0"
globby@^12.0.2:
version "12.2.0"
resolved "https://registry.npmjs.org/globby/-/globby-12.2.0.tgz#2ab8046b4fba4ff6eede835b29f678f90e3d3c22"
integrity sha512-wiSuFQLZ+urS9x2gGPl1H5drc5twabmm4m2gTR27XDFyjUHJUNsS8o/2aKyIF6IoBaR630atdher0XJ5g6OMmA==
dependencies:
array-union "^3.0.1"
dir-glob "^3.0.1"
fast-glob "^3.2.7"
ignore "^5.1.9"
merge2 "^1.4.1"
slash "^4.0.0"
globby@^13.1.1: globby@^13.1.1:
version "13.1.3" version "13.1.3"
resolved "https://registry.npmjs.org/globby/-/globby-13.1.3.tgz#f62baf5720bcb2c1330c8d4ef222ee12318563ff" resolved "https://registry.npmjs.org/globby/-/globby-13.1.3.tgz#f62baf5720bcb2c1330c8d4ef222ee12318563ff"
@ -12757,7 +12736,7 @@ ignore@^4.0.3, ignore@^4.0.6:
resolved "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" resolved "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==
ignore@^5.0.0, ignore@^5.1.1, ignore@^5.1.8, ignore@^5.1.9, ignore@^5.2.0: ignore@^5.0.0, ignore@^5.1.1, ignore@^5.1.8, ignore@^5.2.0:
version "5.2.4" version "5.2.4"
resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324"
integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==