test(e2e): update Playwright screenshots and add better tests and assertions for area calculations (#6022)

* Add (better) assertions for area calculation fixes.
* Add SVG and measurement side panel area for freehand ROI test.
* Add Playwright viewport screenshot scope migration guide.
* Update cornerstonjs dependencies to 4.22.8. Ensure all versions of @babel/preset-env are 7.29.5.

---------

Co-authored-by: Ghadeer Albattarni <165973963+GhadeerAlbattarni@users.noreply.github.com>
This commit is contained in:
Joe Boccanfuso 2026-05-18 10:36:05 -04:00 committed by GitHub
parent cb0cbe702c
commit fe16e80cf3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
174 changed files with 1071 additions and 751 deletions

View File

@ -110,8 +110,9 @@ for (const pkgPath of pkgPaths) {
changes += updateDeps(pkg.resolutions, version); changes += updateDeps(pkg.resolutions, version);
if (changes > 0) { if (changes > 0) {
// Preserve original formatting (detect indent) // Preserve original formatting (detect indent — restrict to spaces/tabs so
const indent = content.match(/^(\s+)/m)?.[1] || ' '; // we don't accidentally capture a CRLF newline as part of the indent string)
const indent = content.match(/^([ \t]+)/m)?.[1] || ' ';
writeFileSync(pkgPath, JSON.stringify(pkg, null, indent) + '\n'); writeFileSync(pkgPath, JSON.stringify(pkg, null, indent) + '\n');
const rel = pkgPath.replace(rootDir + '/', '').replace(rootDir + '\\', ''); const rel = pkgPath.replace(rootDir + '/', '').replace(rootDir + '\\', '');
console.log(` Updated ${rel} (${changes} packages)`); console.log(` Updated ${rel} (${changes} packages)`);

View File

@ -31,7 +31,7 @@
"@babel/plugin-transform-regenerator": "7.28.1", "@babel/plugin-transform-regenerator": "7.28.1",
"@babel/plugin-transform-runtime": "7.28.0", "@babel/plugin-transform-runtime": "7.28.0",
"@babel/plugin-transform-typescript": "7.28.0", "@babel/plugin-transform-typescript": "7.28.0",
"@babel/preset-env": "7.28.0", "@babel/preset-env": "7.29.5",
"@babel/preset-react": "7.27.1", "@babel/preset-react": "7.27.1",
"@babel/preset-typescript": "7.27.1" "@babel/preset-typescript": "7.27.1"
}, },

534
bun.lock
View File

@ -50,7 +50,7 @@
}, },
"addOns/externals/devDependencies": { "addOns/externals/devDependencies": {
"name": "@externals/devDependencies", "name": "@externals/devDependencies",
"version": "3.13.0-beta.68", "version": "3.13.0-beta.74",
"dependencies": { "dependencies": {
"@babel/runtime": "7.28.2", "@babel/runtime": "7.28.2",
"@kitware/vtk.js": "34.15.1", "@kitware/vtk.js": "34.15.1",
@ -131,22 +131,22 @@
}, },
"addOns/externals/dicom-microscopy-viewer": { "addOns/externals/dicom-microscopy-viewer": {
"name": "@externals/dicom-microscopy-viewer", "name": "@externals/dicom-microscopy-viewer",
"version": "3.13.0-beta.68", "version": "3.13.0-beta.74",
"dependencies": { "dependencies": {
"dicom-microscopy-viewer": "0.48.17", "dicom-microscopy-viewer": "0.48.17",
}, },
}, },
"extensions/cornerstone": { "extensions/cornerstone": {
"name": "@ohif/extension-cornerstone", "name": "@ohif/extension-cornerstone",
"version": "3.13.0-beta.68", "version": "3.13.0-beta.74",
"dependencies": { "dependencies": {
"@babel/runtime": "7.28.2", "@babel/runtime": "7.28.2",
"@cornerstonejs/adapters": "4.22.3", "@cornerstonejs/adapters": "4.22.8",
"@cornerstonejs/ai": "4.22.3", "@cornerstonejs/ai": "4.22.8",
"@cornerstonejs/core": "4.22.3", "@cornerstonejs/core": "4.22.8",
"@cornerstonejs/labelmap-interpolation": "4.22.3", "@cornerstonejs/labelmap-interpolation": "4.22.8",
"@cornerstonejs/polymorphic-segmentation": "4.22.3", "@cornerstonejs/polymorphic-segmentation": "4.22.8",
"@cornerstonejs/tools": "4.22.3", "@cornerstonejs/tools": "4.22.8",
"@icr/polyseg-wasm": "0.4.0", "@icr/polyseg-wasm": "0.4.0",
"@itk-wasm/morphological-contour-interpolation": "1.1.0", "@itk-wasm/morphological-contour-interpolation": "1.1.0",
"@kitware/vtk.js": "34.15.1", "@kitware/vtk.js": "34.15.1",
@ -164,9 +164,9 @@
"@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2", "@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2",
"@cornerstonejs/codec-openjpeg": "1.3.0", "@cornerstonejs/codec-openjpeg": "1.3.0",
"@cornerstonejs/codec-openjph": "2.4.7", "@cornerstonejs/codec-openjph": "2.4.7",
"@cornerstonejs/dicom-image-loader": "4.22.3", "@cornerstonejs/dicom-image-loader": "4.22.8",
"@ohif/core": "3.13.0-beta.68", "@ohif/core": "3.13.0-beta.74",
"@ohif/ui": "3.13.0-beta.68", "@ohif/ui": "3.13.0-beta.74",
"dcmjs": "0.49.4", "dcmjs": "0.49.4",
"dicom-parser": "1.8.21", "dicom-parser": "1.8.21",
"hammerjs": "2.0.8", "hammerjs": "2.0.8",
@ -178,18 +178,18 @@
}, },
"extensions/cornerstone-dicom-pmap": { "extensions/cornerstone-dicom-pmap": {
"name": "@ohif/extension-cornerstone-dicom-pmap", "name": "@ohif/extension-cornerstone-dicom-pmap",
"version": "3.13.0-beta.68", "version": "3.13.0-beta.74",
"dependencies": { "dependencies": {
"@babel/runtime": "7.28.2", "@babel/runtime": "7.28.2",
"@cornerstonejs/adapters": "4.22.3", "@cornerstonejs/adapters": "4.22.8",
"@cornerstonejs/core": "4.22.3", "@cornerstonejs/core": "4.22.8",
"@kitware/vtk.js": "34.15.1", "@kitware/vtk.js": "34.15.1",
}, },
"peerDependencies": { "peerDependencies": {
"@ohif/core": "3.13.0-beta.68", "@ohif/core": "3.13.0-beta.74",
"@ohif/extension-cornerstone": "3.13.0-beta.68", "@ohif/extension-cornerstone": "3.13.0-beta.74",
"@ohif/extension-default": "3.13.0-beta.68", "@ohif/extension-default": "3.13.0-beta.74",
"@ohif/i18n": "3.13.0-beta.68", "@ohif/i18n": "3.13.0-beta.74",
"prop-types": "15.8.1", "prop-types": "15.8.1",
"react": "18.3.1", "react": "18.3.1",
"react-dom": "18.3.1", "react-dom": "18.3.1",
@ -200,15 +200,15 @@
}, },
"extensions/cornerstone-dicom-rt": { "extensions/cornerstone-dicom-rt": {
"name": "@ohif/extension-cornerstone-dicom-rt", "name": "@ohif/extension-cornerstone-dicom-rt",
"version": "3.13.0-beta.68", "version": "3.13.0-beta.74",
"dependencies": { "dependencies": {
"@babel/runtime": "7.28.2", "@babel/runtime": "7.28.2",
}, },
"peerDependencies": { "peerDependencies": {
"@ohif/core": "3.13.0-beta.68", "@ohif/core": "3.13.0-beta.74",
"@ohif/extension-cornerstone": "3.13.0-beta.68", "@ohif/extension-cornerstone": "3.13.0-beta.74",
"@ohif/extension-default": "3.13.0-beta.68", "@ohif/extension-default": "3.13.0-beta.74",
"@ohif/i18n": "3.13.0-beta.68", "@ohif/i18n": "3.13.0-beta.74",
"prop-types": "15.8.1", "prop-types": "15.8.1",
"react": "18.3.1", "react": "18.3.1",
"react-dom": "18.3.1", "react-dom": "18.3.1",
@ -219,18 +219,18 @@
}, },
"extensions/cornerstone-dicom-seg": { "extensions/cornerstone-dicom-seg": {
"name": "@ohif/extension-cornerstone-dicom-seg", "name": "@ohif/extension-cornerstone-dicom-seg",
"version": "3.13.0-beta.68", "version": "3.13.0-beta.74",
"dependencies": { "dependencies": {
"@babel/runtime": "7.28.2", "@babel/runtime": "7.28.2",
"@cornerstonejs/adapters": "4.22.3", "@cornerstonejs/adapters": "4.22.8",
"@cornerstonejs/core": "4.22.3", "@cornerstonejs/core": "4.22.8",
"@kitware/vtk.js": "34.15.1", "@kitware/vtk.js": "34.15.1",
}, },
"peerDependencies": { "peerDependencies": {
"@ohif/core": "3.13.0-beta.68", "@ohif/core": "3.13.0-beta.74",
"@ohif/extension-cornerstone": "3.13.0-beta.68", "@ohif/extension-cornerstone": "3.13.0-beta.74",
"@ohif/extension-default": "3.13.0-beta.68", "@ohif/extension-default": "3.13.0-beta.74",
"@ohif/i18n": "3.13.0-beta.68", "@ohif/i18n": "3.13.0-beta.74",
"prop-types": "15.8.1", "prop-types": "15.8.1",
"react": "18.3.1", "react": "18.3.1",
"react-dom": "18.3.1", "react-dom": "18.3.1",
@ -241,19 +241,19 @@
}, },
"extensions/cornerstone-dicom-sr": { "extensions/cornerstone-dicom-sr": {
"name": "@ohif/extension-cornerstone-dicom-sr", "name": "@ohif/extension-cornerstone-dicom-sr",
"version": "3.13.0-beta.68", "version": "3.13.0-beta.74",
"dependencies": { "dependencies": {
"@babel/runtime": "7.28.2", "@babel/runtime": "7.28.2",
"@cornerstonejs/adapters": "4.22.3", "@cornerstonejs/adapters": "4.22.8",
"@cornerstonejs/core": "4.22.3", "@cornerstonejs/core": "4.22.8",
"@cornerstonejs/tools": "4.22.3", "@cornerstonejs/tools": "4.22.8",
"classnames": "2.5.1", "classnames": "2.5.1",
}, },
"peerDependencies": { "peerDependencies": {
"@ohif/core": "3.13.0-beta.68", "@ohif/core": "3.13.0-beta.74",
"@ohif/extension-cornerstone": "3.13.0-beta.68", "@ohif/extension-cornerstone": "3.13.0-beta.74",
"@ohif/extension-measurement-tracking": "3.13.0-beta.68", "@ohif/extension-measurement-tracking": "3.13.0-beta.74",
"@ohif/ui": "3.13.0-beta.68", "@ohif/ui": "3.13.0-beta.74",
"dcmjs": "0.49.4", "dcmjs": "0.49.4",
"dicom-parser": "1.8.21", "dicom-parser": "1.8.21",
"hammerjs": "2.0.8", "hammerjs": "2.0.8",
@ -263,19 +263,19 @@
}, },
"extensions/cornerstone-dynamic-volume": { "extensions/cornerstone-dynamic-volume": {
"name": "@ohif/extension-cornerstone-dynamic-volume", "name": "@ohif/extension-cornerstone-dynamic-volume",
"version": "3.13.0-beta.68", "version": "3.13.0-beta.74",
"dependencies": { "dependencies": {
"@babel/runtime": "7.28.2", "@babel/runtime": "7.28.2",
"@cornerstonejs/core": "4.22.3", "@cornerstonejs/core": "4.22.8",
"@cornerstonejs/tools": "4.22.3", "@cornerstonejs/tools": "4.22.8",
"classnames": "2.5.1", "classnames": "2.5.1",
}, },
"peerDependencies": { "peerDependencies": {
"@ohif/core": "3.13.0-beta.68", "@ohif/core": "3.13.0-beta.74",
"@ohif/extension-cornerstone": "3.13.0-beta.68", "@ohif/extension-cornerstone": "3.13.0-beta.74",
"@ohif/extension-default": "3.13.0-beta.68", "@ohif/extension-default": "3.13.0-beta.74",
"@ohif/i18n": "3.13.0-beta.68", "@ohif/i18n": "3.13.0-beta.74",
"@ohif/ui": "3.13.0-beta.68", "@ohif/ui": "3.13.0-beta.74",
"dcmjs": "0.49.4", "dcmjs": "0.49.4",
"dicom-parser": "1.8.21", "dicom-parser": "1.8.21",
"hammerjs": "2.0.8", "hammerjs": "2.0.8",
@ -285,7 +285,7 @@
}, },
"extensions/default": { "extensions/default": {
"name": "@ohif/extension-default", "name": "@ohif/extension-default",
"version": "3.13.0-beta.68", "version": "3.13.0-beta.74",
"dependencies": { "dependencies": {
"@babel/runtime": "7.28.2", "@babel/runtime": "7.28.2",
"@cornerstonejs/calculate-suv": "1.1.0", "@cornerstonejs/calculate-suv": "1.1.0",
@ -294,8 +294,8 @@
"react-color": "2.19.3", "react-color": "2.19.3",
}, },
"peerDependencies": { "peerDependencies": {
"@ohif/core": "3.13.0-beta.68", "@ohif/core": "3.13.0-beta.74",
"@ohif/i18n": "3.13.0-beta.68", "@ohif/i18n": "3.13.0-beta.74",
"dcmjs": "0.49.4", "dcmjs": "0.49.4",
"dicomweb-client": "0.10.4", "dicomweb-client": "0.10.4",
"prop-types": "15.8.1", "prop-types": "15.8.1",
@ -309,7 +309,7 @@
}, },
"extensions/dicom-microscopy": { "extensions/dicom-microscopy": {
"name": "@ohif/extension-dicom-microscopy", "name": "@ohif/extension-dicom-microscopy",
"version": "3.13.0-beta.68", "version": "3.13.0-beta.74",
"dependencies": { "dependencies": {
"@babel/runtime": "7.28.2", "@babel/runtime": "7.28.2",
"@cornerstonejs/codec-charls": "1.2.3", "@cornerstonejs/codec-charls": "1.2.3",
@ -320,10 +320,10 @@
"mathjs": "12.4.3", "mathjs": "12.4.3",
}, },
"peerDependencies": { "peerDependencies": {
"@ohif/core": "3.13.0-beta.68", "@ohif/core": "3.13.0-beta.74",
"@ohif/extension-default": "3.13.0-beta.68", "@ohif/extension-default": "3.13.0-beta.74",
"@ohif/i18n": "3.13.0-beta.68", "@ohif/i18n": "3.13.0-beta.74",
"@ohif/ui": "3.13.0-beta.68", "@ohif/ui": "3.13.0-beta.74",
"prop-types": "15.8.1", "prop-types": "15.8.1",
"react": "18.3.1", "react": "18.3.1",
"react-dom": "18.3.1", "react-dom": "18.3.1",
@ -334,14 +334,14 @@
}, },
"extensions/dicom-pdf": { "extensions/dicom-pdf": {
"name": "@ohif/extension-dicom-pdf", "name": "@ohif/extension-dicom-pdf",
"version": "3.13.0-beta.68", "version": "3.13.0-beta.74",
"dependencies": { "dependencies": {
"@babel/runtime": "7.28.2", "@babel/runtime": "7.28.2",
"classnames": "2.5.1", "classnames": "2.5.1",
}, },
"peerDependencies": { "peerDependencies": {
"@ohif/core": "3.13.0-beta.68", "@ohif/core": "3.13.0-beta.74",
"@ohif/ui": "3.13.0-beta.68", "@ohif/ui": "3.13.0-beta.74",
"dcmjs": "0.49.4", "dcmjs": "0.49.4",
"dicom-parser": "1.8.21", "dicom-parser": "1.8.21",
"hammerjs": "2.0.8", "hammerjs": "2.0.8",
@ -351,14 +351,14 @@
}, },
"extensions/dicom-video": { "extensions/dicom-video": {
"name": "@ohif/extension-dicom-video", "name": "@ohif/extension-dicom-video",
"version": "3.13.0-beta.68", "version": "3.13.0-beta.74",
"dependencies": { "dependencies": {
"@babel/runtime": "7.28.2", "@babel/runtime": "7.28.2",
"classnames": "2.5.1", "classnames": "2.5.1",
}, },
"peerDependencies": { "peerDependencies": {
"@ohif/core": "3.13.0-beta.68", "@ohif/core": "3.13.0-beta.74",
"@ohif/ui": "3.13.0-beta.68", "@ohif/ui": "3.13.0-beta.74",
"dcmjs": "0.49.4", "dcmjs": "0.49.4",
"dicom-parser": "1.8.21", "dicom-parser": "1.8.21",
"hammerjs": "2.0.8", "hammerjs": "2.0.8",
@ -368,20 +368,20 @@
}, },
"extensions/measurement-tracking": { "extensions/measurement-tracking": {
"name": "@ohif/extension-measurement-tracking", "name": "@ohif/extension-measurement-tracking",
"version": "3.13.0-beta.68", "version": "3.13.0-beta.74",
"dependencies": { "dependencies": {
"@babel/runtime": "7.28.2", "@babel/runtime": "7.28.2",
"@ohif/ui": "3.13.0-beta.68", "@ohif/ui": "3.13.0-beta.74",
"@xstate/react": "3.2.2", "@xstate/react": "3.2.2",
"xstate": "4.38.3", "xstate": "4.38.3",
}, },
"peerDependencies": { "peerDependencies": {
"@cornerstonejs/core": "4.22.3", "@cornerstonejs/core": "4.22.8",
"@cornerstonejs/tools": "4.22.3", "@cornerstonejs/tools": "4.22.8",
"@ohif/core": "3.13.0-beta.68", "@ohif/core": "3.13.0-beta.74",
"@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.68", "@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.74",
"@ohif/extension-default": "3.13.0-beta.68", "@ohif/extension-default": "3.13.0-beta.74",
"@ohif/ui": "3.13.0-beta.68", "@ohif/ui": "3.13.0-beta.74",
"classnames": "2.5.1", "classnames": "2.5.1",
"dcmjs": "0.49.4", "dcmjs": "0.49.4",
"lodash.debounce": "4.0.8", "lodash.debounce": "4.0.8",
@ -394,14 +394,14 @@
}, },
"extensions/test-extension": { "extensions/test-extension": {
"name": "@ohif/extension-test", "name": "@ohif/extension-test",
"version": "3.13.0-beta.68", "version": "3.13.0-beta.74",
"dependencies": { "dependencies": {
"@babel/runtime": "7.28.2", "@babel/runtime": "7.28.2",
"classnames": "2.5.1", "classnames": "2.5.1",
}, },
"peerDependencies": { "peerDependencies": {
"@ohif/core": "3.13.0-beta.68", "@ohif/core": "3.13.0-beta.74",
"@ohif/ui": "3.13.0-beta.68", "@ohif/ui": "3.13.0-beta.74",
"dcmjs": "0.49.4", "dcmjs": "0.49.4",
"dicom-parser": "1.8.21", "dicom-parser": "1.8.21",
"hammerjs": "2.0.8", "hammerjs": "2.0.8",
@ -411,7 +411,7 @@
}, },
"extensions/tmtv": { "extensions/tmtv": {
"name": "@ohif/extension-tmtv", "name": "@ohif/extension-tmtv",
"version": "3.13.0-beta.68", "version": "3.13.0-beta.74",
"dependencies": { "dependencies": {
"@babel/runtime": "7.28.2", "@babel/runtime": "7.28.2",
"classnames": "2.5.1", "classnames": "2.5.1",
@ -428,16 +428,16 @@
}, },
"extensions/usAnnotation": { "extensions/usAnnotation": {
"name": "@ohif/extension-ultrasound-pleura-bline", "name": "@ohif/extension-ultrasound-pleura-bline",
"version": "3.13.0-beta.68", "version": "3.13.0-beta.74",
"dependencies": { "dependencies": {
"@babel/runtime": "7.28.2", "@babel/runtime": "7.28.2",
"@cornerstonejs/core": "4.22.3", "@cornerstonejs/core": "4.22.8",
"@cornerstonejs/tools": "4.22.3", "@cornerstonejs/tools": "4.22.8",
"@ohif/core": "3.13.0-beta.68", "@ohif/core": "3.13.0-beta.74",
"@ohif/extension-cornerstone": "3.13.0-beta.68", "@ohif/extension-cornerstone": "3.13.0-beta.74",
"@ohif/extension-default": "3.13.0-beta.68", "@ohif/extension-default": "3.13.0-beta.74",
"@ohif/i18n": "3.13.0-beta.68", "@ohif/i18n": "3.13.0-beta.74",
"@ohif/ui-next": "3.13.0-beta.68", "@ohif/ui-next": "3.13.0-beta.74",
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "7.28.0", "@babel/core": "7.28.0",
@ -450,7 +450,7 @@
"@babel/plugin-transform-regenerator": "7.28.1", "@babel/plugin-transform-regenerator": "7.28.1",
"@babel/plugin-transform-runtime": "7.28.0", "@babel/plugin-transform-runtime": "7.28.0",
"@babel/plugin-transform-typescript": "7.28.0", "@babel/plugin-transform-typescript": "7.28.0",
"@babel/preset-env": "7.28.0", "@babel/preset-env": "7.29.5",
"@babel/preset-react": "7.27.1", "@babel/preset-react": "7.27.1",
"@babel/preset-typescript": "7.27.1", "@babel/preset-typescript": "7.27.1",
"@svgr/webpack": "8.1.0", "@svgr/webpack": "8.1.0",
@ -476,7 +476,7 @@
}, },
"modes/basic": { "modes/basic": {
"name": "@ohif/mode-basic", "name": "@ohif/mode-basic",
"version": "3.13.0-beta.68", "version": "3.13.0-beta.74",
"dependencies": { "dependencies": {
"@babel/runtime": "7.28.2", "@babel/runtime": "7.28.2",
}, },
@ -485,19 +485,19 @@
"webpack-merge": "5.10.0", "webpack-merge": "5.10.0",
}, },
"peerDependencies": { "peerDependencies": {
"@ohif/core": "3.13.0-beta.68", "@ohif/core": "3.13.0-beta.74",
"@ohif/extension-cornerstone": "3.13.0-beta.68", "@ohif/extension-cornerstone": "3.13.0-beta.74",
"@ohif/extension-cornerstone-dicom-rt": "3.13.0-beta.68", "@ohif/extension-cornerstone-dicom-rt": "3.13.0-beta.74",
"@ohif/extension-cornerstone-dicom-seg": "3.13.0-beta.68", "@ohif/extension-cornerstone-dicom-seg": "3.13.0-beta.74",
"@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.68", "@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.74",
"@ohif/extension-default": "3.13.0-beta.68", "@ohif/extension-default": "3.13.0-beta.74",
"@ohif/extension-dicom-pdf": "3.13.0-beta.68", "@ohif/extension-dicom-pdf": "3.13.0-beta.74",
"@ohif/extension-dicom-video": "3.13.0-beta.68", "@ohif/extension-dicom-video": "3.13.0-beta.74",
}, },
}, },
"modes/basic-dev-mode": { "modes/basic-dev-mode": {
"name": "@ohif/mode-basic-dev-mode", "name": "@ohif/mode-basic-dev-mode",
"version": "3.13.0-beta.68", "version": "3.13.0-beta.74",
"dependencies": { "dependencies": {
"@babel/runtime": "7.28.2", "@babel/runtime": "7.28.2",
"i18next": "17.3.1", "i18next": "17.3.1",
@ -507,17 +507,17 @@
"webpack-merge": "5.10.0", "webpack-merge": "5.10.0",
}, },
"peerDependencies": { "peerDependencies": {
"@ohif/core": "3.13.0-beta.68", "@ohif/core": "3.13.0-beta.74",
"@ohif/extension-cornerstone": "3.13.0-beta.68", "@ohif/extension-cornerstone": "3.13.0-beta.74",
"@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.68", "@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.74",
"@ohif/extension-default": "3.13.0-beta.68", "@ohif/extension-default": "3.13.0-beta.74",
"@ohif/extension-dicom-pdf": "3.13.0-beta.68", "@ohif/extension-dicom-pdf": "3.13.0-beta.74",
"@ohif/extension-dicom-video": "3.13.0-beta.68", "@ohif/extension-dicom-video": "3.13.0-beta.74",
}, },
}, },
"modes/basic-test-mode": { "modes/basic-test-mode": {
"name": "@ohif/mode-test", "name": "@ohif/mode-test",
"version": "3.13.0-beta.68", "version": "3.13.0-beta.74",
"dependencies": { "dependencies": {
"@babel/runtime": "7.28.2", "@babel/runtime": "7.28.2",
"i18next": "17.3.1", "i18next": "17.3.1",
@ -527,19 +527,19 @@
"webpack-merge": "5.10.0", "webpack-merge": "5.10.0",
}, },
"peerDependencies": { "peerDependencies": {
"@ohif/core": "3.13.0-beta.68", "@ohif/core": "3.13.0-beta.74",
"@ohif/extension-cornerstone": "3.13.0-beta.68", "@ohif/extension-cornerstone": "3.13.0-beta.74",
"@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.68", "@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.74",
"@ohif/extension-default": "3.13.0-beta.68", "@ohif/extension-default": "3.13.0-beta.74",
"@ohif/extension-dicom-pdf": "3.13.0-beta.68", "@ohif/extension-dicom-pdf": "3.13.0-beta.74",
"@ohif/extension-dicom-video": "3.13.0-beta.68", "@ohif/extension-dicom-video": "3.13.0-beta.74",
"@ohif/extension-measurement-tracking": "3.13.0-beta.68", "@ohif/extension-measurement-tracking": "3.13.0-beta.74",
"@ohif/extension-test": "3.13.0-beta.68", "@ohif/extension-test": "3.13.0-beta.74",
}, },
}, },
"modes/longitudinal": { "modes/longitudinal": {
"name": "@ohif/mode-longitudinal", "name": "@ohif/mode-longitudinal",
"version": "3.13.0-beta.68", "version": "3.13.0-beta.74",
"dependencies": { "dependencies": {
"@babel/runtime": "7.28.2", "@babel/runtime": "7.28.2",
"i18next": "17.3.1", "i18next": "17.3.1",
@ -549,33 +549,33 @@
"webpack-merge": "5.10.0", "webpack-merge": "5.10.0",
}, },
"peerDependencies": { "peerDependencies": {
"@ohif/core": "3.13.0-beta.68", "@ohif/core": "3.13.0-beta.74",
"@ohif/extension-cornerstone": "3.13.0-beta.68", "@ohif/extension-cornerstone": "3.13.0-beta.74",
"@ohif/extension-cornerstone-dicom-rt": "3.13.0-beta.68", "@ohif/extension-cornerstone-dicom-rt": "3.13.0-beta.74",
"@ohif/extension-cornerstone-dicom-seg": "3.13.0-beta.68", "@ohif/extension-cornerstone-dicom-seg": "3.13.0-beta.74",
"@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.68", "@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.74",
"@ohif/extension-default": "3.13.0-beta.68", "@ohif/extension-default": "3.13.0-beta.74",
"@ohif/extension-dicom-pdf": "3.13.0-beta.68", "@ohif/extension-dicom-pdf": "3.13.0-beta.74",
"@ohif/extension-dicom-video": "3.13.0-beta.68", "@ohif/extension-dicom-video": "3.13.0-beta.74",
"@ohif/extension-measurement-tracking": "3.13.0-beta.68", "@ohif/extension-measurement-tracking": "3.13.0-beta.74",
"@ohif/mode-basic": "3.13.0-beta.68", "@ohif/mode-basic": "3.13.0-beta.74",
}, },
}, },
"modes/microscopy": { "modes/microscopy": {
"name": "@ohif/mode-microscopy", "name": "@ohif/mode-microscopy",
"version": "3.13.0-beta.68", "version": "3.13.0-beta.74",
"dependencies": { "dependencies": {
"@babel/runtime": "7.28.2", "@babel/runtime": "7.28.2",
"i18next": "17.3.1", "i18next": "17.3.1",
}, },
"peerDependencies": { "peerDependencies": {
"@ohif/core": "3.13.0-beta.68", "@ohif/core": "3.13.0-beta.74",
"@ohif/extension-dicom-microscopy": "3.13.0-beta.68", "@ohif/extension-dicom-microscopy": "3.13.0-beta.74",
}, },
}, },
"modes/preclinical-4d": { "modes/preclinical-4d": {
"name": "@ohif/mode-preclinical-4d", "name": "@ohif/mode-preclinical-4d",
"version": "3.13.0-beta.68", "version": "3.13.0-beta.74",
"dependencies": { "dependencies": {
"@babel/runtime": "7.28.2", "@babel/runtime": "7.28.2",
}, },
@ -594,7 +594,7 @@
}, },
"modes/segmentation": { "modes/segmentation": {
"name": "@ohif/mode-segmentation", "name": "@ohif/mode-segmentation",
"version": "3.13.0-beta.68", "version": "3.13.0-beta.74",
"dependencies": { "dependencies": {
"@babel/runtime": "7.28.2", "@babel/runtime": "7.28.2",
"i18next": "17.3.1", "i18next": "17.3.1",
@ -609,7 +609,7 @@
"@babel/plugin-transform-regenerator": "7.28.1", "@babel/plugin-transform-regenerator": "7.28.1",
"@babel/plugin-transform-runtime": "7.28.0", "@babel/plugin-transform-runtime": "7.28.0",
"@babel/plugin-transform-typescript": "7.28.0", "@babel/plugin-transform-typescript": "7.28.0",
"@babel/preset-env": "7.28.0", "@babel/preset-env": "7.29.5",
"@babel/preset-react": "7.27.1", "@babel/preset-react": "7.27.1",
"@babel/preset-typescript": "7.27.1", "@babel/preset-typescript": "7.27.1",
"@svgr/webpack": "8.1.0", "@svgr/webpack": "8.1.0",
@ -623,20 +623,20 @@
"webpack-merge": "5.10.0", "webpack-merge": "5.10.0",
}, },
"peerDependencies": { "peerDependencies": {
"@ohif/core": "3.13.0-beta.68", "@ohif/core": "3.13.0-beta.74",
"@ohif/extension-cornerstone": "3.13.0-beta.68", "@ohif/extension-cornerstone": "3.13.0-beta.74",
"@ohif/extension-cornerstone-dicom-rt": "3.13.0-beta.68", "@ohif/extension-cornerstone-dicom-rt": "3.13.0-beta.74",
"@ohif/extension-cornerstone-dicom-seg": "3.13.0-beta.68", "@ohif/extension-cornerstone-dicom-seg": "3.13.0-beta.74",
"@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.68", "@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.74",
"@ohif/extension-default": "3.13.0-beta.68", "@ohif/extension-default": "3.13.0-beta.74",
"@ohif/extension-dicom-pdf": "3.13.0-beta.68", "@ohif/extension-dicom-pdf": "3.13.0-beta.74",
"@ohif/extension-dicom-video": "3.13.0-beta.68", "@ohif/extension-dicom-video": "3.13.0-beta.74",
"@ohif/mode-basic": "3.13.0-beta.68", "@ohif/mode-basic": "3.13.0-beta.74",
}, },
}, },
"modes/tmtv": { "modes/tmtv": {
"name": "@ohif/mode-tmtv", "name": "@ohif/mode-tmtv",
"version": "3.13.0-beta.68", "version": "3.13.0-beta.74",
"dependencies": { "dependencies": {
"@babel/runtime": "7.28.2", "@babel/runtime": "7.28.2",
"i18next": "17.3.1", "i18next": "17.3.1",
@ -657,14 +657,14 @@
}, },
"modes/usAnnotation": { "modes/usAnnotation": {
"name": "@ohif/mode-ultrasound-pleura-bline", "name": "@ohif/mode-ultrasound-pleura-bline",
"version": "3.13.0-beta.68", "version": "3.13.0-beta.74",
"dependencies": { "dependencies": {
"@babel/runtime": "7.28.2", "@babel/runtime": "7.28.2",
"@cornerstonejs/core": "4.22.3", "@cornerstonejs/core": "4.22.8",
"@cornerstonejs/tools": "4.22.3", "@cornerstonejs/tools": "4.22.8",
"@ohif/core": "3.13.0-beta.68", "@ohif/core": "3.13.0-beta.74",
"@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.68", "@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.74",
"@ohif/extension-ultrasound-pleura-bline": "3.13.0-beta.68", "@ohif/extension-ultrasound-pleura-bline": "3.13.0-beta.74",
"i18next": "17.3.1", "i18next": "17.3.1",
}, },
"devDependencies": { "devDependencies": {
@ -677,7 +677,7 @@
"@babel/plugin-transform-regenerator": "7.28.1", "@babel/plugin-transform-regenerator": "7.28.1",
"@babel/plugin-transform-runtime": "7.28.0", "@babel/plugin-transform-runtime": "7.28.0",
"@babel/plugin-transform-typescript": "7.28.0", "@babel/plugin-transform-typescript": "7.28.0",
"@babel/preset-env": "7.28.0", "@babel/preset-env": "7.29.5",
"@babel/preset-react": "7.27.1", "@babel/preset-react": "7.27.1",
"@babel/preset-typescript": "7.27.1", "@babel/preset-typescript": "7.27.1",
"@svgr/webpack": "8.1.0", "@svgr/webpack": "8.1.0",
@ -693,34 +693,34 @@
}, },
"platform/app": { "platform/app": {
"name": "@ohif/app", "name": "@ohif/app",
"version": "3.13.0-beta.68", "version": "3.13.0-beta.74",
"dependencies": { "dependencies": {
"@babel/runtime": "7.28.2", "@babel/runtime": "7.28.2",
"@cornerstonejs/codec-charls": "1.2.3", "@cornerstonejs/codec-charls": "1.2.3",
"@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2", "@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2",
"@cornerstonejs/codec-openjpeg": "1.3.0", "@cornerstonejs/codec-openjpeg": "1.3.0",
"@cornerstonejs/codec-openjph": "2.4.7", "@cornerstonejs/codec-openjph": "2.4.7",
"@cornerstonejs/dicom-image-loader": "4.22.3", "@cornerstonejs/dicom-image-loader": "4.22.8",
"@emotion/serialize": "1.3.3", "@emotion/serialize": "1.3.3",
"@ohif/core": "3.13.0-beta.68", "@ohif/core": "3.13.0-beta.74",
"@ohif/extension-cornerstone": "3.13.0-beta.68", "@ohif/extension-cornerstone": "3.13.0-beta.74",
"@ohif/extension-cornerstone-dicom-rt": "3.13.0-beta.68", "@ohif/extension-cornerstone-dicom-rt": "3.13.0-beta.74",
"@ohif/extension-cornerstone-dicom-seg": "3.13.0-beta.68", "@ohif/extension-cornerstone-dicom-seg": "3.13.0-beta.74",
"@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.68", "@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.74",
"@ohif/extension-default": "3.13.0-beta.68", "@ohif/extension-default": "3.13.0-beta.74",
"@ohif/extension-dicom-microscopy": "3.13.0-beta.68", "@ohif/extension-dicom-microscopy": "3.13.0-beta.74",
"@ohif/extension-dicom-pdf": "3.13.0-beta.68", "@ohif/extension-dicom-pdf": "3.13.0-beta.74",
"@ohif/extension-dicom-video": "3.13.0-beta.68", "@ohif/extension-dicom-video": "3.13.0-beta.74",
"@ohif/extension-test": "3.13.0-beta.68", "@ohif/extension-test": "3.13.0-beta.74",
"@ohif/extension-ultrasound-pleura-bline": "3.13.0-beta.68", "@ohif/extension-ultrasound-pleura-bline": "3.13.0-beta.74",
"@ohif/i18n": "3.13.0-beta.68", "@ohif/i18n": "3.13.0-beta.74",
"@ohif/mode-basic-dev-mode": "3.13.0-beta.68", "@ohif/mode-basic-dev-mode": "3.13.0-beta.74",
"@ohif/mode-longitudinal": "3.13.0-beta.68", "@ohif/mode-longitudinal": "3.13.0-beta.74",
"@ohif/mode-microscopy": "3.13.0-beta.68", "@ohif/mode-microscopy": "3.13.0-beta.74",
"@ohif/mode-test": "3.13.0-beta.68", "@ohif/mode-test": "3.13.0-beta.74",
"@ohif/mode-ultrasound-pleura-bline": "3.13.0-beta.68", "@ohif/mode-ultrasound-pleura-bline": "3.13.0-beta.74",
"@ohif/ui": "3.13.0-beta.68", "@ohif/ui": "3.13.0-beta.74",
"@ohif/ui-next": "3.13.0-beta.68", "@ohif/ui-next": "3.13.0-beta.74",
"@svgr/webpack": "8.1.0", "@svgr/webpack": "8.1.0",
"@types/react": "18.3.23", "@types/react": "18.3.23",
"classnames": "2.5.1", "classnames": "2.5.1",
@ -772,7 +772,7 @@
}, },
"platform/cli": { "platform/cli": {
"name": "@ohif/cli", "name": "@ohif/cli",
"version": "3.13.0-beta.68", "version": "3.13.0-beta.74",
"bin": { "bin": {
"ohif-cli": "src/index.js", "ohif-cli": "src/index.js",
}, },
@ -796,7 +796,7 @@
}, },
"platform/core": { "platform/core": {
"name": "@ohif/core", "name": "@ohif/core",
"version": "3.13.0-beta.68", "version": "3.13.0-beta.74",
"dependencies": { "dependencies": {
"@babel/runtime": "7.28.2", "@babel/runtime": "7.28.2",
"dcmjs": "0.49.4", "dcmjs": "0.49.4",
@ -821,16 +821,16 @@
"@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2", "@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2",
"@cornerstonejs/codec-openjpeg": "1.3.0", "@cornerstonejs/codec-openjpeg": "1.3.0",
"@cornerstonejs/codec-openjph": "2.4.7", "@cornerstonejs/codec-openjph": "2.4.7",
"@cornerstonejs/core": "4.22.3", "@cornerstonejs/core": "4.22.8",
"@cornerstonejs/dicom-image-loader": "4.22.3", "@cornerstonejs/dicom-image-loader": "4.22.8",
"@ohif/ui": "3.13.0-beta.68", "@ohif/ui": "3.13.0-beta.74",
"cornerstone-math": "0.1.10", "cornerstone-math": "0.1.10",
"dicom-parser": "1.8.21", "dicom-parser": "1.8.21",
}, },
}, },
"platform/i18n": { "platform/i18n": {
"name": "@ohif/i18n", "name": "@ohif/i18n",
"version": "3.13.0-beta.68", "version": "3.13.0-beta.74",
"dependencies": { "dependencies": {
"@babel/runtime": "7.28.2", "@babel/runtime": "7.28.2",
"i18next-locize-backend": "2.2.2", "i18next-locize-backend": "2.2.2",
@ -855,7 +855,7 @@
}, },
"platform/ui": { "platform/ui": {
"name": "@ohif/ui", "name": "@ohif/ui",
"version": "3.13.0-beta.68", "version": "3.13.0-beta.74",
"dependencies": { "dependencies": {
"@testing-library/react": "13.4.0", "@testing-library/react": "13.4.0",
"browser-detect": "0.2.28", "browser-detect": "0.2.28",
@ -905,7 +905,7 @@
}, },
"platform/ui-next": { "platform/ui-next": {
"name": "@ohif/ui-next", "name": "@ohif/ui-next",
"version": "3.13.0-beta.68", "version": "3.13.0-beta.74",
"dependencies": { "dependencies": {
"@radix-ui/react-accordion": "1.2.11", "@radix-ui/react-accordion": "1.2.11",
"@radix-ui/react-checkbox": "1.3.2", "@radix-ui/react-checkbox": "1.3.2",
@ -1245,9 +1245,9 @@
"@bcoe/v8-coverage": ["@bcoe/v8-coverage@0.2.3", "", {}, "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw=="], "@bcoe/v8-coverage": ["@bcoe/v8-coverage@0.2.3", "", {}, "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw=="],
"@cornerstonejs/adapters": ["@cornerstonejs/adapters@4.22.3", "", { "dependencies": { "@babel/runtime-corejs2": "7.26.10", "buffer": "6.0.3", "dcmjs": "0.49.4", "gl-matrix": "3.4.3", "ndarray": "1.0.19" }, "peerDependencies": { "@cornerstonejs/core": "4.22.3", "@cornerstonejs/tools": "4.22.3" } }, "sha512-58TaTUl7AmLARnKApfz9c5IWzIaPPewH8sjD0BxKu5PeVHSRSlKX7jH4pv1akapIbDqXBEW6unb45kLmm6u7dg=="], "@cornerstonejs/adapters": ["@cornerstonejs/adapters@4.22.8", "", { "dependencies": { "@babel/runtime-corejs2": "7.26.10", "buffer": "6.0.3", "dcmjs": "0.49.4", "gl-matrix": "3.4.3", "ndarray": "1.0.19" }, "peerDependencies": { "@cornerstonejs/core": "4.22.8", "@cornerstonejs/tools": "4.22.8" } }, "sha512-WUphdrsQVGqUN5KPt75FN4a7/tL49k41eCLa5fW8FmhNoi/NkmCPlr91z0ixf07P2dMtzv/eSmJ3IZI6W+FIrw=="],
"@cornerstonejs/ai": ["@cornerstonejs/ai@4.22.3", "", { "dependencies": { "@babel/runtime-corejs2": "7.26.10", "buffer": "6.0.3", "dcmjs": "0.49.4", "gl-matrix": "3.4.3", "lodash.clonedeep": "4.5.0", "ndarray": "1.0.19", "onnxruntime-common": "1.17.1", "onnxruntime-web": "1.17.1" }, "peerDependencies": { "@cornerstonejs/core": "4.22.3", "@cornerstonejs/tools": "4.22.3" } }, "sha512-NhRcQISjcDCp7rWCK9hGmCgsS36XKyT4AsCBgXuG7iU3ghI77j5kt9sUdqi0M4lRYLYZ1XMrFSDjNDCwFP+eYg=="], "@cornerstonejs/ai": ["@cornerstonejs/ai@4.22.8", "", { "dependencies": { "@babel/runtime-corejs2": "7.26.10", "buffer": "6.0.3", "dcmjs": "0.49.4", "gl-matrix": "3.4.3", "lodash.clonedeep": "4.5.0", "ndarray": "1.0.19", "onnxruntime-common": "1.17.1", "onnxruntime-web": "1.17.1" }, "peerDependencies": { "@cornerstonejs/core": "4.22.8", "@cornerstonejs/tools": "4.22.8" } }, "sha512-rN/7nicjphDsOWqPGTzbq/BTJD8dy2r7XW4P46FnyEPRmO8KVisTOvHaEEu3EklMVqvodbRzigW73kO1mh7eNw=="],
"@cornerstonejs/calculate-suv": ["@cornerstonejs/calculate-suv@1.1.0", "", {}, "sha512-Q9XraiDJif9aMFArD2iEuDO/HXbcRVCqB7KfaHgDrdTTjgDFovS91Psbdim7crypRSvE6dh/+HKeFNHdvNkA6w=="], "@cornerstonejs/calculate-suv": ["@cornerstonejs/calculate-suv@1.1.0", "", {}, "sha512-Q9XraiDJif9aMFArD2iEuDO/HXbcRVCqB7KfaHgDrdTTjgDFovS91Psbdim7crypRSvE6dh/+HKeFNHdvNkA6w=="],
@ -1259,15 +1259,15 @@
"@cornerstonejs/codec-openjph": ["@cornerstonejs/codec-openjph@2.4.7", "", {}, "sha512-qvP4q4JDib7mi9r7LqKOwqz7YZ8gjtDX4ZCezeYf8+eb7MBXCz5uXAMeVF3yz9Axw4XiIMdB/pqXkm8tqCl13w=="], "@cornerstonejs/codec-openjph": ["@cornerstonejs/codec-openjph@2.4.7", "", {}, "sha512-qvP4q4JDib7mi9r7LqKOwqz7YZ8gjtDX4ZCezeYf8+eb7MBXCz5uXAMeVF3yz9Axw4XiIMdB/pqXkm8tqCl13w=="],
"@cornerstonejs/core": ["@cornerstonejs/core@4.22.3", "", { "dependencies": { "@kitware/vtk.js": "34.15.1", "comlink": "4.4.2", "gl-matrix": "3.4.3", "loglevel": "1.9.2" } }, "sha512-oxLcg24ER3HHSAEsz3iG7+cb2oHnVSzt7H8EeRtK69e6Ztjl6XkEmXeAbbJypm2QYIkPYb3oJb6zWeYOz1NtYw=="], "@cornerstonejs/core": ["@cornerstonejs/core@4.22.8", "", { "dependencies": { "@kitware/vtk.js": "34.15.1", "comlink": "4.4.2", "gl-matrix": "3.4.3", "loglevel": "1.9.2" } }, "sha512-GOv8sTwV3hqhZpAYSFH/yhNj15TgcWh364ndIegT29g87FURHu8Ql9cF6irOamAuehJ3YKfbPxUZzqiXtfyPDg=="],
"@cornerstonejs/dicom-image-loader": ["@cornerstonejs/dicom-image-loader@4.22.3", "", { "dependencies": { "@cornerstonejs/codec-charls": "1.2.3", "@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2", "@cornerstonejs/codec-openjpeg": "1.3.0", "@cornerstonejs/codec-openjph": "2.4.7", "comlink": "4.4.2", "dicom-parser": "1.8.21", "jpeg-lossless-decoder-js": "2.1.2", "pako": "2.1.0", "uuid": "9.0.1" }, "peerDependencies": { "@cornerstonejs/core": "4.22.3" } }, "sha512-TVPSc3PUvy2I6+ZnWX8B2uqJZ5onUd/+e+m/BfeEdZC51GMhC4VfTmqOwOjWDNDyO35ZA9j1mqk8iIJzDpqoeA=="], "@cornerstonejs/dicom-image-loader": ["@cornerstonejs/dicom-image-loader@4.22.8", "", { "dependencies": { "@cornerstonejs/codec-charls": "1.2.3", "@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2", "@cornerstonejs/codec-openjpeg": "1.3.0", "@cornerstonejs/codec-openjph": "2.4.7", "comlink": "4.4.2", "dicom-parser": "1.8.21", "jpeg-lossless-decoder-js": "2.1.2", "pako": "2.1.0", "uuid": "9.0.1" }, "peerDependencies": { "@cornerstonejs/core": "4.22.8" } }, "sha512-3Bb3xJiO9ddDCeT/wHL8R0G1t8W4+aYY8N9YGV+eMUI1WTkRES3WH3N7U8EtjLYXKqfc15NIEe78Otf2qS+CgQ=="],
"@cornerstonejs/labelmap-interpolation": ["@cornerstonejs/labelmap-interpolation@4.22.3", "", { "dependencies": { "@itk-wasm/morphological-contour-interpolation": "1.1.0", "itk-wasm": "1.0.0-b.165" }, "peerDependencies": { "@cornerstonejs/core": "4.22.3", "@cornerstonejs/tools": "4.22.3", "@kitware/vtk.js": "34.15.1" } }, "sha512-ngschi2EKr+47LWbbTiu6tt3aw4e7yp0mVCDXwJm1Z2eyugemiiAQvOT77EKSBZ//L2fAZR3Edr+qJFzPa5KUw=="], "@cornerstonejs/labelmap-interpolation": ["@cornerstonejs/labelmap-interpolation@4.22.8", "", { "dependencies": { "@itk-wasm/morphological-contour-interpolation": "1.1.0", "itk-wasm": "1.0.0-b.165" }, "peerDependencies": { "@cornerstonejs/core": "4.22.8", "@cornerstonejs/tools": "4.22.8", "@kitware/vtk.js": "34.15.1" } }, "sha512-GKr123lPCr6Tl3GDOFMjm0m+gexDvAJjYYGshCcSx6/pT6PT30ALRXi0pXXdcGr1kbk9SKEMM1uzxFLXJs6uIQ=="],
"@cornerstonejs/polymorphic-segmentation": ["@cornerstonejs/polymorphic-segmentation@4.22.3", "", { "dependencies": { "@icr/polyseg-wasm": "0.4.0" }, "peerDependencies": { "@cornerstonejs/core": "4.22.3", "@cornerstonejs/tools": "4.22.3", "@kitware/vtk.js": "34.15.1" } }, "sha512-JNmtLbuwY8de3uwFf1YqySp5wt2BCT6kpg9gcoDNMmNxGDo0uT5yph1Muh+24sG7WDaoRwyzAEvG11h9NHgoqw=="], "@cornerstonejs/polymorphic-segmentation": ["@cornerstonejs/polymorphic-segmentation@4.22.8", "", { "dependencies": { "@icr/polyseg-wasm": "0.4.0" }, "peerDependencies": { "@cornerstonejs/core": "4.22.8", "@cornerstonejs/tools": "4.22.8", "@kitware/vtk.js": "34.15.1" } }, "sha512-cLliz/E4BjKKw7rnyYvDprc8BK011LwaCwvWv6h9iUGWm2j72NhsRLf2jdcpEav3wyUJtWDHlvXO3QBzlHHW0A=="],
"@cornerstonejs/tools": ["@cornerstonejs/tools@4.22.3", "", { "dependencies": { "@types/offscreencanvas": "2019.7.3", "comlink": "4.4.2", "lodash.get": "4.4.2" }, "peerDependencies": { "@cornerstonejs/core": "4.22.3", "@kitware/vtk.js": "34.15.1", "@types/d3-array": "3.2.1", "@types/d3-interpolate": "3.0.4", "d3-array": "3.2.4", "d3-interpolate": "3.0.1", "gl-matrix": "3.4.3" } }, "sha512-2XQmUesRWiqWTh3xGnLsQ6qqKI55vSVV4UqGXiPxnMcf6azDfEhcJO8JJCH1VXaDa89jxLBdZUDehUnb0UsIxA=="], "@cornerstonejs/tools": ["@cornerstonejs/tools@4.22.8", "", { "dependencies": { "@types/offscreencanvas": "2019.7.3", "comlink": "4.4.2", "lodash.get": "4.4.2" }, "peerDependencies": { "@cornerstonejs/core": "4.22.8", "@kitware/vtk.js": "34.15.1", "@types/d3-array": "3.2.1", "@types/d3-interpolate": "3.0.4", "d3-array": "3.2.4", "d3-interpolate": "3.0.1", "gl-matrix": "3.4.3" } }, "sha512-vDTMIOJ+oZJyPixg/iQbYNM9XFz2Ud+VGMAf6mAP3LhpH7ofCh0Phkf9BtJiCjKT+IQqloFSvWjy6aoLd8KNJA=="],
"@cspotcode/source-map-support": ["@cspotcode/source-map-support@0.8.1", "", { "dependencies": { "@jridgewell/trace-mapping": "0.3.9" } }, "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw=="], "@cspotcode/source-map-support": ["@cspotcode/source-map-support@0.8.1", "", { "dependencies": { "@jridgewell/trace-mapping": "0.3.9" } }, "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw=="],
@ -5581,12 +5581,6 @@
"@ohif/app/copy-webpack-plugin": ["copy-webpack-plugin@10.2.4", "", { "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" }, "peerDependencies": { "webpack": "^5.1.0" } }, "sha512-xFVltahqlsRcyyJqQbDY6EYTtyQZF9rf+JPjwHObLdPFMEISqkFkr7mFoVOC6BfYS/dNThyoQKvziugm+OnwBg=="], "@ohif/app/copy-webpack-plugin": ["copy-webpack-plugin@10.2.4", "", { "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" }, "peerDependencies": { "webpack": "^5.1.0" } }, "sha512-xFVltahqlsRcyyJqQbDY6EYTtyQZF9rf+JPjwHObLdPFMEISqkFkr7mFoVOC6BfYS/dNThyoQKvziugm+OnwBg=="],
"@ohif/extension-ultrasound-pleura-bline/@babel/preset-env": ["@babel/preset-env@7.28.0", "", { "dependencies": { "@babel/compat-data": "^7.28.0", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.27.1", "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.27.1", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-import-assertions": "^7.27.1", "@babel/plugin-syntax-import-attributes": "^7.27.1", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.27.1", "@babel/plugin-transform-async-generator-functions": "^7.28.0", "@babel/plugin-transform-async-to-generator": "^7.27.1", "@babel/plugin-transform-block-scoped-functions": "^7.27.1", "@babel/plugin-transform-block-scoping": "^7.28.0", "@babel/plugin-transform-class-properties": "^7.27.1", "@babel/plugin-transform-class-static-block": "^7.27.1", "@babel/plugin-transform-classes": "^7.28.0", "@babel/plugin-transform-computed-properties": "^7.27.1", "@babel/plugin-transform-destructuring": "^7.28.0", "@babel/plugin-transform-dotall-regex": "^7.27.1", "@babel/plugin-transform-duplicate-keys": "^7.27.1", "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1", "@babel/plugin-transform-dynamic-import": "^7.27.1", "@babel/plugin-transform-explicit-resource-management": "^7.28.0", "@babel/plugin-transform-exponentiation-operator": "^7.27.1", "@babel/plugin-transform-export-namespace-from": "^7.27.1", "@babel/plugin-transform-for-of": "^7.27.1", "@babel/plugin-transform-function-name": "^7.27.1", "@babel/plugin-transform-json-strings": "^7.27.1", "@babel/plugin-transform-literals": "^7.27.1", "@babel/plugin-transform-logical-assignment-operators": "^7.27.1", "@babel/plugin-transform-member-expression-literals": "^7.27.1", "@babel/plugin-transform-modules-amd": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.27.1", "@babel/plugin-transform-modules-systemjs": "^7.27.1", "@babel/plugin-transform-modules-umd": "^7.27.1", "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1", "@babel/plugin-transform-new-target": "^7.27.1", "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", "@babel/plugin-transform-numeric-separator": "^7.27.1", "@babel/plugin-transform-object-rest-spread": "^7.28.0", "@babel/plugin-transform-object-super": "^7.27.1", "@babel/plugin-transform-optional-catch-binding": "^7.27.1", "@babel/plugin-transform-optional-chaining": "^7.27.1", "@babel/plugin-transform-parameters": "^7.27.7", "@babel/plugin-transform-private-methods": "^7.27.1", "@babel/plugin-transform-private-property-in-object": "^7.27.1", "@babel/plugin-transform-property-literals": "^7.27.1", "@babel/plugin-transform-regenerator": "^7.28.0", "@babel/plugin-transform-regexp-modifiers": "^7.27.1", "@babel/plugin-transform-reserved-words": "^7.27.1", "@babel/plugin-transform-shorthand-properties": "^7.27.1", "@babel/plugin-transform-spread": "^7.27.1", "@babel/plugin-transform-sticky-regex": "^7.27.1", "@babel/plugin-transform-template-literals": "^7.27.1", "@babel/plugin-transform-typeof-symbol": "^7.27.1", "@babel/plugin-transform-unicode-escapes": "^7.27.1", "@babel/plugin-transform-unicode-property-regex": "^7.27.1", "@babel/plugin-transform-unicode-regex": "^7.27.1", "@babel/plugin-transform-unicode-sets-regex": "^7.27.1", "@babel/preset-modules": "0.1.6-no-external-plugins", "babel-plugin-polyfill-corejs2": "^0.4.14", "babel-plugin-polyfill-corejs3": "^0.13.0", "babel-plugin-polyfill-regenerator": "^0.6.5", "core-js-compat": "^3.43.0", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-VmaxeGOwuDqzLl5JUkIRM1X2Qu2uKGxHEQWh+cvvbl7JuJRgKGJSfsEF/bUaxFhJl/XAyxBe7q7qSuTbKFuCyg=="],
"@ohif/mode-segmentation/@babel/preset-env": ["@babel/preset-env@7.28.0", "", { "dependencies": { "@babel/compat-data": "^7.28.0", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.27.1", "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.27.1", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-import-assertions": "^7.27.1", "@babel/plugin-syntax-import-attributes": "^7.27.1", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.27.1", "@babel/plugin-transform-async-generator-functions": "^7.28.0", "@babel/plugin-transform-async-to-generator": "^7.27.1", "@babel/plugin-transform-block-scoped-functions": "^7.27.1", "@babel/plugin-transform-block-scoping": "^7.28.0", "@babel/plugin-transform-class-properties": "^7.27.1", "@babel/plugin-transform-class-static-block": "^7.27.1", "@babel/plugin-transform-classes": "^7.28.0", "@babel/plugin-transform-computed-properties": "^7.27.1", "@babel/plugin-transform-destructuring": "^7.28.0", "@babel/plugin-transform-dotall-regex": "^7.27.1", "@babel/plugin-transform-duplicate-keys": "^7.27.1", "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1", "@babel/plugin-transform-dynamic-import": "^7.27.1", "@babel/plugin-transform-explicit-resource-management": "^7.28.0", "@babel/plugin-transform-exponentiation-operator": "^7.27.1", "@babel/plugin-transform-export-namespace-from": "^7.27.1", "@babel/plugin-transform-for-of": "^7.27.1", "@babel/plugin-transform-function-name": "^7.27.1", "@babel/plugin-transform-json-strings": "^7.27.1", "@babel/plugin-transform-literals": "^7.27.1", "@babel/plugin-transform-logical-assignment-operators": "^7.27.1", "@babel/plugin-transform-member-expression-literals": "^7.27.1", "@babel/plugin-transform-modules-amd": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.27.1", "@babel/plugin-transform-modules-systemjs": "^7.27.1", "@babel/plugin-transform-modules-umd": "^7.27.1", "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1", "@babel/plugin-transform-new-target": "^7.27.1", "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", "@babel/plugin-transform-numeric-separator": "^7.27.1", "@babel/plugin-transform-object-rest-spread": "^7.28.0", "@babel/plugin-transform-object-super": "^7.27.1", "@babel/plugin-transform-optional-catch-binding": "^7.27.1", "@babel/plugin-transform-optional-chaining": "^7.27.1", "@babel/plugin-transform-parameters": "^7.27.7", "@babel/plugin-transform-private-methods": "^7.27.1", "@babel/plugin-transform-private-property-in-object": "^7.27.1", "@babel/plugin-transform-property-literals": "^7.27.1", "@babel/plugin-transform-regenerator": "^7.28.0", "@babel/plugin-transform-regexp-modifiers": "^7.27.1", "@babel/plugin-transform-reserved-words": "^7.27.1", "@babel/plugin-transform-shorthand-properties": "^7.27.1", "@babel/plugin-transform-spread": "^7.27.1", "@babel/plugin-transform-sticky-regex": "^7.27.1", "@babel/plugin-transform-template-literals": "^7.27.1", "@babel/plugin-transform-typeof-symbol": "^7.27.1", "@babel/plugin-transform-unicode-escapes": "^7.27.1", "@babel/plugin-transform-unicode-property-regex": "^7.27.1", "@babel/plugin-transform-unicode-regex": "^7.27.1", "@babel/plugin-transform-unicode-sets-regex": "^7.27.1", "@babel/preset-modules": "0.1.6-no-external-plugins", "babel-plugin-polyfill-corejs2": "^0.4.14", "babel-plugin-polyfill-corejs3": "^0.13.0", "babel-plugin-polyfill-regenerator": "^0.6.5", "core-js-compat": "^3.43.0", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-VmaxeGOwuDqzLl5JUkIRM1X2Qu2uKGxHEQWh+cvvbl7JuJRgKGJSfsEF/bUaxFhJl/XAyxBe7q7qSuTbKFuCyg=="],
"@ohif/mode-ultrasound-pleura-bline/@babel/preset-env": ["@babel/preset-env@7.28.0", "", { "dependencies": { "@babel/compat-data": "^7.28.0", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.27.1", "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.27.1", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-import-assertions": "^7.27.1", "@babel/plugin-syntax-import-attributes": "^7.27.1", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.27.1", "@babel/plugin-transform-async-generator-functions": "^7.28.0", "@babel/plugin-transform-async-to-generator": "^7.27.1", "@babel/plugin-transform-block-scoped-functions": "^7.27.1", "@babel/plugin-transform-block-scoping": "^7.28.0", "@babel/plugin-transform-class-properties": "^7.27.1", "@babel/plugin-transform-class-static-block": "^7.27.1", "@babel/plugin-transform-classes": "^7.28.0", "@babel/plugin-transform-computed-properties": "^7.27.1", "@babel/plugin-transform-destructuring": "^7.28.0", "@babel/plugin-transform-dotall-regex": "^7.27.1", "@babel/plugin-transform-duplicate-keys": "^7.27.1", "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1", "@babel/plugin-transform-dynamic-import": "^7.27.1", "@babel/plugin-transform-explicit-resource-management": "^7.28.0", "@babel/plugin-transform-exponentiation-operator": "^7.27.1", "@babel/plugin-transform-export-namespace-from": "^7.27.1", "@babel/plugin-transform-for-of": "^7.27.1", "@babel/plugin-transform-function-name": "^7.27.1", "@babel/plugin-transform-json-strings": "^7.27.1", "@babel/plugin-transform-literals": "^7.27.1", "@babel/plugin-transform-logical-assignment-operators": "^7.27.1", "@babel/plugin-transform-member-expression-literals": "^7.27.1", "@babel/plugin-transform-modules-amd": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.27.1", "@babel/plugin-transform-modules-systemjs": "^7.27.1", "@babel/plugin-transform-modules-umd": "^7.27.1", "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1", "@babel/plugin-transform-new-target": "^7.27.1", "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", "@babel/plugin-transform-numeric-separator": "^7.27.1", "@babel/plugin-transform-object-rest-spread": "^7.28.0", "@babel/plugin-transform-object-super": "^7.27.1", "@babel/plugin-transform-optional-catch-binding": "^7.27.1", "@babel/plugin-transform-optional-chaining": "^7.27.1", "@babel/plugin-transform-parameters": "^7.27.7", "@babel/plugin-transform-private-methods": "^7.27.1", "@babel/plugin-transform-private-property-in-object": "^7.27.1", "@babel/plugin-transform-property-literals": "^7.27.1", "@babel/plugin-transform-regenerator": "^7.28.0", "@babel/plugin-transform-regexp-modifiers": "^7.27.1", "@babel/plugin-transform-reserved-words": "^7.27.1", "@babel/plugin-transform-shorthand-properties": "^7.27.1", "@babel/plugin-transform-spread": "^7.27.1", "@babel/plugin-transform-sticky-regex": "^7.27.1", "@babel/plugin-transform-template-literals": "^7.27.1", "@babel/plugin-transform-typeof-symbol": "^7.27.1", "@babel/plugin-transform-unicode-escapes": "^7.27.1", "@babel/plugin-transform-unicode-property-regex": "^7.27.1", "@babel/plugin-transform-unicode-regex": "^7.27.1", "@babel/plugin-transform-unicode-sets-regex": "^7.27.1", "@babel/preset-modules": "0.1.6-no-external-plugins", "babel-plugin-polyfill-corejs2": "^0.4.14", "babel-plugin-polyfill-corejs3": "^0.13.0", "babel-plugin-polyfill-regenerator": "^0.6.5", "core-js-compat": "^3.43.0", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-VmaxeGOwuDqzLl5JUkIRM1X2Qu2uKGxHEQWh+cvvbl7JuJRgKGJSfsEF/bUaxFhJl/XAyxBe7q7qSuTbKFuCyg=="],
"@protobufjs/fetch/@protobufjs/inquire": ["@protobufjs/inquire@1.1.0", "", {}, "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q=="], "@protobufjs/fetch/@protobufjs/inquire": ["@protobufjs/inquire@1.1.0", "", {}, "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q=="],
"@rollup/plugin-node-resolve/deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="], "@rollup/plugin-node-resolve/deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="],
@ -6669,180 +6663,6 @@
"@ohif/app/copy-webpack-plugin/globby": ["globby@12.2.0", "", { "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" } }, "sha512-wiSuFQLZ+urS9x2gGPl1H5drc5twabmm4m2gTR27XDFyjUHJUNsS8o/2aKyIF6IoBaR630atdher0XJ5g6OMmA=="], "@ohif/app/copy-webpack-plugin/globby": ["globby@12.2.0", "", { "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" } }, "sha512-wiSuFQLZ+urS9x2gGPl1H5drc5twabmm4m2gTR27XDFyjUHJUNsS8o/2aKyIF6IoBaR630atdher0XJ5g6OMmA=="],
"@ohif/extension-ultrasound-pleura-bline/@babel/preset-env/@babel/compat-data": ["@babel/compat-data@7.28.0", "", {}, "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw=="],
"@ohif/extension-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-bugfix-firefox-class-in-computed-class-key": ["@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-QPG3C9cCVRQLxAVwmefEmwdTanECuUBMQZ/ym5kiw3XKCGA7qkuQLcjWWHcrD/GKbn/WmJwaezfuuAOcyKlRPA=="],
"@ohif/extension-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": ["@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-6BpaYGDavZqkI6yT+KSPdpZFfpnd68UKXbcjI9pJ13pvHhPrCKWOOLp+ysvMeA+DxnhuPpgIaRpxRxo5A9t5jw=="],
"@ohif/extension-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-syntax-import-assertions": ["@babel/plugin-syntax-import-assertions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg=="],
"@ohif/extension-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-syntax-import-attributes": ["@babel/plugin-syntax-import-attributes@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww=="],
"@ohif/extension-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-async-generator-functions": ["@babel/plugin-transform-async-generator-functions@7.28.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-remap-async-to-generator": "^7.27.1", "@babel/traverse": "^7.28.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q=="],
"@ohif/extension-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-async-to-generator": ["@babel/plugin-transform-async-to-generator@7.27.1", "", { "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-remap-async-to-generator": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA=="],
"@ohif/extension-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-block-scoping": ["@babel/plugin-transform-block-scoping@7.28.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-gKKnwjpdx5sER/wl0WN0efUBFzF/56YZO0RJrSYP4CljXnP31ByY7fol89AzomdlLNzI36AvOTmYHsnZTCkq8Q=="],
"@ohif/extension-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-class-static-block": ["@babel/plugin-transform-class-static-block@7.27.1", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.12.0" } }, "sha512-s734HmYU78MVzZ++joYM+NkJusItbdRcbm+AGRgJCt3iA+yux0QpD9cBVdz3tKyrjVYWRl7j0mHSmv4lhV0aoA=="],
"@ohif/extension-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-classes": ["@babel/plugin-transform-classes@7.28.0", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-globals": "^7.28.0", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/traverse": "^7.28.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-IjM1IoJNw72AZFlj33Cu8X0q2XK/6AaVC3jQu+cgQ5lThWD5ajnuUAml80dqRmOhmPkTH8uAwnpMu9Rvj0LTRA=="],
"@ohif/extension-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-computed-properties": ["@babel/plugin-transform-computed-properties@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/template": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw=="],
"@ohif/extension-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-dotall-regex": ["@babel/plugin-transform-dotall-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw=="],
"@ohif/extension-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex": ["@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ=="],
"@ohif/extension-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-explicit-resource-management": ["@babel/plugin-transform-explicit-resource-management@7.28.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/plugin-transform-destructuring": "^7.28.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ=="],
"@ohif/extension-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-exponentiation-operator": ["@babel/plugin-transform-exponentiation-operator@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-uspvXnhHvGKf2r4VVtBpeFnuDWsJLQ6MF6lGJLC89jBR1uoVeqM416AZtTuhTezOfgHicpJQmoD5YUakO/YmXQ=="],
"@ohif/extension-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-json-strings": ["@babel/plugin-transform-json-strings@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q=="],
"@ohif/extension-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-logical-assignment-operators": ["@babel/plugin-transform-logical-assignment-operators@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-SJvDs5dXxiae4FbSL1aBJlG4wvl594N6YEVVn9e3JGulwioy6z3oPjx/sQBO3Y4NwUu5HNix6KJ3wBZoewcdbw=="],
"@ohif/extension-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw=="],
"@ohif/extension-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex": ["@babel/plugin-transform-named-capturing-groups-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng=="],
"@ohif/extension-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-nullish-coalescing-operator": ["@babel/plugin-transform-nullish-coalescing-operator@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA=="],
"@ohif/extension-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-numeric-separator": ["@babel/plugin-transform-numeric-separator@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw=="],
"@ohif/extension-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-optional-catch-binding": ["@babel/plugin-transform-optional-catch-binding@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q=="],
"@ohif/extension-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-optional-chaining": ["@babel/plugin-transform-optional-chaining@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg=="],
"@ohif/extension-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-regexp-modifiers": ["@babel/plugin-transform-regexp-modifiers@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA=="],
"@ohif/extension-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-spread": ["@babel/plugin-transform-spread@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q=="],
"@ohif/extension-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-unicode-property-regex": ["@babel/plugin-transform-unicode-property-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q=="],
"@ohif/extension-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex": ["@babel/plugin-transform-unicode-sets-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw=="],
"@ohif/extension-ultrasound-pleura-bline/@babel/preset-env/core-js-compat": ["core-js-compat@3.44.0", "", { "dependencies": { "browserslist": "^4.25.1" } }, "sha512-JepmAj2zfl6ogy34qfWtcE7nHKAJnKsQFRn++scjVS2bZFllwptzw61BZcZFYBPpUznLfAvh0LGhxKppk04ClA=="],
"@ohif/extension-ultrasound-pleura-bline/@babel/preset-env/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
"@ohif/mode-segmentation/@babel/preset-env/@babel/compat-data": ["@babel/compat-data@7.28.0", "", {}, "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw=="],
"@ohif/mode-segmentation/@babel/preset-env/@babel/plugin-bugfix-firefox-class-in-computed-class-key": ["@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-QPG3C9cCVRQLxAVwmefEmwdTanECuUBMQZ/ym5kiw3XKCGA7qkuQLcjWWHcrD/GKbn/WmJwaezfuuAOcyKlRPA=="],
"@ohif/mode-segmentation/@babel/preset-env/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": ["@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-6BpaYGDavZqkI6yT+KSPdpZFfpnd68UKXbcjI9pJ13pvHhPrCKWOOLp+ysvMeA+DxnhuPpgIaRpxRxo5A9t5jw=="],
"@ohif/mode-segmentation/@babel/preset-env/@babel/plugin-syntax-import-assertions": ["@babel/plugin-syntax-import-assertions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg=="],
"@ohif/mode-segmentation/@babel/preset-env/@babel/plugin-syntax-import-attributes": ["@babel/plugin-syntax-import-attributes@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww=="],
"@ohif/mode-segmentation/@babel/preset-env/@babel/plugin-transform-async-generator-functions": ["@babel/plugin-transform-async-generator-functions@7.28.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-remap-async-to-generator": "^7.27.1", "@babel/traverse": "^7.28.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q=="],
"@ohif/mode-segmentation/@babel/preset-env/@babel/plugin-transform-async-to-generator": ["@babel/plugin-transform-async-to-generator@7.27.1", "", { "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-remap-async-to-generator": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA=="],
"@ohif/mode-segmentation/@babel/preset-env/@babel/plugin-transform-block-scoping": ["@babel/plugin-transform-block-scoping@7.28.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-gKKnwjpdx5sER/wl0WN0efUBFzF/56YZO0RJrSYP4CljXnP31ByY7fol89AzomdlLNzI36AvOTmYHsnZTCkq8Q=="],
"@ohif/mode-segmentation/@babel/preset-env/@babel/plugin-transform-class-static-block": ["@babel/plugin-transform-class-static-block@7.27.1", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.12.0" } }, "sha512-s734HmYU78MVzZ++joYM+NkJusItbdRcbm+AGRgJCt3iA+yux0QpD9cBVdz3tKyrjVYWRl7j0mHSmv4lhV0aoA=="],
"@ohif/mode-segmentation/@babel/preset-env/@babel/plugin-transform-classes": ["@babel/plugin-transform-classes@7.28.0", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-globals": "^7.28.0", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/traverse": "^7.28.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-IjM1IoJNw72AZFlj33Cu8X0q2XK/6AaVC3jQu+cgQ5lThWD5ajnuUAml80dqRmOhmPkTH8uAwnpMu9Rvj0LTRA=="],
"@ohif/mode-segmentation/@babel/preset-env/@babel/plugin-transform-computed-properties": ["@babel/plugin-transform-computed-properties@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/template": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw=="],
"@ohif/mode-segmentation/@babel/preset-env/@babel/plugin-transform-dotall-regex": ["@babel/plugin-transform-dotall-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw=="],
"@ohif/mode-segmentation/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex": ["@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ=="],
"@ohif/mode-segmentation/@babel/preset-env/@babel/plugin-transform-explicit-resource-management": ["@babel/plugin-transform-explicit-resource-management@7.28.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/plugin-transform-destructuring": "^7.28.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ=="],
"@ohif/mode-segmentation/@babel/preset-env/@babel/plugin-transform-exponentiation-operator": ["@babel/plugin-transform-exponentiation-operator@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-uspvXnhHvGKf2r4VVtBpeFnuDWsJLQ6MF6lGJLC89jBR1uoVeqM416AZtTuhTezOfgHicpJQmoD5YUakO/YmXQ=="],
"@ohif/mode-segmentation/@babel/preset-env/@babel/plugin-transform-json-strings": ["@babel/plugin-transform-json-strings@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q=="],
"@ohif/mode-segmentation/@babel/preset-env/@babel/plugin-transform-logical-assignment-operators": ["@babel/plugin-transform-logical-assignment-operators@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-SJvDs5dXxiae4FbSL1aBJlG4wvl594N6YEVVn9e3JGulwioy6z3oPjx/sQBO3Y4NwUu5HNix6KJ3wBZoewcdbw=="],
"@ohif/mode-segmentation/@babel/preset-env/@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw=="],
"@ohif/mode-segmentation/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex": ["@babel/plugin-transform-named-capturing-groups-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng=="],
"@ohif/mode-segmentation/@babel/preset-env/@babel/plugin-transform-nullish-coalescing-operator": ["@babel/plugin-transform-nullish-coalescing-operator@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA=="],
"@ohif/mode-segmentation/@babel/preset-env/@babel/plugin-transform-numeric-separator": ["@babel/plugin-transform-numeric-separator@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw=="],
"@ohif/mode-segmentation/@babel/preset-env/@babel/plugin-transform-optional-catch-binding": ["@babel/plugin-transform-optional-catch-binding@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q=="],
"@ohif/mode-segmentation/@babel/preset-env/@babel/plugin-transform-optional-chaining": ["@babel/plugin-transform-optional-chaining@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg=="],
"@ohif/mode-segmentation/@babel/preset-env/@babel/plugin-transform-regexp-modifiers": ["@babel/plugin-transform-regexp-modifiers@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA=="],
"@ohif/mode-segmentation/@babel/preset-env/@babel/plugin-transform-spread": ["@babel/plugin-transform-spread@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q=="],
"@ohif/mode-segmentation/@babel/preset-env/@babel/plugin-transform-unicode-property-regex": ["@babel/plugin-transform-unicode-property-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q=="],
"@ohif/mode-segmentation/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex": ["@babel/plugin-transform-unicode-sets-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw=="],
"@ohif/mode-segmentation/@babel/preset-env/core-js-compat": ["core-js-compat@3.44.0", "", { "dependencies": { "browserslist": "^4.25.1" } }, "sha512-JepmAj2zfl6ogy34qfWtcE7nHKAJnKsQFRn++scjVS2bZFllwptzw61BZcZFYBPpUznLfAvh0LGhxKppk04ClA=="],
"@ohif/mode-segmentation/@babel/preset-env/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
"@ohif/mode-ultrasound-pleura-bline/@babel/preset-env/@babel/compat-data": ["@babel/compat-data@7.28.0", "", {}, "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw=="],
"@ohif/mode-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-bugfix-firefox-class-in-computed-class-key": ["@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-QPG3C9cCVRQLxAVwmefEmwdTanECuUBMQZ/ym5kiw3XKCGA7qkuQLcjWWHcrD/GKbn/WmJwaezfuuAOcyKlRPA=="],
"@ohif/mode-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": ["@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-6BpaYGDavZqkI6yT+KSPdpZFfpnd68UKXbcjI9pJ13pvHhPrCKWOOLp+ysvMeA+DxnhuPpgIaRpxRxo5A9t5jw=="],
"@ohif/mode-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-syntax-import-assertions": ["@babel/plugin-syntax-import-assertions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg=="],
"@ohif/mode-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-syntax-import-attributes": ["@babel/plugin-syntax-import-attributes@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww=="],
"@ohif/mode-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-async-generator-functions": ["@babel/plugin-transform-async-generator-functions@7.28.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-remap-async-to-generator": "^7.27.1", "@babel/traverse": "^7.28.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q=="],
"@ohif/mode-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-async-to-generator": ["@babel/plugin-transform-async-to-generator@7.27.1", "", { "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-remap-async-to-generator": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA=="],
"@ohif/mode-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-block-scoping": ["@babel/plugin-transform-block-scoping@7.28.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-gKKnwjpdx5sER/wl0WN0efUBFzF/56YZO0RJrSYP4CljXnP31ByY7fol89AzomdlLNzI36AvOTmYHsnZTCkq8Q=="],
"@ohif/mode-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-class-static-block": ["@babel/plugin-transform-class-static-block@7.27.1", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.12.0" } }, "sha512-s734HmYU78MVzZ++joYM+NkJusItbdRcbm+AGRgJCt3iA+yux0QpD9cBVdz3tKyrjVYWRl7j0mHSmv4lhV0aoA=="],
"@ohif/mode-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-classes": ["@babel/plugin-transform-classes@7.28.0", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-globals": "^7.28.0", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/traverse": "^7.28.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-IjM1IoJNw72AZFlj33Cu8X0q2XK/6AaVC3jQu+cgQ5lThWD5ajnuUAml80dqRmOhmPkTH8uAwnpMu9Rvj0LTRA=="],
"@ohif/mode-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-computed-properties": ["@babel/plugin-transform-computed-properties@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/template": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw=="],
"@ohif/mode-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-dotall-regex": ["@babel/plugin-transform-dotall-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw=="],
"@ohif/mode-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex": ["@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ=="],
"@ohif/mode-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-explicit-resource-management": ["@babel/plugin-transform-explicit-resource-management@7.28.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/plugin-transform-destructuring": "^7.28.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ=="],
"@ohif/mode-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-exponentiation-operator": ["@babel/plugin-transform-exponentiation-operator@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-uspvXnhHvGKf2r4VVtBpeFnuDWsJLQ6MF6lGJLC89jBR1uoVeqM416AZtTuhTezOfgHicpJQmoD5YUakO/YmXQ=="],
"@ohif/mode-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-json-strings": ["@babel/plugin-transform-json-strings@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q=="],
"@ohif/mode-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-logical-assignment-operators": ["@babel/plugin-transform-logical-assignment-operators@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-SJvDs5dXxiae4FbSL1aBJlG4wvl594N6YEVVn9e3JGulwioy6z3oPjx/sQBO3Y4NwUu5HNix6KJ3wBZoewcdbw=="],
"@ohif/mode-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw=="],
"@ohif/mode-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex": ["@babel/plugin-transform-named-capturing-groups-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng=="],
"@ohif/mode-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-nullish-coalescing-operator": ["@babel/plugin-transform-nullish-coalescing-operator@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA=="],
"@ohif/mode-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-numeric-separator": ["@babel/plugin-transform-numeric-separator@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw=="],
"@ohif/mode-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-optional-catch-binding": ["@babel/plugin-transform-optional-catch-binding@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q=="],
"@ohif/mode-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-optional-chaining": ["@babel/plugin-transform-optional-chaining@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg=="],
"@ohif/mode-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-regexp-modifiers": ["@babel/plugin-transform-regexp-modifiers@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA=="],
"@ohif/mode-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-spread": ["@babel/plugin-transform-spread@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q=="],
"@ohif/mode-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-unicode-property-regex": ["@babel/plugin-transform-unicode-property-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q=="],
"@ohif/mode-ultrasound-pleura-bline/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex": ["@babel/plugin-transform-unicode-sets-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw=="],
"@ohif/mode-ultrasound-pleura-bline/@babel/preset-env/core-js-compat": ["core-js-compat@3.44.0", "", { "dependencies": { "browserslist": "^4.25.1" } }, "sha512-JepmAj2zfl6ogy34qfWtcE7nHKAJnKsQFRn++scjVS2bZFllwptzw61BZcZFYBPpUznLfAvh0LGhxKppk04ClA=="],
"@ohif/mode-ultrasound-pleura-bline/@babel/preset-env/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
"@rspack/binding-wasm32-wasi/@napi-rs/wasm-runtime/@tybys/wasm-util": ["@tybys/wasm-util@0.10.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ=="], "@rspack/binding-wasm32-wasi/@napi-rs/wasm-runtime/@tybys/wasm-util": ["@tybys/wasm-util@0.10.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ=="],
"@sigstore/sign/make-fetch-happen/minipass-fetch": ["minipass-fetch@5.0.1", "", { "dependencies": { "minipass": "^7.0.3", "minipass-sized": "^2.0.0", "minizlib": "^3.0.1" }, "optionalDependencies": { "encoding": "^0.1.13" } }, "sha512-yHK8pb0iCGat0lDrs/D6RZmCdaBT64tULXjdxjSMAqoDi18Q3qKEUTHypHQZQd9+FYpIS+lkvpq6C/R6SbUeRw=="], "@sigstore/sign/make-fetch-happen/minipass-fetch": ["minipass-fetch@5.0.1", "", { "dependencies": { "minipass": "^7.0.3", "minipass-sized": "^2.0.0", "minizlib": "^3.0.1" }, "optionalDependencies": { "encoding": "^0.1.13" } }, "sha512-yHK8pb0iCGat0lDrs/D6RZmCdaBT64tULXjdxjSMAqoDi18Q3qKEUTHypHQZQd9+FYpIS+lkvpq6C/R6SbUeRw=="],

View File

@ -46,8 +46,8 @@
}, },
"dependencies": { "dependencies": {
"@babel/runtime": "7.28.2", "@babel/runtime": "7.28.2",
"@cornerstonejs/adapters": "4.22.3", "@cornerstonejs/adapters": "4.22.8",
"@cornerstonejs/core": "4.22.3", "@cornerstonejs/core": "4.22.8",
"@kitware/vtk.js": "34.15.1" "@kitware/vtk.js": "34.15.1"
} }
} }

View File

@ -46,8 +46,8 @@
}, },
"dependencies": { "dependencies": {
"@babel/runtime": "7.28.2", "@babel/runtime": "7.28.2",
"@cornerstonejs/adapters": "4.22.3", "@cornerstonejs/adapters": "4.22.8",
"@cornerstonejs/core": "4.22.3", "@cornerstonejs/core": "4.22.8",
"@kitware/vtk.js": "34.15.1" "@kitware/vtk.js": "34.15.1"
} }
} }

View File

@ -46,9 +46,9 @@
}, },
"dependencies": { "dependencies": {
"@babel/runtime": "7.28.2", "@babel/runtime": "7.28.2",
"@cornerstonejs/adapters": "4.22.3", "@cornerstonejs/adapters": "4.22.8",
"@cornerstonejs/core": "4.22.3", "@cornerstonejs/core": "4.22.8",
"@cornerstonejs/tools": "4.22.3", "@cornerstonejs/tools": "4.22.8",
"classnames": "2.5.1" "classnames": "2.5.1"
} }
} }

View File

@ -42,8 +42,8 @@
}, },
"dependencies": { "dependencies": {
"@babel/runtime": "7.28.2", "@babel/runtime": "7.28.2",
"@cornerstonejs/core": "4.22.3", "@cornerstonejs/core": "4.22.8",
"@cornerstonejs/tools": "4.22.3", "@cornerstonejs/tools": "4.22.8",
"classnames": "2.5.1" "classnames": "2.5.1"
} }
} }

View File

@ -40,7 +40,7 @@
"@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2", "@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2",
"@cornerstonejs/codec-openjpeg": "1.3.0", "@cornerstonejs/codec-openjpeg": "1.3.0",
"@cornerstonejs/codec-openjph": "2.4.7", "@cornerstonejs/codec-openjph": "2.4.7",
"@cornerstonejs/dicom-image-loader": "4.22.3", "@cornerstonejs/dicom-image-loader": "4.22.8",
"@ohif/core": "3.13.0-beta.74", "@ohif/core": "3.13.0-beta.74",
"@ohif/ui": "3.13.0-beta.74", "@ohif/ui": "3.13.0-beta.74",
"dcmjs": "0.49.4", "dcmjs": "0.49.4",
@ -53,12 +53,12 @@
}, },
"dependencies": { "dependencies": {
"@babel/runtime": "7.28.2", "@babel/runtime": "7.28.2",
"@cornerstonejs/adapters": "4.22.3", "@cornerstonejs/adapters": "4.22.8",
"@cornerstonejs/ai": "4.22.3", "@cornerstonejs/ai": "4.22.8",
"@cornerstonejs/core": "4.22.3", "@cornerstonejs/core": "4.22.8",
"@cornerstonejs/labelmap-interpolation": "4.22.3", "@cornerstonejs/labelmap-interpolation": "4.22.8",
"@cornerstonejs/polymorphic-segmentation": "4.22.3", "@cornerstonejs/polymorphic-segmentation": "4.22.8",
"@cornerstonejs/tools": "4.22.3", "@cornerstonejs/tools": "4.22.8",
"@icr/polyseg-wasm": "0.4.0", "@icr/polyseg-wasm": "0.4.0",
"@itk-wasm/morphological-contour-interpolation": "1.1.0", "@itk-wasm/morphological-contour-interpolation": "1.1.0",
"@kitware/vtk.js": "34.15.1", "@kitware/vtk.js": "34.15.1",

View File

@ -32,8 +32,8 @@
"start": "yarn run dev" "start": "yarn run dev"
}, },
"peerDependencies": { "peerDependencies": {
"@cornerstonejs/core": "4.22.3", "@cornerstonejs/core": "4.22.8",
"@cornerstonejs/tools": "4.22.3", "@cornerstonejs/tools": "4.22.8",
"@ohif/core": "3.13.0-beta.74", "@ohif/core": "3.13.0-beta.74",
"@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.74", "@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.74",
"@ohif/extension-default": "3.13.0-beta.74", "@ohif/extension-default": "3.13.0-beta.74",

View File

@ -42,8 +42,8 @@
}, },
"dependencies": { "dependencies": {
"@babel/runtime": "7.28.2", "@babel/runtime": "7.28.2",
"@cornerstonejs/core": "4.22.3", "@cornerstonejs/core": "4.22.8",
"@cornerstonejs/tools": "4.22.3", "@cornerstonejs/tools": "4.22.8",
"@ohif/core": "3.13.0-beta.74", "@ohif/core": "3.13.0-beta.74",
"@ohif/extension-cornerstone": "3.13.0-beta.74", "@ohif/extension-cornerstone": "3.13.0-beta.74",
"@ohif/extension-default": "3.13.0-beta.74", "@ohif/extension-default": "3.13.0-beta.74",
@ -61,7 +61,7 @@
"@babel/plugin-transform-regenerator": "7.28.1", "@babel/plugin-transform-regenerator": "7.28.1",
"@babel/plugin-transform-runtime": "7.28.0", "@babel/plugin-transform-runtime": "7.28.0",
"@babel/plugin-transform-typescript": "7.28.0", "@babel/plugin-transform-typescript": "7.28.0",
"@babel/preset-env": "7.28.0", "@babel/preset-env": "7.29.5",
"@babel/preset-react": "7.27.1", "@babel/preset-react": "7.27.1",
"@babel/preset-typescript": "7.27.1", "@babel/preset-typescript": "7.27.1",
"@svgr/webpack": "8.1.0", "@svgr/webpack": "8.1.0",

View File

@ -59,7 +59,7 @@
"@babel/plugin-transform-regenerator": "7.28.1", "@babel/plugin-transform-regenerator": "7.28.1",
"@babel/plugin-transform-runtime": "7.28.0", "@babel/plugin-transform-runtime": "7.28.0",
"@babel/plugin-transform-typescript": "7.28.0", "@babel/plugin-transform-typescript": "7.28.0",
"@babel/preset-env": "7.28.0", "@babel/preset-env": "7.29.5",
"@babel/preset-react": "7.27.1", "@babel/preset-react": "7.27.1",
"@babel/preset-typescript": "7.27.1", "@babel/preset-typescript": "7.27.1",
"@svgr/webpack": "8.1.0", "@svgr/webpack": "8.1.0",

View File

@ -34,8 +34,8 @@
}, },
"dependencies": { "dependencies": {
"@babel/runtime": "7.28.2", "@babel/runtime": "7.28.2",
"@cornerstonejs/core": "4.22.3", "@cornerstonejs/core": "4.22.8",
"@cornerstonejs/tools": "4.22.3", "@cornerstonejs/tools": "4.22.8",
"@ohif/core": "3.13.0-beta.74", "@ohif/core": "3.13.0-beta.74",
"@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.74", "@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.74",
"@ohif/extension-ultrasound-pleura-bline": "3.13.0-beta.74", "@ohif/extension-ultrasound-pleura-bline": "3.13.0-beta.74",
@ -51,7 +51,7 @@
"@babel/plugin-transform-regenerator": "7.28.1", "@babel/plugin-transform-regenerator": "7.28.1",
"@babel/plugin-transform-runtime": "7.28.0", "@babel/plugin-transform-runtime": "7.28.0",
"@babel/plugin-transform-typescript": "7.28.0", "@babel/plugin-transform-typescript": "7.28.0",
"@babel/preset-env": "7.28.0", "@babel/preset-env": "7.29.5",
"@babel/preset-react": "7.27.1", "@babel/preset-react": "7.27.1",
"@babel/preset-typescript": "7.27.1", "@babel/preset-typescript": "7.27.1",
"@svgr/webpack": "8.1.0", "@svgr/webpack": "8.1.0",

View File

@ -54,7 +54,7 @@
"@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2", "@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2",
"@cornerstonejs/codec-openjpeg": "1.3.0", "@cornerstonejs/codec-openjpeg": "1.3.0",
"@cornerstonejs/codec-openjph": "2.4.7", "@cornerstonejs/codec-openjph": "2.4.7",
"@cornerstonejs/dicom-image-loader": "4.22.3", "@cornerstonejs/dicom-image-loader": "4.22.8",
"@emotion/serialize": "1.3.3", "@emotion/serialize": "1.3.3",
"@ohif/core": "3.13.0-beta.74", "@ohif/core": "3.13.0-beta.74",
"@ohif/extension-cornerstone": "3.13.0-beta.74", "@ohif/extension-cornerstone": "3.13.0-beta.74",

View File

@ -41,7 +41,7 @@
"@babel/plugin-transform-regenerator": "^7.16.7", "@babel/plugin-transform-regenerator": "^7.16.7",
"@babel/plugin-transform-runtime": "7.28.0", "@babel/plugin-transform-runtime": "7.28.0",
"@babel/plugin-transform-typescript": "^7.28.0", "@babel/plugin-transform-typescript": "^7.28.0",
"@babel/preset-env": "7.28.0", "@babel/preset-env": "7.29.5",
"@babel/preset-react": "^7.27.1", "@babel/preset-react": "^7.27.1",
"@babel/preset-typescript": "^7.27.1", "@babel/preset-typescript": "^7.27.1",
"@babel/plugin-transform-private-property-in-object": "^7.27.1", "@babel/plugin-transform-private-property-in-object": "^7.27.1",

View File

@ -32,7 +32,7 @@
"@babel/plugin-transform-regenerator": "^7.16.7", "@babel/plugin-transform-regenerator": "^7.16.7",
"@babel/plugin-transform-runtime": "7.28.0", "@babel/plugin-transform-runtime": "7.28.0",
"@babel/plugin-transform-typescript": "^7.28.0", "@babel/plugin-transform-typescript": "^7.28.0",
"@babel/preset-env": "7.28.0", "@babel/preset-env": "7.29.5",
"@babel/preset-react": "^7.27.1", "@babel/preset-react": "^7.27.1",
"@babel/preset-typescript": "^7.27.1", "@babel/preset-typescript": "^7.27.1",
"babel-loader": "^8.0.0-beta.4", "babel-loader": "^8.0.0-beta.4",

View File

@ -37,8 +37,8 @@
"@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2", "@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2",
"@cornerstonejs/codec-openjpeg": "1.3.0", "@cornerstonejs/codec-openjpeg": "1.3.0",
"@cornerstonejs/codec-openjph": "2.4.7", "@cornerstonejs/codec-openjph": "2.4.7",
"@cornerstonejs/core": "4.22.3", "@cornerstonejs/core": "4.22.8",
"@cornerstonejs/dicom-image-loader": "4.22.3", "@cornerstonejs/dicom-image-loader": "4.22.8",
"@ohif/ui": "3.13.0-beta.74", "@ohif/ui": "3.13.0-beta.74",
"cornerstone-math": "0.1.10", "cornerstone-math": "0.1.10",
"dicom-parser": "1.8.21" "dicom-parser": "1.8.21"

View File

@ -0,0 +1,80 @@
---
sidebar_position: 3
sidebar_label: Playwright Viewport Screenshots
title: Playwright viewport screenshot scope
---
# Playwright viewport screenshot scope
Playwright tests whose assertions concern the viewport (rendering, overlays,
measurements, segmentations, etc.) should scope `checkForScreenshot` to the
viewport itself — or, at most, the entire viewport grid. They should **not**
capture the surrounding OHIF UI (toolbar, side panels, study browser, header,
etc.).
## Why
Full-page screenshots that include the app chrome are fragile and noisy:
- Any unrelated UI tweak (toolbar layout, panel styling, icon changes,
measurement-panel rows, button states) regenerates the baseline and forces
unrelated screenshot churn across the test suite.
- Diffs become harder to read — a small viewport regression hides inside a
screenshot dominated by chrome.
- Tests that are nominally about viewport behavior end up gated on UI state
that has nothing to do with the feature under test.
Scoping the screenshot to the viewport (or viewport grid) keeps baselines
stable, makes failures meaningful, and aligns the screenshot with what the
test is actually asserting.
## Migration
Pass a viewport-scoped locator as the second argument to `checkForScreenshot`:
- **Single viewport** — use `activeViewport.pane` (from
`viewportPageObject.active`).
- **Whole viewport grid** (e.g. MPR, 3D-four-up, or any test concerned with
multi-viewport layout) — use `viewportPageObject.grid`.
Avoid passing `page` as the locator for viewport-focused tests — that captures
the full page including all of the OHIF chrome.
**Before — full-page screenshot includes chrome:**
```ts
await checkForScreenshot(
page,
page,
screenShotPaths.length.lengthDisplayedCorrectly
);
```
**After — single viewport:**
```ts
const activeViewport = await viewportPageObject.active;
// ... interact with the viewport ...
await checkForScreenshot(
page,
activeViewport.pane,
screenShotPaths.length.lengthDisplayedCorrectly
);
```
**After — viewport grid (multi-viewport layouts):**
```ts
await mainToolbarPageObject.layoutSelection.MPR.click();
await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.mpr.mprDisplayedCorrectly
);
```
If a test legitimately needs to assert on chrome (panel content, toolbar
state, measurement-row text), prefer a targeted locator for that element
rather than a full-page screenshot that incidentally includes the viewport.

View File

@ -182,6 +182,7 @@ const DataRowComponent = React.forwardRef<HTMLDivElement, DataRowProps>(
<div <div
key={`empty-${indent}`} key={`empty-${indent}`}
className="h-2" className="h-2"
data-cy="data-row-detail-line-empty"
></div> ></div>
); );
} }
@ -190,6 +191,7 @@ const DataRowComponent = React.forwardRef<HTMLDivElement, DataRowProps>(
<div <div
key={cleanText} key={cleanText}
className="whitespace-pre-wrap" className="whitespace-pre-wrap"
data-cy="data-row-detail-line"
> >
{indentation} {indentation}
<span className="font-medium">{cleanText}</span> <span className="font-medium">{cleanText}</span>
@ -197,14 +199,17 @@ const DataRowComponent = React.forwardRef<HTMLDivElement, DataRowProps>(
); );
}; };
const renderDetails = (details: string[]) => { const renderDetails = (details: string[], variant: 'primary' | 'secondary') => {
const visibleLines = details.slice(0, 4); const visibleLines = details.slice(0, 4);
const hiddenLines = details.slice(4); const hiddenLines = details.slice(4);
return ( return (
<Tooltip> <Tooltip>
<TooltipTrigger asChild> <TooltipTrigger asChild>
<div className="cursor-help"> <div
className="cursor-help"
data-cy={`data-row-details-${variant}`}
>
<div className="flex flex-col space-y-1"> <div className="flex flex-col space-y-1">
{visibleLines.map((line, lineIndex) => {visibleLines.map((line, lineIndex) =>
renderDetailText(line, line.startsWith(' ') ? 1 : 0) renderDetailText(line, line.startsWith(' ') ? 1 : 0)
@ -418,12 +423,15 @@ const DataRowComponent = React.forwardRef<HTMLDivElement, DataRowProps>(
{/* Details Section */} {/* Details Section */}
{details && (details.primary?.length > 0 || details.secondary?.length > 0) && ( {details && (details.primary?.length > 0 || details.secondary?.length > 0) && (
<div className="ml-7 px-2 py-2"> <div
className="ml-7 px-2 py-2"
data-cy="data-row-details"
>
<div className="text-secondary-foreground flex items-center gap-1 text-base leading-normal"> <div className="text-secondary-foreground flex items-center gap-1 text-base leading-normal">
{details.primary?.length > 0 && renderDetails(details.primary)} {details.primary?.length > 0 && renderDetails(details.primary, 'primary')}
{details.secondary?.length > 0 && ( {details.secondary?.length > 0 && (
<div className="text-muted-foreground ml-auto text-sm"> <div className="text-muted-foreground ml-auto text-sm">
{renderDetails(details.secondary)} {renderDetails(details.secondary, 'secondary')}
</div> </div>
)} )}
</div> </div>

View File

@ -107,26 +107,28 @@ const Row = ({ item, index }: RowProps) => {
const { uid } = item; const { uid } = item;
return ( return (
<DataRow <div data-cy={`measurement-table-row-${index}`}>
key={item.uid} <DataRow
description={item.label} key={item.uid}
number={index + 1} description={item.label}
title={item.label} number={index + 1}
colorHex={item.colorHex} title={item.label}
isSelected={item.isSelected} colorHex={item.colorHex}
details={item.displayText} isSelected={item.isSelected}
onDelete={e => onAction(e, 'removeMeasurement', uid)} details={item.displayText}
onSelect={e => onAction(e, 'jumpToMeasurement', uid)} onDelete={e => onAction(e, 'removeMeasurement', uid)}
onRename={e => onAction(e, 'renameMeasurement', uid)} onSelect={e => onAction(e, 'jumpToMeasurement', uid)}
onToggleVisibility={e => onAction(e, 'toggleVisibilityMeasurement', uid)} onRename={e => onAction(e, 'renameMeasurement', uid)}
onToggleLocked={e => onAction(e, 'toggleLockMeasurement', uid)} onToggleVisibility={e => onAction(e, 'toggleVisibilityMeasurement', uid)}
onColor={e => onAction(e, 'changeMeasurementColor', uid)} onToggleLocked={e => onAction(e, 'toggleLockMeasurement', uid)}
disableEditing={disableEditing} onColor={e => onAction(e, 'changeMeasurementColor', uid)}
isVisible={item.isVisible} disableEditing={disableEditing}
isLocked={item.isLocked} isVisible={item.isVisible}
> isLocked={item.isLocked}
{item.isUnmapped && <DataRow.Status.Warning tooltip={item.statusTooltip} />} >
</DataRow> {item.isUnmapped && <DataRow.Status.Warning tooltip={item.statusTooltip} />}
</DataRow>
</div>
); );
}; };

View File

@ -15,7 +15,11 @@ test.beforeEach(async ({ page }) => {
}); });
test.describe('3D four up Test', async () => { test.describe('3D four up Test', async () => {
test('should render 3D four up correctly.', async ({ page, mainToolbarPageObject }) => { test('should render 3D four up correctly.', async ({
page,
mainToolbarPageObject,
viewportPageObject,
}) => {
await mainToolbarPageObject.layoutSelection.threeDFourUp.click(); await mainToolbarPageObject.layoutSelection.threeDFourUp.click();
await attemptAction(() => reduce3DViewportSize(page), 10, 100); await attemptAction(() => reduce3DViewportSize(page), 10, 100);
@ -24,7 +28,7 @@ test.describe('3D four up Test', async () => {
await checkForScreenshot( await checkForScreenshot(
page, page,
page, viewportPageObject.grid,
screenShotPaths.threeDFourUp.threeDFourUpDisplayedCorrectly screenShotPaths.threeDFourUp.threeDFourUpDisplayedCorrectly
); );
}); });

View File

@ -15,10 +15,18 @@ test.beforeEach(async ({ page }) => {
}); });
test.describe('3D main Test', async () => { test.describe('3D main Test', async () => {
test('should render 3D main correctly.', async ({ page, mainToolbarPageObject }) => { test('should render 3D main correctly.', async ({
page,
mainToolbarPageObject,
viewportPageObject,
}) => {
await mainToolbarPageObject.layoutSelection.threeDMain.click(); await mainToolbarPageObject.layoutSelection.threeDMain.click();
await attemptAction(() => reduce3DViewportSize(page), 10, 100); await attemptAction(() => reduce3DViewportSize(page), 10, 100);
await waitForViewportsRendered(page); await waitForViewportsRendered(page);
await checkForScreenshot(page, page, screenShotPaths.threeDMain.threeDMainDisplayedCorrectly); await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.threeDMain.threeDMainDisplayedCorrectly
);
}); });
}); });

View File

@ -15,14 +15,18 @@ test.beforeEach(async ({ page }) => {
}); });
test.describe('3D only Test', async () => { test.describe('3D only Test', async () => {
test('should render 3D only correctly.', async ({ page, mainToolbarPageObject }) => { test('should render 3D only correctly.', async ({
page,
mainToolbarPageObject,
viewportPageObject,
}) => {
await mainToolbarPageObject.layoutSelection.threeDOnly.click(); await mainToolbarPageObject.layoutSelection.threeDOnly.click();
await attemptAction(() => reduce3DViewportSize(page), 10, 100); await attemptAction(() => reduce3DViewportSize(page), 10, 100);
await waitForViewportsRendered(page); await waitForViewportsRendered(page);
// Use a 4 percent diff pixel ratio to account for slight color differences in the 3D viewport // Use a 4 percent diff pixel ratio to account for slight color differences in the 3D viewport
await checkForScreenshot({ await checkForScreenshot({
page, page,
locator: page, locator: viewportPageObject.grid,
screenshotPath: screenShotPaths.threeDOnly.threeDOnlyDisplayedCorrectly, screenshotPath: screenShotPaths.threeDOnly.threeDOnlyDisplayedCorrectly,
maxDiffPixelRatio: 0.04, maxDiffPixelRatio: 0.04,
}); });

View File

@ -15,14 +15,18 @@ test.beforeEach(async ({ page }) => {
}); });
test.describe('3D primary Test', async () => { test.describe('3D primary Test', async () => {
test('should render 3D primary correctly.', async ({ page, mainToolbarPageObject }) => { test('should render 3D primary correctly.', async ({
page,
mainToolbarPageObject,
viewportPageObject,
}) => {
await mainToolbarPageObject.layoutSelection.threeDPrimary.click(); await mainToolbarPageObject.layoutSelection.threeDPrimary.click();
await attemptAction(() => reduce3DViewportSize(page), 10, 100); await attemptAction(() => reduce3DViewportSize(page), 10, 100);
await waitForViewportsRendered(page); await waitForViewportsRendered(page);
await checkForScreenshot( await checkForScreenshot(
page, page,
page, viewportPageObject.grid,
screenShotPaths.threeDPrimary.threeDPrimaryDisplayedCorrectly screenShotPaths.threeDPrimary.threeDPrimaryDisplayedCorrectly
); );
}); });

View File

@ -20,5 +20,10 @@ test('should display the angle tool', async ({
{ x: 550, y: 300 }, { x: 550, y: 300 },
]); ]);
await DOMOverlayPageObject.viewport.measurementTracking.confirm.click(); await DOMOverlayPageObject.viewport.measurementTracking.confirm.click();
await checkForScreenshot(page, page, screenShotPaths.angle.angleDisplayedCorrectly);
await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.angle.angleDisplayedCorrectly
);
}); });

View File

@ -7,11 +7,16 @@ test.beforeEach(async ({ page }) => {
}); });
test.describe('Axial Primary Test', async () => { test.describe('Axial Primary Test', async () => {
test('should render Axial Primary correctly.', async ({ page, mainToolbarPageObject }) => { test('should render Axial Primary correctly.', async ({
page,
mainToolbarPageObject,
viewportPageObject,
}) => {
await mainToolbarPageObject.layoutSelection.axialPrimary.click(); await mainToolbarPageObject.layoutSelection.axialPrimary.click();
await checkForScreenshot( await checkForScreenshot(
page, page,
page, viewportPageObject.grid,
screenShotPaths.axialPrimary.axialPrimaryDisplayedCorrectly screenShotPaths.axialPrimary.axialPrimaryDisplayedCorrectly
); );
}); });

View File

@ -19,9 +19,10 @@ test('should display the bidirectional tool', async ({
{ x: 515, y: 339 }, { x: 515, y: 339 },
]); ]);
await DOMOverlayPageObject.viewport.measurementTracking.confirm.click(); await DOMOverlayPageObject.viewport.measurementTracking.confirm.click();
await checkForScreenshot( await checkForScreenshot(
page, page,
page, viewportPageObject.grid,
screenShotPaths.bidirectional.bidirectionalDisplayedCorrectly screenShotPaths.bidirectional.bidirectionalDisplayedCorrectly
); );
}); });

View File

@ -19,5 +19,9 @@ test('should display the circle tool', async ({
{ x: 488, y: 247 }, { x: 488, y: 247 },
]); ]);
await DOMOverlayPageObject.viewport.measurementTracking.confirm.click(); await DOMOverlayPageObject.viewport.measurementTracking.confirm.click();
await checkForScreenshot(page, page, screenShotPaths.circle.circleDisplayedCorrectly); await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.circle.circleDisplayedCorrectly
);
}); });

View File

@ -21,5 +21,10 @@ test('should display the cobb angle tool', async ({
{ x: 625, y: 291 }, { x: 625, y: 291 },
]); ]);
await DOMOverlayPageObject.viewport.measurementTracking.confirm.click(); await DOMOverlayPageObject.viewport.measurementTracking.confirm.click();
await checkForScreenshot(page, page, screenShotPaths.cobbangle.cobbangleDisplayedCorrectly);
await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.cobbangle.cobbangleDisplayedCorrectly
);
}); });

View File

@ -21,13 +21,17 @@ test('should the context menu completely on screen and is not clipped for a poin
await DOMOverlayPageObject.viewport.measurementTracking.confirm.click(); await DOMOverlayPageObject.viewport.measurementTracking.confirm.click();
await checkForScreenshot(page, page, screenShotPaths.contextMenu.preContextMenuNearBottomEdge); await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.contextMenu.preContextMenuNearBottomEdge
);
await activeViewport.normalizedClickAt([{ x: 0.55, y: 0.98 }], 'right'); await activeViewport.normalizedClickAt([{ x: 0.55, y: 0.98 }], 'right');
await checkForScreenshot({ await checkForScreenshot({
page, page,
locator: page, locator: viewportPageObject.grid,
screenshotPath: screenShotPaths.contextMenu.contextMenuNearBottomEdgeNotClipped, screenshotPath: screenShotPaths.contextMenu.contextMenuNearBottomEdgeNotClipped,
}); });
}); });

View File

@ -19,5 +19,10 @@ test('should display the ellipse tool', async ({
{ x: 508, y: 281 }, { x: 508, y: 281 },
]); ]);
await DOMOverlayPageObject.viewport.measurementTracking.confirm.click(); await DOMOverlayPageObject.viewport.measurementTracking.confirm.click();
await checkForScreenshot(page, page, screenShotPaths.ellipse.ellipseDisplayedCorrectly);
await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.ellipse.ellipseDisplayedCorrectly
);
}); });

View File

@ -6,11 +6,16 @@ test.beforeEach(async ({ page }) => {
await visitStudy(page, studyInstanceUID, mode, 2000); await visitStudy(page, studyInstanceUID, mode, 2000);
}); });
test('should flip the image horizontally', async ({ page, mainToolbarPageObject }) => { test('should flip the image horizontally', async ({
page,
mainToolbarPageObject,
viewportPageObject,
}) => {
await mainToolbarPageObject.moreTools.flipHorizontal.click(); await mainToolbarPageObject.moreTools.flipHorizontal.click();
await checkForScreenshot( await checkForScreenshot(
page, page,
page, viewportPageObject.grid,
screenShotPaths.flipHorizontal.flipHorizontalDisplayedCorrectly screenShotPaths.flipHorizontal.flipHorizontalDisplayedCorrectly
); );
}); });

View File

@ -1,4 +1,10 @@
import { expect, test, visitStudy, subscribeToMeasurementAdded } from './utils'; import {
expect,
getAnnotationStats,
subscribeToMeasurementAdded,
test,
visitStudy,
} from './utils';
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
const studyInstanceUID = '1.3.6.1.4.1.25403.345050719074.3824.20170125095438.5'; const studyInstanceUID = '1.3.6.1.4.1.25403.345050719074.3824.20170125095438.5';
@ -32,3 +38,70 @@ test('should not fire MEASUREMENT_ADDED when clicking the annotation text', asyn
await measurementAdded.unsubscribe(); await measurementAdded.unsubscribe();
} }
}); });
test('rectangle and freehand at identical coordinates should yield comparable area', async ({
page,
DOMOverlayPageObject,
mainToolbarPageObject,
rightPanelPageObject,
viewportPageObject,
}) => {
// Open measurements panel first — needed later for the delete action, and
// opening up-front means both shapes are drawn against the same viewport
// layout (so normalized coords don't shift between draws).
await rightPanelPageObject.toggle();
await rightPanelPageObject.measurementsPanel.select();
const activeViewport = await viewportPageObject.active;
// End on the left edge just shy of the start so cornerstone3D's proximity-
// close triggers via the standard mouseup path (which fires
// ANNOTATION_COMPLETED). Ending at the start point would enter interactive close-
// preview mode and suppress the completion event; ending further away
// would draw a diagonal that distorts the rectangular shape.
const corners = [
{ x: 0.3, y: 0.3 },
{ x: 0.55, y: 0.3 },
{ x: 0.55, y: 0.55 },
{ x: 0.3, y: 0.55 },
{ x: 0.3, y: 0.31 },
];
const [topLeft, , bottomRight] = corners;
await mainToolbarPageObject.measurementTools.rectangleROI.click();
await activeViewport.normalizedClickAt([topLeft, bottomRight]);
await DOMOverlayPageObject.viewport.measurementTracking.confirm.click();
const rectangles = await getAnnotationStats(page, { toolName: 'RectangleROI' });
const rectArea = rectangles[0].firstTargetStats!.area as number;
const rectRow = rightPanelPageObject.measurementsPanel.panel.nthMeasurement(0);
const rectSvgLines = activeViewport.getSvgAnnotationStatTextLines(rectangles[0].annotationUID);
await expect(rectSvgLines.nth(0)).toHaveText(`Area: ${Math.round(rectArea)} mm²`);
await expect(rectRow.stats.primary.lines.nth(0)).toHaveText(`${Math.round(rectArea)} mm²`);
// Remove the rectangle so the freehand can drag through the same coords
// without grabbing the rectangle's handles.
await rectRow.actions.delete();
await mainToolbarPageObject.measurementTools.freehandROI.click();
await activeViewport.normalizedPathDragAt({
path: corners,
config: { steps: 20, delay: 30 },
});
const freehands = await getAnnotationStats(page, { toolName: 'PlanarFreehandROI' });
const freehandArea = freehands[0].firstTargetStats!.area as number;
const freehandRow = rightPanelPageObject.measurementsPanel.panel.nthMeasurement(0);
const freehandSvgLines = activeViewport.getSvgAnnotationStatTextLines(freehands[0].annotationUID);
await expect(freehandSvgLines.nth(0)).toHaveText(`Area: ${Math.round(freehandArea)} mm²`);
await expect(freehandRow.stats.primary.lines.nth(0)).toHaveText(`${Math.round(freehandArea)} mm²`);
const pctDiff = (Math.abs(rectArea - freehandArea) / rectArea) * 100;
console.log(
`Rectangle: ${rectArea.toFixed(2)} mm² | ` +
`Freehand: ${freehandArea.toFixed(2)} mm² | ` +
`diff: ${pctDiff.toFixed(2)}%`
);
expect(pctDiff).toBeLessThan(1);
});

View File

@ -12,8 +12,12 @@ test.beforeEach(async ({ page }) => {
await visitStudy(page, studyInstanceUID, mode, 2000); await visitStudy(page, studyInstanceUID, mode, 2000);
}); });
test('should invert the image', async ({ page, mainToolbarPageObject }) => { test('should invert the image', async ({ page, mainToolbarPageObject, viewportPageObject }) => {
await mainToolbarPageObject.moreTools.invert.click(); await mainToolbarPageObject.moreTools.invert.click();
await waitForViewportsRendered(page); await waitForViewportsRendered(page);
await checkForScreenshot(page, page, screenShotPaths.invert.invertDisplayedCorrectly); await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.invert.invertDisplayedCorrectly
);
}); });

View File

@ -54,7 +54,11 @@ test('should hydrate in MPR correctly', async ({
await DOMOverlayPageObject.viewport.measurementTracking.confirm.click(); await DOMOverlayPageObject.viewport.measurementTracking.confirm.click();
// scroll away // scroll away
await checkForScreenshot(page, page, screenShotPaths.jumpToMeasurementMPR.initialDraw); await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.jumpToMeasurementMPR.initialDraw
);
// Focus on the canvas first, then use mouse wheel to scroll away // Focus on the canvas first, then use mouse wheel to scroll away
await page.evaluate(() => { await page.evaluate(() => {
@ -78,11 +82,19 @@ test('should hydrate in MPR correctly', async ({
await page.waitForTimeout(5000); await page.waitForTimeout(5000);
await checkForScreenshot(page, page, screenShotPaths.jumpToMeasurementMPR.scrollAway); await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.jumpToMeasurementMPR.scrollAway
);
await rightPanelPageObject.measurementsPanel.panel.nthMeasurement(0).click(); await rightPanelPageObject.measurementsPanel.panel.nthMeasurement(0).click();
await checkForScreenshot(page, page, screenShotPaths.jumpToMeasurementMPR.jumpToMeasurementStack); await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.jumpToMeasurementMPR.jumpToMeasurementStack
);
await mainToolbarPageObject.layoutSelection.MPR.click(); await mainToolbarPageObject.layoutSelection.MPR.click();
@ -93,19 +105,27 @@ test('should hydrate in MPR correctly', async ({
await page.waitForTimeout(3000); await page.waitForTimeout(3000);
await checkForScreenshot(page, page, screenShotPaths.jumpToMeasurementMPR.jumpInMPR); await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.jumpToMeasurementMPR.jumpInMPR
);
await leftPanelPageObject.loadSeriesByDescription('Lung 3.0 CE'); await leftPanelPageObject.loadSeriesByDescription('Lung 3.0 CE');
await page.waitForTimeout(5000); await page.waitForTimeout(5000);
await checkForScreenshot(page, page, screenShotPaths.jumpToMeasurementMPR.changeSeriesInMPR); await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.jumpToMeasurementMPR.changeSeriesInMPR
);
await rightPanelPageObject.measurementsPanel.panel.nthMeasurement(0).click(); await rightPanelPageObject.measurementsPanel.panel.nthMeasurement(0).click();
await checkForScreenshot( await checkForScreenshot(
page, page,
page, viewportPageObject.grid,
screenShotPaths.jumpToMeasurementMPR.jumpToMeasurementAfterSeriesChange screenShotPaths.jumpToMeasurementMPR.jumpToMeasurementAfterSeriesChange
); );
}); });

View File

@ -38,7 +38,11 @@ test('should prevent editing of label map segmentations when panelSegmentation.d
// navigate to the 12th image and ensure the correct overlay is displayed // navigate to the 12th image and ensure the correct overlay is displayed
await press({ page, key: 'ArrowDown', nTimes: 11 }); await press({ page, key: 'ArrowDown', nTimes: 11 });
await checkForScreenshot(page, page, screenShotPaths.labelMapSegLocking.globalLockedSegPreEdit); await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.labelMapSegLocking.globalLockedSegPreEdit
);
// Attempt to erase the segmentations. // Attempt to erase the segmentations.
await rightPanelPageObject.labelMapSegmentationPanel.tools.eraser.click(); await rightPanelPageObject.labelMapSegmentationPanel.tools.eraser.click();
@ -61,7 +65,11 @@ test('should prevent editing of label map segmentations when panelSegmentation.d
end: { x: 1.0, y: 0.75 }, end: { x: 1.0, y: 0.75 },
}); });
await checkForScreenshot(page, page, screenShotPaths.labelMapSegLocking.globalLockedSegPostEdit); await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.labelMapSegLocking.globalLockedSegPostEdit
);
}); });
test('should allow editing of label map segmentations when panelSegmentation.disableEditing is false', async ({ test('should allow editing of label map segmentations when panelSegmentation.disableEditing is false', async ({
@ -89,7 +97,11 @@ test('should allow editing of label map segmentations when panelSegmentation.dis
// navigate to the 12th image and ensure the correct overlay is displayed // navigate to the 12th image and ensure the correct overlay is displayed
await press({ page, key: 'ArrowDown', nTimes: 11 }); await press({ page, key: 'ArrowDown', nTimes: 11 });
await checkForScreenshot(page, page, screenShotPaths.labelMapSegLocking.globalUnlockedSegPreEdit); await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.labelMapSegLocking.globalUnlockedSegPreEdit
);
// Attempt to erase the segmentations. // Attempt to erase the segmentations.
await rightPanelPageObject.labelMapSegmentationPanel.tools.eraser.click(); await rightPanelPageObject.labelMapSegmentationPanel.tools.eraser.click();
@ -114,7 +126,7 @@ test('should allow editing of label map segmentations when panelSegmentation.dis
await checkForScreenshot( await checkForScreenshot(
page, page,
page, viewportPageObject.grid,
screenShotPaths.labelMapSegLocking.globalUnlockedSegPostEdit screenShotPaths.labelMapSegLocking.globalUnlockedSegPostEdit
); );
}); });

View File

@ -19,5 +19,10 @@ test('should display the length tool', async ({
{ x: 544, y: 232 }, { x: 544, y: 232 },
]); ]);
await DOMOverlayPageObject.viewport.measurementTracking.confirm.click(); await DOMOverlayPageObject.viewport.measurementTracking.confirm.click();
await checkForScreenshot(page, page, screenShotPaths.length.lengthDisplayedCorrectly);
await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.length.lengthDisplayedCorrectly
);
}); });

View File

@ -1,4 +1,11 @@
import { checkForScreenshot, screenShotPaths, test, visitStudy, expect } from './utils'; import {
checkForScreenshot,
expect,
getAnnotationStats,
screenShotPaths,
test,
visitStudy,
} from './utils';
import { press } from './utils/keyboardUtils'; import { press } from './utils/keyboardUtils';
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
@ -24,7 +31,23 @@ test('should display the livewire tool', async ({
{ x: 383, y: 461 }, { x: 383, y: 461 },
]); ]);
await DOMOverlayPageObject.viewport.measurementTracking.confirm.click(); await DOMOverlayPageObject.viewport.measurementTracking.confirm.click();
await checkForScreenshot(page, page, screenShotPaths.livewire.livewireDisplayedCorrectly);
await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.livewire.livewireDisplayedCorrectly
);
const livewires = await getAnnotationStats(page, { toolName: 'LivewireContour' });
expect(livewires.length).toBeGreaterThan(0);
const stats = livewires[0].firstTargetStats!;
expect(stats.areaUnit).toBe('mm²');
expect(Math.round(stats.area as number)).toBe(28906);
const lines = activeViewport.getSvgAnnotationStatTextLines(livewires[0].annotationUID);
await expect(lines).toHaveCount(1);
await expect(lines.nth(0)).toHaveText('Area: 28906 mm²');
}); });
test('should restore viewport interactivity after deleting an in-progress Livewire annotation via context menu', async ({ test('should restore viewport interactivity after deleting an in-progress Livewire annotation via context menu', async ({

View File

@ -7,8 +7,17 @@ test.beforeEach(async ({ page }) => {
}); });
test.describe('MPR Test', async () => { test.describe('MPR Test', async () => {
test('should render MPR correctly.', async ({ page, mainToolbarPageObject }) => { test('should render MPR correctly.', async ({
page,
mainToolbarPageObject,
viewportPageObject,
}) => {
await mainToolbarPageObject.layoutSelection.MPR.click(); await mainToolbarPageObject.layoutSelection.MPR.click();
await checkForScreenshot(page, page, screenShotPaths.mpr.mprDisplayedCorrectly);
await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.mpr.mprDisplayedCorrectly
);
}); });
}); });

View File

@ -25,7 +25,7 @@ test('should launch MPR with unhydrated RTSTRUCT chosen from the data overlay me
await checkForScreenshot( await checkForScreenshot(
page, page,
page, viewportPageObject.grid,
screenShotPaths.mprThenRTOverlayNoHydration.mprPreRTOverlayNoHydration screenShotPaths.mprThenRTOverlayNoHydration.mprPreRTOverlayNoHydration
); );
@ -48,6 +48,7 @@ test('should launch MPR with unhydrated RTSTRUCT chosen from the data overlay me
await checkForScreenshot({ await checkForScreenshot({
page, page,
locator: viewportPageObject.grid,
screenshotPath: screenShotPaths.mprThenRTOverlayNoHydration.mprPostRTOverlayNoHydration, screenshotPath: screenShotPaths.mprThenRTOverlayNoHydration.mprPostRTOverlayNoHydration,
normalizedClip: { x: 0, y: 0, width: 1.0, height: 0.75 }, // clip to avoid any popups concerning surface creation and clipping normalizedClip: { x: 0, y: 0, width: 1.0, height: 0.75 }, // clip to avoid any popups concerning surface creation and clipping
}); });

View File

@ -21,7 +21,7 @@ test('should launch MPR with unhydrated SEG chosen from the data overlay menu',
await checkForScreenshot( await checkForScreenshot(
page, page,
page, viewportPageObject.grid,
screenShotPaths.mprThenSEGOverlayNoHydration.mprPreSEGOverlayNoHydration screenShotPaths.mprThenSEGOverlayNoHydration.mprPreSEGOverlayNoHydration
); );
@ -42,7 +42,7 @@ test('should launch MPR with unhydrated SEG chosen from the data overlay menu',
await checkForScreenshot( await checkForScreenshot(
page, page,
page, viewportPageObject.grid,
screenShotPaths.mprThenSEGOverlayNoHydration.mprPostSEGOverlayNoHydration screenShotPaths.mprThenSEGOverlayNoHydration.mprPostSEGOverlayNoHydration
); );
}); });

View File

@ -69,15 +69,15 @@ test('checks if measurement item can be relabeled under Measurements panel', asy
// Open measurement panel confirm default empty // Open measurement panel confirm default empty
await rightPanelPageObject.measurementsPanel.select(); await rightPanelPageObject.measurementsPanel.select();
const measurementRow = rightPanelPageObject.measurementsPanel.panel.nthMeasurement(0).locator; const measurementRow = rightPanelPageObject.measurementsPanel.panel.nthMeasurement(0);
await expect(measurementRow).toContainText('(empty)'); await expect(measurementRow.title).toHaveText('(empty)');
// Expand and click rename // Expand and click rename
await rightPanelPageObject.measurementsPanel.panel.nthMeasurement(0).actions.rename(relabelText); await rightPanelPageObject.measurementsPanel.panel.nthMeasurement(0).actions.rename(relabelText);
// Check dialog closed and renamed // Check dialog closed and renamed
await expect(DOMOverlayPageObject.dialog.input.locator).toBeHidden(); await expect(DOMOverlayPageObject.dialog.input.locator).toBeHidden();
await expect(measurementRow).toContainText(relabelText); await expect(measurementRow.title).toHaveText(relabelText);
}); });
test('checks if measurement item can be relabeled through the context menu on the viewport', async ({ test('checks if measurement item can be relabeled through the context menu on the viewport', async ({
@ -98,8 +98,8 @@ test('checks if measurement item can be relabeled through the context menu on th
// Open measurement panel confirm default empty // Open measurement panel confirm default empty
await rightPanelPageObject.measurementsPanel.select(); await rightPanelPageObject.measurementsPanel.select();
const measurementRow = rightPanelPageObject.measurementsPanel.panel.nthMeasurement(0).locator; const measurementRow = rightPanelPageObject.measurementsPanel.panel.nthMeasurement(0);
await expect(measurementRow).toContainText('(empty)'); await expect(measurementRow.title).toHaveText('(empty)');
// Right click and click rename // Right click and click rename
await page.waitForTimeout(200); // small delay for context menu await page.waitForTimeout(200); // small delay for context menu
@ -117,7 +117,7 @@ test('checks if measurement item can be relabeled through the context menu on th
// Check dialog closed and renamed // Check dialog closed and renamed
await expect(DOMOverlayPageObject.dialog.title).toBeHidden(); await expect(DOMOverlayPageObject.dialog.title).toBeHidden();
await expect(measurementRow).toContainText(relabelText); await expect(measurementRow.title).toHaveText(relabelText);
}); });
test('checks if image would jump when clicked on a measurement item', async ({ test('checks if image would jump when clicked on a measurement item', async ({

View File

@ -49,6 +49,7 @@ test('should display multiple segmentation overlays (both SEG and RT)', async ({
await checkForScreenshot({ await checkForScreenshot({
page, page,
locator: viewportPageObject.grid,
screenshotPath: screenShotPaths.multipleSegmentationDataOverlays.threeSegOverlaysInOverlayMenu, screenshotPath: screenShotPaths.multipleSegmentationDataOverlays.threeSegOverlaysInOverlayMenu,
}); });
@ -58,6 +59,7 @@ test('should display multiple segmentation overlays (both SEG and RT)', async ({
await checkForScreenshot({ await checkForScreenshot({
page, page,
locator: viewportPageObject.grid,
screenshotPath: screenShotPaths.multipleSegmentationDataOverlays.threeSegOverlaysInOverlayMenu, screenshotPath: screenShotPaths.multipleSegmentationDataOverlays.threeSegOverlaysInOverlayMenu,
}); });
@ -70,6 +72,7 @@ test('should display multiple segmentation overlays (both SEG and RT)', async ({
await checkForScreenshot({ await checkForScreenshot({
page, page,
locator: viewportPageObject.grid,
screenshotPath: screenShotPaths.multipleSegmentationDataOverlays.overlaysDisplayed, screenshotPath: screenShotPaths.multipleSegmentationDataOverlays.overlaysDisplayed,
}); });
@ -85,6 +88,7 @@ test('should display multiple segmentation overlays (both SEG and RT)', async ({
await checkForScreenshot({ await checkForScreenshot({
page, page,
locator: viewportPageObject.grid,
screenshotPath: screenShotPaths.multipleSegmentationDataOverlays.overlaySEGsAndRTDisplayed, screenshotPath: screenShotPaths.multipleSegmentationDataOverlays.overlaySEGsAndRTDisplayed,
}); });
@ -94,6 +98,7 @@ test('should display multiple segmentation overlays (both SEG and RT)', async ({
await checkForScreenshot({ await checkForScreenshot({
page, page,
locator: viewportPageObject.grid,
screenshotPath: screenShotPaths.multipleSegmentationDataOverlays.overlaySEGsAndRTDisplayed, screenshotPath: screenShotPaths.multipleSegmentationDataOverlays.overlaySEGsAndRTDisplayed,
}); });
}); });

View File

@ -16,5 +16,10 @@ test('should display the probe tool', async ({
const activeViewport = await viewportPageObject.active; const activeViewport = await viewportPageObject.active;
await activeViewport.clickAt([{ x: 550, y: 200 }]); await activeViewport.clickAt([{ x: 550, y: 200 }]);
await DOMOverlayPageObject.viewport.measurementTracking.confirm.click(); await DOMOverlayPageObject.viewport.measurementTracking.confirm.click();
await checkForScreenshot(page, page, screenShotPaths.probe.probeDisplayedCorrectly);
await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.probe.probeDisplayedCorrectly
);
}); });

View File

@ -12,7 +12,8 @@ test('should overlay an unhydrated RTSTRUCT over a display set that the RTSTRUCT
page, page,
viewportPageObject, viewportPageObject,
}) => { }) => {
const dataOverlayPageObject = (await viewportPageObject.getById('default')).overlayMenu.dataOverlay; const dataOverlayPageObject = (await viewportPageObject.getById('default')).overlayMenu
.dataOverlay;
await dataOverlayPageObject.toggle(); await dataOverlayPageObject.toggle();
await dataOverlayPageObject.addSegmentation('Contours on PET'); await dataOverlayPageObject.addSegmentation('Contours on PET');
@ -26,7 +27,7 @@ test('should overlay an unhydrated RTSTRUCT over a display set that the RTSTRUCT
await checkForScreenshot( await checkForScreenshot(
page, page,
page, viewportPageObject.grid,
screenShotPaths.rtDataOverlayForUnreferencedDisplaySetNoHydration.overlayFirstImage screenShotPaths.rtDataOverlayForUnreferencedDisplaySetNoHydration.overlayFirstImage
); );
@ -37,7 +38,7 @@ test('should overlay an unhydrated RTSTRUCT over a display set that the RTSTRUCT
await checkForScreenshot( await checkForScreenshot(
page, page,
page, viewportPageObject.grid,
screenShotPaths.rtDataOverlayForUnreferencedDisplaySetNoHydration.overlayMiddleImage screenShotPaths.rtDataOverlayForUnreferencedDisplaySetNoHydration.overlayMiddleImage
); );
}); });

View File

@ -37,7 +37,7 @@ test('should launch MPR with unhydrated RTSTRUCT chosen from the data overlay me
await checkForScreenshot( await checkForScreenshot(
page, page,
page, viewportPageObject.grid,
screenShotPaths.rtDataOverlayNoHydrationThenMPR.rtDataOverlayNoHydrationPreMPR screenShotPaths.rtDataOverlayNoHydrationThenMPR.rtDataOverlayNoHydrationPreMPR
); );
@ -47,7 +47,7 @@ test('should launch MPR with unhydrated RTSTRUCT chosen from the data overlay me
await checkForScreenshot( await checkForScreenshot(
page, page,
page, viewportPageObject.grid,
screenShotPaths.rtDataOverlayNoHydrationThenMPR.rtDataOverlayNoHydrationPostMPR screenShotPaths.rtDataOverlayNoHydrationThenMPR.rtDataOverlayNoHydrationPostMPR
); );

View File

@ -11,17 +11,30 @@ test('should hydrate RT reports correctly', async ({
DOMOverlayPageObject, DOMOverlayPageObject,
leftPanelPageObject, leftPanelPageObject,
rightPanelPageObject, rightPanelPageObject,
viewportPageObject,
}) => { }) => {
await rightPanelPageObject.toggle(); await rightPanelPageObject.toggle();
await leftPanelPageObject.loadSeriesByModality('RTSTRUCT'); await leftPanelPageObject.loadSeriesByModality('RTSTRUCT');
await page.waitForTimeout(5000); await page.waitForTimeout(5000);
await checkForScreenshot(page, page, screenShotPaths.rtHydration.rtPreHydration); await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.rtHydration.rtPreHydration
);
await DOMOverlayPageObject.viewport.segmentationHydration.yes.click(); await DOMOverlayPageObject.viewport.segmentationHydration.yes.click();
await page.waitForTimeout(5000); await page.waitForTimeout(5000);
await checkForScreenshot(page, page, screenShotPaths.rtHydration.rtPostHydration); await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.rtHydration.rtPostHydration
);
await rightPanelPageObject.labelMapSegmentationPanel.panel.segmentByText('Small Sphere').click(); await rightPanelPageObject.labelMapSegmentationPanel.panel.segmentByText('Small Sphere').click();
await page.waitForTimeout(5000); await page.waitForTimeout(5000);
await checkForScreenshot(page, page, screenShotPaths.rtHydration.rtJumpToStructure); await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.rtHydration.rtJumpToStructure
);
}); });

View File

@ -11,11 +11,16 @@ test('should hydrate RT reports correctly', async ({
DOMOverlayPageObject, DOMOverlayPageObject,
leftPanelPageObject, leftPanelPageObject,
rightPanelPageObject, rightPanelPageObject,
viewportPageObject,
}) => { }) => {
await rightPanelPageObject.toggle(); await rightPanelPageObject.toggle();
await leftPanelPageObject.loadSeriesByModality('RTSTRUCT'); await leftPanelPageObject.loadSeriesByModality('RTSTRUCT');
await checkForScreenshot(page, page, screenShotPaths.rtHydration2.rtPreHydration); await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.rtHydration2.rtPreHydration
);
// wait for 3 seconds // wait for 3 seconds
await page.evaluate(() => { await page.evaluate(() => {
// Access cornerstone directly from the window object // Access cornerstone directly from the window object
@ -40,5 +45,9 @@ test('should hydrate RT reports correctly', async ({
// should preserve zoom and pan and scroll position after hydration // should preserve zoom and pan and scroll position after hydration
await DOMOverlayPageObject.viewport.segmentationHydration.yes.click(); await DOMOverlayPageObject.viewport.segmentationHydration.yes.click();
await checkForScreenshot(page, page, screenShotPaths.rtHydration.rtPostHydration); await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.rtHydration.rtPostHydration
);
}); });

View File

@ -12,6 +12,7 @@ test('should hydrate an RTSTRUCT from MPR', async ({
leftPanelPageObject, leftPanelPageObject,
mainToolbarPageObject, mainToolbarPageObject,
rightPanelPageObject, rightPanelPageObject,
viewportPageObject,
}) => { }) => {
await rightPanelPageObject.toggle(); await rightPanelPageObject.toggle();
@ -19,25 +20,37 @@ test('should hydrate an RTSTRUCT from MPR', async ({
await page.waitForTimeout(10000); await page.waitForTimeout(10000);
await checkForScreenshot(page, page, screenShotPaths.rtHydrationFromMPR.mprBeforeRT); await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.rtHydrationFromMPR.mprBeforeRT
);
await leftPanelPageObject.loadSeriesByModality('RTSTRUCT'); await leftPanelPageObject.loadSeriesByModality('RTSTRUCT');
await page.waitForTimeout(5000); await page.waitForTimeout(5000);
await checkForScreenshot(page, page, screenShotPaths.rtHydrationFromMPR.mprAfterRT); await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.rtHydrationFromMPR.mprAfterRT
);
await DOMOverlayPageObject.viewport.segmentationHydration.yes.click(); await DOMOverlayPageObject.viewport.segmentationHydration.yes.click();
await page.waitForTimeout(5000); await page.waitForTimeout(5000);
await checkForScreenshot(page, page, screenShotPaths.rtHydrationFromMPR.mprAfterRTHydrated); await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.rtHydrationFromMPR.mprAfterRTHydrated
);
await mainToolbarPageObject.layoutSelection.axialPrimary.click(); await mainToolbarPageObject.layoutSelection.axialPrimary.click();
await checkForScreenshot( await checkForScreenshot(
page, page,
page, viewportPageObject.grid,
screenShotPaths.rtHydrationFromMPR.mprAfterRTHydratedAfterLayoutChange screenShotPaths.rtHydrationFromMPR.mprAfterRTHydratedAfterLayoutChange
); );
}); });

View File

@ -12,6 +12,7 @@ test('should hydrate an RTSTRUCT and then launch MPR', async ({
leftPanelPageObject, leftPanelPageObject,
mainToolbarPageObject, mainToolbarPageObject,
rightPanelPageObject, rightPanelPageObject,
viewportPageObject,
}) => { }) => {
await rightPanelPageObject.toggle(); await rightPanelPageObject.toggle();
await leftPanelPageObject.loadSeriesByModality('RTSTRUCT'); await leftPanelPageObject.loadSeriesByModality('RTSTRUCT');
@ -20,7 +21,11 @@ test('should hydrate an RTSTRUCT and then launch MPR', async ({
await page.waitForTimeout(5000); await page.waitForTimeout(5000);
await checkForScreenshot(page, page, screenShotPaths.rtHydrationThenMPR.rtPostHydration); await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.rtHydrationThenMPR.rtPostHydration
);
await mainToolbarPageObject.layoutSelection.axialPrimary.click(); await mainToolbarPageObject.layoutSelection.axialPrimary.click();
@ -28,7 +33,7 @@ test('should hydrate an RTSTRUCT and then launch MPR', async ({
await checkForScreenshot( await checkForScreenshot(
page, page,
page, viewportPageObject.grid,
screenShotPaths.rtHydrationThenMPR.rtPostHydrationMPRAxialPrimary screenShotPaths.rtHydrationThenMPR.rtPostHydrationMPRAxialPrimary
); );
}); });

View File

@ -11,17 +11,26 @@ test('should launch MPR with unhydrated RTSTRUCT', async ({
leftPanelPageObject, leftPanelPageObject,
mainToolbarPageObject, mainToolbarPageObject,
rightPanelPageObject, rightPanelPageObject,
viewportPageObject,
}) => { }) => {
await rightPanelPageObject.toggle(); await rightPanelPageObject.toggle();
await leftPanelPageObject.loadSeriesByModality('RTSTRUCT'); await leftPanelPageObject.loadSeriesByModality('RTSTRUCT');
await page.waitForTimeout(5000); await page.waitForTimeout(5000);
await checkForScreenshot(page, page, screenShotPaths.rtNoHydrationThenMPR.rtNoHydrationPreMPR); await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.rtNoHydrationThenMPR.rtNoHydrationPreMPR
);
await mainToolbarPageObject.layoutSelection.MPR.click(); await mainToolbarPageObject.layoutSelection.MPR.click();
await page.waitForTimeout(5000); await page.waitForTimeout(5000);
await checkForScreenshot(page, page, screenShotPaths.rtNoHydrationThenMPR.rtNoHydrationPostMPR); await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.rtNoHydrationThenMPR.rtNoHydrationPostMPR
);
}); });

View File

@ -19,5 +19,10 @@ test('should display the rectangle tool', async ({
{ x: 591, y: 217 }, { x: 591, y: 217 },
]); ]);
await DOMOverlayPageObject.viewport.measurementTracking.confirm.click(); await DOMOverlayPageObject.viewport.measurementTracking.confirm.click();
await checkForScreenshot(page, page, screenShotPaths.rectangle.rectangleDisplayedCorrectly);
await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.rectangle.rectangleDisplayedCorrectly
);
}); });

View File

@ -6,9 +6,18 @@ test.beforeEach(async ({ page }) => {
await visitStudy(page, studyInstanceUID, mode, 2000); await visitStudy(page, studyInstanceUID, mode, 2000);
}); });
test('should reset the image to its original state', async ({ page, mainToolbarPageObject }) => { test('should reset the image to its original state', async ({
page,
mainToolbarPageObject,
viewportPageObject,
}) => {
await mainToolbarPageObject.moreTools.rotateRight.click(); await mainToolbarPageObject.moreTools.rotateRight.click();
await mainToolbarPageObject.moreTools.invert.click(); await mainToolbarPageObject.moreTools.invert.click();
await mainToolbarPageObject.moreTools.reset.click(); await mainToolbarPageObject.moreTools.reset.click();
await checkForScreenshot(page, page, screenShotPaths.reset.resetDisplayedCorrectly);
await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.reset.resetDisplayedCorrectly
);
}); });

View File

@ -6,7 +6,16 @@ test.beforeEach(async ({ page }) => {
await visitStudy(page, studyInstanceUID, mode, 2000); await visitStudy(page, studyInstanceUID, mode, 2000);
}); });
test('should rotate the image to the right', async ({ page, mainToolbarPageObject }) => { test('should rotate the image to the right', async ({
page,
mainToolbarPageObject,
viewportPageObject,
}) => {
await mainToolbarPageObject.moreTools.rotateRight.click(); await mainToolbarPageObject.moreTools.rotateRight.click();
await checkForScreenshot(page, page, screenShotPaths.rotateRight.rotateRightDisplayedCorrectly);
await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.rotateRight.rotateRightDisplayedCorrectly
);
}); });

View File

@ -14,7 +14,8 @@ test('should launch MPR with unhydrated SEG chosen from the data overlay menu',
viewportPageObject, viewportPageObject,
}) => { }) => {
await rightPanelPageObject.toggle(); await rightPanelPageObject.toggle();
const dataOverlayPageObject = (await viewportPageObject.getById('default')).overlayMenu.dataOverlay; const dataOverlayPageObject = (await viewportPageObject.getById('default')).overlayMenu
.dataOverlay;
await dataOverlayPageObject.toggle(); await dataOverlayPageObject.toggle();
await dataOverlayPageObject.addSegmentation('Segmentation'); await dataOverlayPageObject.addSegmentation('Segmentation');
@ -28,7 +29,7 @@ test('should launch MPR with unhydrated SEG chosen from the data overlay menu',
await checkForScreenshot( await checkForScreenshot(
page, page,
page, viewportPageObject.grid,
screenShotPaths.segDataOverlayNoHydrationThenMPR.segDataOverlayNoHydrationPreMPR screenShotPaths.segDataOverlayNoHydrationThenMPR.segDataOverlayNoHydrationPreMPR
); );
@ -38,7 +39,7 @@ test('should launch MPR with unhydrated SEG chosen from the data overlay menu',
await checkForScreenshot( await checkForScreenshot(
page, page,
page, viewportPageObject.grid,
screenShotPaths.segDataOverlayNoHydrationThenMPR.segDataOverlayNoHydrationPostMPR screenShotPaths.segDataOverlayNoHydrationThenMPR.segDataOverlayNoHydrationPostMPR
); );

View File

@ -11,12 +11,17 @@ test('should hydrate SEG reports correctly', async ({
DOMOverlayPageObject, DOMOverlayPageObject,
leftPanelPageObject, leftPanelPageObject,
rightPanelPageObject, rightPanelPageObject,
viewportPageObject,
}) => { }) => {
await rightPanelPageObject.toggle(); await rightPanelPageObject.toggle();
await leftPanelPageObject.loadSeriesByDescription('SEG'); await leftPanelPageObject.loadSeriesByDescription('SEG');
await page.waitForTimeout(5000); await page.waitForTimeout(5000);
await checkForScreenshot(page, page, screenShotPaths.segHydration.segPreHydration); await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.segHydration.segPreHydration
);
await page.evaluate(() => { await page.evaluate(() => {
// Access cornerstone directly from the window object // Access cornerstone directly from the window object
@ -40,5 +45,9 @@ test('should hydrate SEG reports correctly', async ({
await DOMOverlayPageObject.viewport.segmentationHydration.yes.click(); await DOMOverlayPageObject.viewport.segmentationHydration.yes.click();
await page.waitForTimeout(5000); await page.waitForTimeout(5000);
await checkForScreenshot(page, page, screenShotPaths.segHydration.segPostHydration); await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.segHydration.segPostHydration
);
}); });

View File

@ -35,9 +35,10 @@ test.describe('3D four up SEG hydration', async () => {
screenShotPaths.segHydrationFrom3DFourUp.threeDFourUpBeforeSEG screenShotPaths.segHydrationFrom3DFourUp.threeDFourUpBeforeSEG
); );
let viewportRenderCycle = waitForViewportRenderCycle(page);
await leftPanelPageObject.loadSeriesByDescription('SEG'); await leftPanelPageObject.loadSeriesByDescription('SEG');
await waitForViewportsRendered(page); await viewportRenderCycle;
await checkForScreenshot( await checkForScreenshot(
page, page,
@ -49,7 +50,7 @@ test.describe('3D four up SEG hydration', async () => {
// High rendered timeout needed: layout has 4 viewports (3D volume + MPR planes + SEG overlays), // High rendered timeout needed: layout has 4 viewports (3D volume + MPR planes + SEG overlays),
// which can take significantly longer time to fully render // which can take significantly longer time to fully render
const viewportRenderCycle = waitForViewportRenderCycle(page, { renderedTimeout: 180000 }); viewportRenderCycle = waitForViewportRenderCycle(page, { renderedTimeout: 180000 });
await DOMOverlayPageObject.viewport.segmentationHydration.yes.click(); await DOMOverlayPageObject.viewport.segmentationHydration.yes.click();

View File

@ -12,6 +12,7 @@ test('should properly display MPR for MR', async ({
leftPanelPageObject, leftPanelPageObject,
mainToolbarPageObject, mainToolbarPageObject,
rightPanelPageObject, rightPanelPageObject,
viewportPageObject,
}) => { }) => {
await rightPanelPageObject.toggle(); await rightPanelPageObject.toggle();
await leftPanelPageObject.loadSeriesByDescription('SEG'); await leftPanelPageObject.loadSeriesByDescription('SEG');
@ -19,14 +20,18 @@ test('should properly display MPR for MR', async ({
await DOMOverlayPageObject.viewport.segmentationHydration.yes.click(); await DOMOverlayPageObject.viewport.segmentationHydration.yes.click();
await page.waitForTimeout(5000); await page.waitForTimeout(5000);
await checkForScreenshot(page, page, screenShotPaths.segHydrationThenMPR.segPostHydration); await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.segHydrationThenMPR.segPostHydration
);
await mainToolbarPageObject.layoutSelection.axialPrimary.click(); await mainToolbarPageObject.layoutSelection.axialPrimary.click();
await page.waitForTimeout(5000); await page.waitForTimeout(5000);
await checkForScreenshot( await checkForScreenshot(
page, page,
page, viewportPageObject.grid,
screenShotPaths.segHydrationThenMPR.segPostHydrationMPRAxialPrimary screenShotPaths.segHydrationThenMPR.segPostHydrationMPRAxialPrimary
); );
}); });

View File

@ -11,17 +11,26 @@ test('should launch MPR with unhydrated SEG', async ({
leftPanelPageObject, leftPanelPageObject,
mainToolbarPageObject, mainToolbarPageObject,
rightPanelPageObject, rightPanelPageObject,
viewportPageObject,
}) => { }) => {
await rightPanelPageObject.toggle(); await rightPanelPageObject.toggle();
await leftPanelPageObject.loadSeriesByDescription('SEG'); await leftPanelPageObject.loadSeriesByDescription('SEG');
await page.waitForTimeout(5000); await page.waitForTimeout(5000);
await checkForScreenshot(page, page, screenShotPaths.segNoHydrationThenMPR.segNoHydrationPreMPR); await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.segNoHydrationThenMPR.segNoHydrationPreMPR
);
await mainToolbarPageObject.layoutSelection.MPR.click(); await mainToolbarPageObject.layoutSelection.MPR.click();
await page.waitForTimeout(5000); await page.waitForTimeout(5000);
await checkForScreenshot(page, page, screenShotPaths.segNoHydrationThenMPR.segNoHydrationPostMPR); await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.segNoHydrationThenMPR.segNoHydrationPostMPR
);
}); });

View File

@ -11,12 +11,17 @@ test('should hydrate SR reports correctly', async ({
DOMOverlayPageObject, DOMOverlayPageObject,
leftPanelPageObject, leftPanelPageObject,
rightPanelPageObject, rightPanelPageObject,
viewportPageObject,
}) => { }) => {
await rightPanelPageObject.toggle(); await rightPanelPageObject.toggle();
await rightPanelPageObject.measurementsPanel.select(); await rightPanelPageObject.measurementsPanel.select();
await leftPanelPageObject.loadSeriesByModality('SR'); await leftPanelPageObject.loadSeriesByModality('SR');
await page.waitForTimeout(2000); await page.waitForTimeout(2000);
await checkForScreenshot(page, page, screenShotPaths.srHydration.srPreHydration); await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.srHydration.srPreHydration
);
await page.evaluate(() => { await page.evaluate(() => {
// Access cornerstone directly from the window object // Access cornerstone directly from the window object
@ -39,7 +44,11 @@ test('should hydrate SR reports correctly', async ({
await DOMOverlayPageObject.viewport.segmentationHydration.yes.click(); await DOMOverlayPageObject.viewport.segmentationHydration.yes.click();
await page.waitForTimeout(2000); await page.waitForTimeout(2000);
await checkForScreenshot(page, page, screenShotPaths.srHydration.srPostHydration); await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.srHydration.srPostHydration
);
await page.evaluate(() => { await page.evaluate(() => {
// Access cornerstone directly from the window object // Access cornerstone directly from the window object
@ -62,5 +71,9 @@ test('should hydrate SR reports correctly', async ({
await rightPanelPageObject.measurementsPanel.panel.nthMeasurement(0).click(); await rightPanelPageObject.measurementsPanel.panel.nthMeasurement(0).click();
await checkForScreenshot(page, page, screenShotPaths.srHydration.srJumpToMeasurement); await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.srHydration.srJumpToMeasurement
);
}); });

View File

@ -1,5 +1,14 @@
import { Locator } from '@playwright/test';
import { checkForScreenshot, expect, screenShotPaths, test, visitStudy } from './utils'; import { checkForScreenshot, expect, screenShotPaths, test, visitStudy } from './utils';
async function expectNonEmptyDetailLines(lines: Locator) {
const lineCount = await lines.count();
expect(lineCount).toBeGreaterThan(0);
for (let lineIndex = 0; lineIndex < lineCount; lineIndex++) {
await expect(lines.nth(lineIndex)).not.toBeEmpty();
}
}
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
const studyInstanceUID = '1.3.6.1.4.1.14519.5.2.1.7310.5101.860473186348887719777907797922'; const studyInstanceUID = '1.3.6.1.4.1.14519.5.2.1.7310.5101.860473186348887719777907797922';
const mode = 'viewer'; const mode = 'viewer';
@ -92,19 +101,13 @@ test('should hydrate SCOORD3D probe measurements correctly', async ({
); );
// Verify the measurements list has the correct probe measurements // Verify the measurements list has the correct probe measurements
const measurementRows = page.getByTestId('data-row'); expect(await rightPanelPageObject.measurementsPanel.panel.rows).not.toHaveCount(0);
const rowCount = await measurementRows.count(); const rowCount = await rightPanelPageObject.measurementsPanel.panel.getMeasurementCount();
expect(await rightPanelPageObject.measurementsPanel.panel.getMeasurementCount()).toBeGreaterThan(
0
);
// Verify that the measurements are probe measurements (not other types)
for (let i = 0; i < rowCount; i++) { for (let i = 0; i < rowCount; i++) {
const measurementText = await rightPanelPageObject.measurementsPanel.panel const measurement = rightPanelPageObject.measurementsPanel.panel.nthMeasurement(i);
.nthMeasurement(i) await expect(measurement.title).not.toBeEmpty();
.locator.textContent(); await expectNonEmptyDetailLines(measurement.stats.primary.lines);
// Probe measurements should be present, verify they're not other measurement types
expect(measurementText).toBeTruthy();
} }
// Test jumping to a specific measurement by scrolling and clicking // Test jumping to a specific measurement by scrolling and clicking
@ -199,10 +202,8 @@ test('should display SCOORD3D probe measurements correctly', async ({
// Verify that the measurements are probe measurements (not other types like rectangle) // Verify that the measurements are probe measurements (not other types like rectangle)
for (let i = 0; i < rowCount; i++) { for (let i = 0; i < rowCount; i++) {
const measurementText = await rightPanelPageObject.measurementsPanel.panel const measurement = rightPanelPageObject.measurementsPanel.panel.nthMeasurement(i);
.nthMeasurement(i) await expect(measurement.title).not.toBeEmpty();
.locator.textContent(); await expectNonEmptyDetailLines(measurement.stats.primary.lines);
// Probe measurements should be present, verify they're not other measurement types
expect(measurementText).toBeTruthy();
} }
}); });

View File

@ -1,4 +1,21 @@
import { checkForScreenshot, expect, screenShotPaths, test, visitStudy } from './utils'; import type { Locator } from '@playwright/test';
import {
checkForScreenshot,
expect,
getAnnotationStats,
screenShotPaths,
test,
visitStudy,
} from './utils';
async function expectNonEmptyDetailLines(lines: Locator) {
const lineCount = await lines.count();
expect(lineCount).toBeGreaterThan(0);
for (let lineIndex = 0; lineIndex < lineCount; lineIndex++) {
await expect(lines.nth(lineIndex)).not.toBeEmpty();
}
}
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
const studyInstanceUID = '1.2.840.113654.2.55.242841386983064378162007136685545369722'; const studyInstanceUID = '1.2.840.113654.2.55.242841386983064378162007136685545369722';
@ -96,13 +113,11 @@ test('should hydrate SCOORD rectangle measurements correctly', async ({
const rowCount = await rightPanelPageObject.measurementsPanel.panel.getMeasurementCount(); const rowCount = await rightPanelPageObject.measurementsPanel.panel.getMeasurementCount();
expect(rowCount).toBeGreaterThan(0); expect(rowCount).toBeGreaterThan(0);
// Verify that the measurements are rectangle measurements (not other types)
for (let i = 0; i < rowCount; i++) { for (let i = 0; i < rowCount; i++) {
const measurementText = await rightPanelPageObject.measurementsPanel.panel const measurement = rightPanelPageObject.measurementsPanel.panel.nthMeasurement(i);
.nthMeasurement(i) await expect(measurement.title).not.toBeEmpty();
.locator.textContent(); await expectNonEmptyDetailLines(measurement.stats.primary.lines);
// Rectangle measurements should be present, verify they're not other measurement types await expectNonEmptyDetailLines(measurement.stats.secondary.lines);
expect(measurementText).toBeTruthy();
} }
// Test jumping to a specific measurement by scrolling and clicking // Test jumping to a specific measurement by scrolling and clicking
@ -195,12 +210,38 @@ test('should display SCOORD rectangle measurements correctly', async ({
const rowCount = await rightPanelPageObject.measurementsPanel.panel.getMeasurementCount(); const rowCount = await rightPanelPageObject.measurementsPanel.panel.getMeasurementCount();
expect(rowCount).toBeGreaterThan(0); expect(rowCount).toBeGreaterThan(0);
// Verify that the measurements are rectangle measurements (not other types like probe) const firstMeasurement = rightPanelPageObject.measurementsPanel.panel.nthMeasurement(0);
const expectedFirstPrimaryDetailLines = ['276 mm²', 'Max: 598 HU', 'Lung structure'];
await expect(firstMeasurement.stats.primary.lines).toHaveCount(
expectedFirstPrimaryDetailLines.length
);
for (let lineIndex = 0; lineIndex < expectedFirstPrimaryDetailLines.length; lineIndex++) {
await expect(firstMeasurement.stats.primary.lines.nth(lineIndex)).toHaveText(
expectedFirstPrimaryDetailLines[lineIndex]
);
}
// Assert against the source-of-truth cachedStats on the cornerstone annotation,
// independent of UI label formatting. Values should match the displayed labels
// after rounding ("276 mm²", "Max: 598 HU").
const rectangles = await getAnnotationStats(page, { toolName: 'RectangleROI' });
expect(rectangles.length).toBeGreaterThan(0);
const stats = rectangles[0].firstTargetStats!;
expect(stats.areaUnit).toBe('mm²');
expect(Math.round(stats.area as number)).toBe(276);
expect(Math.round(stats.max as number)).toBe(598);
expect(stats.Modality).toBe('CT');
expect(stats.modalityUnit).toBe('HU');
const lines = activeViewport.getSvgAnnotationStatTextLines(rectangles[0].annotationUID);
await expect(lines).toHaveCount(5);
await expect(lines.nth(0)).toHaveText('Area: 276 mm²');
for (let i = 0; i < rowCount; i++) { for (let i = 0; i < rowCount; i++) {
const measurementText = await rightPanelPageObject.measurementsPanel.panel const measurement = rightPanelPageObject.measurementsPanel.panel.nthMeasurement(i);
.nthMeasurement(i) await expect(measurement.title).not.toBeEmpty();
.locator.textContent(); await expectNonEmptyDetailLines(measurement.stats.primary.lines);
// Rectangle measurements should be present, verify they're not other measurement types await expectNonEmptyDetailLines(measurement.stats.secondary.lines);
expect(measurementText).toBeTruthy();
} }
}); });

View File

@ -1,4 +1,11 @@
import { checkForScreenshot, screenShotPaths, test, visitStudy, expect } from './utils'; import {
checkForScreenshot,
expect,
getAnnotationStats,
screenShotPaths,
test,
visitStudy,
} from './utils';
import { press } from './utils/keyboardUtils'; import { press } from './utils/keyboardUtils';
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
@ -24,7 +31,22 @@ test('should display the spline tool', async ({
{ x: 383, y: 461 }, { x: 383, y: 461 },
]); ]);
await DOMOverlayPageObject.viewport.measurementTracking.confirm.click(); await DOMOverlayPageObject.viewport.measurementTracking.confirm.click();
await checkForScreenshot(page, page, screenShotPaths.spline.splineDisplayedCorrectly); await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.spline.splineDisplayedCorrectly
);
const splines = await getAnnotationStats(page, { toolName: 'SplineROI' });
expect(splines.length).toBeGreaterThan(0);
const stats = splines[0].firstTargetStats!;
expect(stats.areaUnit).toBe('mm²');
expect(Math.round(stats.area as number)).toBe(38811);
const lines = activeViewport.getSvgAnnotationStatTextLines(splines[0].annotationUID);
await expect(lines).toHaveCount(1);
await expect(lines.nth(0)).toHaveText('Area: 38811 mm²');
}); });
test('should restore viewport interactivity after deleting an in-progress Spline annotation via context menu', async ({ test('should restore viewport interactivity after deleting an in-progress Spline annotation via context menu', async ({

View File

@ -112,30 +112,58 @@ export class RightPanelPageObject {
get measurementsPanel() { get measurementsPanel() {
const page = this.page; const page = this.page;
const getMeasurementByIdx = (index: number) => this.getPanelRowByIdx(index); const trackedMeasurementsPanel = page.getByTestId('trackedMeasurements-panel').last();
const getMeasurementByText = (text: string) => this.getPanelRowByText(text); const measurementTableRows = trackedMeasurementsPanel.locator(
const menuButton = page.getByTestId('trackedMeasurements-btn'); '[data-cy^="measurement-table-row-"]'
);
const getMeasurementStatsAt = (index: number) => {
const dataRow = trackedMeasurementsPanel
.getByTestId(`measurement-table-row-${index}`)
.getByTestId('data-row');
const locator = dataRow.locator('..').getByTestId('data-row-details');
const primaryLocator = locator.getByTestId('data-row-details-primary');
const secondaryLocator = locator.getByTestId('data-row-details-secondary');
return {
locator,
primary: {
locator: primaryLocator,
lines: primaryLocator.getByTestId('data-row-detail-line'),
},
secondary: {
locator: secondaryLocator,
lines: secondaryLocator.getByTestId('data-row-detail-line'),
},
};
};
const getMeasurementDataRowAt = (index: number) => {
const rowWrapper = trackedMeasurementsPanel.getByTestId(`measurement-table-row-${index}`);
const dataRow = rowWrapper.getByTestId('data-row');
const row = this.getPanelRowDataObject(rowWrapper);
// Selection highlight (bg-popover) is on the inner DataRow, not the measurement-table-row wrapper
return {
...row,
locator: dataRow,
stats: getMeasurementStatsAt(index),
};
};
const trackedMeasurementsMenu = page.getByTestId('trackedMeasurements-btn');
return { return {
menuButton,
panel: { panel: {
deleteAll: async () => { deleteAll: async () => {
await page.getByRole('button', { name: 'Delete' }).click(); await page.getByRole('button', { name: 'Delete' }).click();
}, },
getMeasurementCount: async () => { getMeasurementCount: async () => {
return await page.getByTestId('data-row').count(); return await measurementTableRows.count();
}, },
rows: page.getByTestId('data-row'), rows: measurementTableRows,
locator: page.getByTestId('trackedMeasurements-panel').last(), locator: trackedMeasurementsPanel,
nthMeasurement(index: number) { nthMeasurement(index: number) {
return getMeasurementByIdx(index); return getMeasurementDataRowAt(index);
},
measurementByText(text: string) {
return getMeasurementByText(text);
}, },
}, },
select: async () => { select: async () => {
await menuButton.click(); await trackedMeasurementsMenu.click();
}, },
}; };
} }
@ -414,7 +442,6 @@ export class RightPanelPageObject {
get microscopyPanel() { get microscopyPanel() {
const page = this.page; const page = this.page;
const getMeasurementByIdx = (index: number) => this.getPanelRowByIdx(index); const getMeasurementByIdx = (index: number) => this.getPanelRowByIdx(index);
const getMeasurementByText = (text: string) => this.getPanelRowByText(text);
return { return {
locator: page.getByTestId('measurements-panel'), locator: page.getByTestId('measurements-panel'),
@ -424,9 +451,6 @@ export class RightPanelPageObject {
nthMeasurement(index: number) { nthMeasurement(index: number) {
return getMeasurementByIdx(index); return getMeasurementByIdx(index);
}, },
measurementByText(text: string) {
return getMeasurementByText(text);
},
}; };
} }
} }

View File

@ -5,12 +5,13 @@ import {
simulateDoubleClickOnElement, simulateDoubleClickOnElement,
simulateNormalizedClicksOnElement, simulateNormalizedClicksOnElement,
simulateNormalizedDragOnElement, simulateNormalizedDragOnElement,
simulateNormalizedPathDragOnElement,
} from '../utils'; } from '../utils';
import { DataOverlayPageObject } from './DataOverlayPageObject'; import { DataOverlayPageObject } from './DataOverlayPageObject';
import { DOMOverlayPageObject } from './DOMOverlayPageObject'; import { DOMOverlayPageObject } from './DOMOverlayPageObject';
import { MagnifyGlassPageObject } from './MagnifyGlassPageObject'; import { MagnifyGlassPageObject } from './MagnifyGlassPageObject';
type SvgInnerElement = 'circle' | 'path' | 'd' | 'line'; type SvgInnerElement = 'circle' | 'path' | 'd' | 'line' | 'g';
type NormalizedDragParams = { type NormalizedDragParams = {
start: { x: number; y: number }; start: { x: number; y: number };
@ -18,6 +19,11 @@ type NormalizedDragParams = {
config?: { button?: 'left' | 'right' | 'middle'; delay?: number; steps?: number }; config?: { button?: 'left' | 'right' | 'middle'; delay?: number; steps?: number };
}; };
type NormalizedPathDragParams = {
path: { x: number; y: number }[];
config?: { button?: 'left' | 'right' | 'middle'; delay?: number; steps?: number };
};
export interface IOverlayText { export interface IOverlayText {
get windowLevel(): Locator; get windowLevel(): Locator;
get instanceNumber(): Locator; get instanceNumber(): Locator;
@ -56,6 +62,7 @@ export interface IViewportPageObject {
button?: 'left' | 'right' | 'middle' button?: 'left' | 'right' | 'middle'
) => Promise<void>; ) => Promise<void>;
normalizedDragAt: (params: NormalizedDragParams) => Promise<void>; normalizedDragAt: (params: NormalizedDragParams) => Promise<void>;
normalizedPathDragAt: (params: NormalizedPathDragParams) => Promise<void>;
orientationMarkers: { orientationMarkers: {
topMid: Locator; topMid: Locator;
leftMid: Locator; leftMid: Locator;
@ -81,6 +88,7 @@ export interface IViewportPageObject {
}; };
pane: Locator; pane: Locator;
svg: (innerElement?: SvgInnerElement) => Locator; svg: (innerElement?: SvgInnerElement) => Locator;
getSvgAnnotationStatTextLines: (uid: string) => Locator;
navigationArrows: { navigationArrows: {
locator: Locator; locator: Locator;
prev: { prev: {
@ -297,6 +305,15 @@ export class ViewportPageObject {
steps: params.config?.steps, steps: params.config?.steps,
}); });
}, },
normalizedPathDragAt: async (params: NormalizedPathDragParams) => {
await simulateNormalizedPathDragOnElement({
locator: viewport,
path: params.path,
button: params.config?.button,
delay: params.config?.delay,
steps: params.config?.steps,
});
},
orientationMarkers: this.getOrientationMarkers(viewport), orientationMarkers: this.getOrientationMarkers(viewport),
overlayText: this.getOverlayText(viewport), overlayText: this.getOverlayText(viewport),
overlayMenu: await this.getOverlayMenu(viewport), overlayMenu: await this.getOverlayMenu(viewport),
@ -304,6 +321,11 @@ export class ViewportPageObject {
svg: (innerElement?: SvgInnerElement) => { svg: (innerElement?: SvgInnerElement) => {
return this.getSvg(viewport, innerElement); return this.getSvg(viewport, innerElement);
}, },
getSvgAnnotationStatTextLines: (uid: string) => {
return this.getSvg(viewport)
.locator(`g[data-annotation-uid="${uid}"]`)
.locator('tspan');
},
navigationArrows: this.getNavigationArrows(viewport), navigationArrows: this.getNavigationArrows(viewport),
sliceNavigation: this.getSliceNavigation(viewport), sliceNavigation: this.getSliceNavigation(viewport),
magnifyGlass: new MagnifyGlassPageObject(this.page, viewport), magnifyGlass: new MagnifyGlassPageObject(this.page, viewport),

Binary file not shown.

Before

Width:  |  Height:  |  Size: 351 KiB

After

Width:  |  Height:  |  Size: 282 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 304 KiB

After

Width:  |  Height:  |  Size: 230 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 349 KiB

After

Width:  |  Height:  |  Size: 272 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 320 KiB

After

Width:  |  Height:  |  Size: 250 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 257 KiB

After

Width:  |  Height:  |  Size: 175 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 270 KiB

After

Width:  |  Height:  |  Size: 272 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 269 KiB

After

Width:  |  Height:  |  Size: 271 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 267 KiB

After

Width:  |  Height:  |  Size: 268 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 341 KiB

After

Width:  |  Height:  |  Size: 274 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 259 KiB

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 267 KiB

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 256 KiB

After

Width:  |  Height:  |  Size: 174 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 257 KiB

After

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 254 KiB

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 213 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 211 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 215 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 195 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 196 KiB

After

Width:  |  Height:  |  Size: 201 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 KiB

After

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 202 KiB

After

Width:  |  Height:  |  Size: 206 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 192 KiB

After

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 200 KiB

After

Width:  |  Height:  |  Size: 206 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 209 KiB

After

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 265 KiB

After

Width:  |  Height:  |  Size: 182 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 KiB

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 253 KiB

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 284 KiB

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 230 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 194 KiB

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 194 KiB

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 230 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 131 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 303 KiB

After

Width:  |  Height:  |  Size: 219 KiB

Some files were not shown because too many files have changed in this diff Show More