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);
if (changes > 0) {
// Preserve original formatting (detect indent)
const indent = content.match(/^(\s+)/m)?.[1] || ' ';
// Preserve original formatting (detect indent — restrict to spaces/tabs so
// 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');
const rel = pkgPath.replace(rootDir + '/', '').replace(rootDir + '\\', '');
console.log(` Updated ${rel} (${changes} packages)`);

View File

@ -31,7 +31,7 @@
"@babel/plugin-transform-regenerator": "7.28.1",
"@babel/plugin-transform-runtime": "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-typescript": "7.27.1"
},

534
bun.lock
View File

@ -50,7 +50,7 @@
},
"addOns/externals/devDependencies": {
"name": "@externals/devDependencies",
"version": "3.13.0-beta.68",
"version": "3.13.0-beta.74",
"dependencies": {
"@babel/runtime": "7.28.2",
"@kitware/vtk.js": "34.15.1",
@ -131,22 +131,22 @@
},
"addOns/externals/dicom-microscopy-viewer": {
"name": "@externals/dicom-microscopy-viewer",
"version": "3.13.0-beta.68",
"version": "3.13.0-beta.74",
"dependencies": {
"dicom-microscopy-viewer": "0.48.17",
},
},
"extensions/cornerstone": {
"name": "@ohif/extension-cornerstone",
"version": "3.13.0-beta.68",
"version": "3.13.0-beta.74",
"dependencies": {
"@babel/runtime": "7.28.2",
"@cornerstonejs/adapters": "4.22.3",
"@cornerstonejs/ai": "4.22.3",
"@cornerstonejs/core": "4.22.3",
"@cornerstonejs/labelmap-interpolation": "4.22.3",
"@cornerstonejs/polymorphic-segmentation": "4.22.3",
"@cornerstonejs/tools": "4.22.3",
"@cornerstonejs/adapters": "4.22.8",
"@cornerstonejs/ai": "4.22.8",
"@cornerstonejs/core": "4.22.8",
"@cornerstonejs/labelmap-interpolation": "4.22.8",
"@cornerstonejs/polymorphic-segmentation": "4.22.8",
"@cornerstonejs/tools": "4.22.8",
"@icr/polyseg-wasm": "0.4.0",
"@itk-wasm/morphological-contour-interpolation": "1.1.0",
"@kitware/vtk.js": "34.15.1",
@ -164,9 +164,9 @@
"@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2",
"@cornerstonejs/codec-openjpeg": "1.3.0",
"@cornerstonejs/codec-openjph": "2.4.7",
"@cornerstonejs/dicom-image-loader": "4.22.3",
"@ohif/core": "3.13.0-beta.68",
"@ohif/ui": "3.13.0-beta.68",
"@cornerstonejs/dicom-image-loader": "4.22.8",
"@ohif/core": "3.13.0-beta.74",
"@ohif/ui": "3.13.0-beta.74",
"dcmjs": "0.49.4",
"dicom-parser": "1.8.21",
"hammerjs": "2.0.8",
@ -178,18 +178,18 @@
},
"extensions/cornerstone-dicom-pmap": {
"name": "@ohif/extension-cornerstone-dicom-pmap",
"version": "3.13.0-beta.68",
"version": "3.13.0-beta.74",
"dependencies": {
"@babel/runtime": "7.28.2",
"@cornerstonejs/adapters": "4.22.3",
"@cornerstonejs/core": "4.22.3",
"@cornerstonejs/adapters": "4.22.8",
"@cornerstonejs/core": "4.22.8",
"@kitware/vtk.js": "34.15.1",
},
"peerDependencies": {
"@ohif/core": "3.13.0-beta.68",
"@ohif/extension-cornerstone": "3.13.0-beta.68",
"@ohif/extension-default": "3.13.0-beta.68",
"@ohif/i18n": "3.13.0-beta.68",
"@ohif/core": "3.13.0-beta.74",
"@ohif/extension-cornerstone": "3.13.0-beta.74",
"@ohif/extension-default": "3.13.0-beta.74",
"@ohif/i18n": "3.13.0-beta.74",
"prop-types": "15.8.1",
"react": "18.3.1",
"react-dom": "18.3.1",
@ -200,15 +200,15 @@
},
"extensions/cornerstone-dicom-rt": {
"name": "@ohif/extension-cornerstone-dicom-rt",
"version": "3.13.0-beta.68",
"version": "3.13.0-beta.74",
"dependencies": {
"@babel/runtime": "7.28.2",
},
"peerDependencies": {
"@ohif/core": "3.13.0-beta.68",
"@ohif/extension-cornerstone": "3.13.0-beta.68",
"@ohif/extension-default": "3.13.0-beta.68",
"@ohif/i18n": "3.13.0-beta.68",
"@ohif/core": "3.13.0-beta.74",
"@ohif/extension-cornerstone": "3.13.0-beta.74",
"@ohif/extension-default": "3.13.0-beta.74",
"@ohif/i18n": "3.13.0-beta.74",
"prop-types": "15.8.1",
"react": "18.3.1",
"react-dom": "18.3.1",
@ -219,18 +219,18 @@
},
"extensions/cornerstone-dicom-seg": {
"name": "@ohif/extension-cornerstone-dicom-seg",
"version": "3.13.0-beta.68",
"version": "3.13.0-beta.74",
"dependencies": {
"@babel/runtime": "7.28.2",
"@cornerstonejs/adapters": "4.22.3",
"@cornerstonejs/core": "4.22.3",
"@cornerstonejs/adapters": "4.22.8",
"@cornerstonejs/core": "4.22.8",
"@kitware/vtk.js": "34.15.1",
},
"peerDependencies": {
"@ohif/core": "3.13.0-beta.68",
"@ohif/extension-cornerstone": "3.13.0-beta.68",
"@ohif/extension-default": "3.13.0-beta.68",
"@ohif/i18n": "3.13.0-beta.68",
"@ohif/core": "3.13.0-beta.74",
"@ohif/extension-cornerstone": "3.13.0-beta.74",
"@ohif/extension-default": "3.13.0-beta.74",
"@ohif/i18n": "3.13.0-beta.74",
"prop-types": "15.8.1",
"react": "18.3.1",
"react-dom": "18.3.1",
@ -241,19 +241,19 @@
},
"extensions/cornerstone-dicom-sr": {
"name": "@ohif/extension-cornerstone-dicom-sr",
"version": "3.13.0-beta.68",
"version": "3.13.0-beta.74",
"dependencies": {
"@babel/runtime": "7.28.2",
"@cornerstonejs/adapters": "4.22.3",
"@cornerstonejs/core": "4.22.3",
"@cornerstonejs/tools": "4.22.3",
"@cornerstonejs/adapters": "4.22.8",
"@cornerstonejs/core": "4.22.8",
"@cornerstonejs/tools": "4.22.8",
"classnames": "2.5.1",
},
"peerDependencies": {
"@ohif/core": "3.13.0-beta.68",
"@ohif/extension-cornerstone": "3.13.0-beta.68",
"@ohif/extension-measurement-tracking": "3.13.0-beta.68",
"@ohif/ui": "3.13.0-beta.68",
"@ohif/core": "3.13.0-beta.74",
"@ohif/extension-cornerstone": "3.13.0-beta.74",
"@ohif/extension-measurement-tracking": "3.13.0-beta.74",
"@ohif/ui": "3.13.0-beta.74",
"dcmjs": "0.49.4",
"dicom-parser": "1.8.21",
"hammerjs": "2.0.8",
@ -263,19 +263,19 @@
},
"extensions/cornerstone-dynamic-volume": {
"name": "@ohif/extension-cornerstone-dynamic-volume",
"version": "3.13.0-beta.68",
"version": "3.13.0-beta.74",
"dependencies": {
"@babel/runtime": "7.28.2",
"@cornerstonejs/core": "4.22.3",
"@cornerstonejs/tools": "4.22.3",
"@cornerstonejs/core": "4.22.8",
"@cornerstonejs/tools": "4.22.8",
"classnames": "2.5.1",
},
"peerDependencies": {
"@ohif/core": "3.13.0-beta.68",
"@ohif/extension-cornerstone": "3.13.0-beta.68",
"@ohif/extension-default": "3.13.0-beta.68",
"@ohif/i18n": "3.13.0-beta.68",
"@ohif/ui": "3.13.0-beta.68",
"@ohif/core": "3.13.0-beta.74",
"@ohif/extension-cornerstone": "3.13.0-beta.74",
"@ohif/extension-default": "3.13.0-beta.74",
"@ohif/i18n": "3.13.0-beta.74",
"@ohif/ui": "3.13.0-beta.74",
"dcmjs": "0.49.4",
"dicom-parser": "1.8.21",
"hammerjs": "2.0.8",
@ -285,7 +285,7 @@
},
"extensions/default": {
"name": "@ohif/extension-default",
"version": "3.13.0-beta.68",
"version": "3.13.0-beta.74",
"dependencies": {
"@babel/runtime": "7.28.2",
"@cornerstonejs/calculate-suv": "1.1.0",
@ -294,8 +294,8 @@
"react-color": "2.19.3",
},
"peerDependencies": {
"@ohif/core": "3.13.0-beta.68",
"@ohif/i18n": "3.13.0-beta.68",
"@ohif/core": "3.13.0-beta.74",
"@ohif/i18n": "3.13.0-beta.74",
"dcmjs": "0.49.4",
"dicomweb-client": "0.10.4",
"prop-types": "15.8.1",
@ -309,7 +309,7 @@
},
"extensions/dicom-microscopy": {
"name": "@ohif/extension-dicom-microscopy",
"version": "3.13.0-beta.68",
"version": "3.13.0-beta.74",
"dependencies": {
"@babel/runtime": "7.28.2",
"@cornerstonejs/codec-charls": "1.2.3",
@ -320,10 +320,10 @@
"mathjs": "12.4.3",
},
"peerDependencies": {
"@ohif/core": "3.13.0-beta.68",
"@ohif/extension-default": "3.13.0-beta.68",
"@ohif/i18n": "3.13.0-beta.68",
"@ohif/ui": "3.13.0-beta.68",
"@ohif/core": "3.13.0-beta.74",
"@ohif/extension-default": "3.13.0-beta.74",
"@ohif/i18n": "3.13.0-beta.74",
"@ohif/ui": "3.13.0-beta.74",
"prop-types": "15.8.1",
"react": "18.3.1",
"react-dom": "18.3.1",
@ -334,14 +334,14 @@
},
"extensions/dicom-pdf": {
"name": "@ohif/extension-dicom-pdf",
"version": "3.13.0-beta.68",
"version": "3.13.0-beta.74",
"dependencies": {
"@babel/runtime": "7.28.2",
"classnames": "2.5.1",
},
"peerDependencies": {
"@ohif/core": "3.13.0-beta.68",
"@ohif/ui": "3.13.0-beta.68",
"@ohif/core": "3.13.0-beta.74",
"@ohif/ui": "3.13.0-beta.74",
"dcmjs": "0.49.4",
"dicom-parser": "1.8.21",
"hammerjs": "2.0.8",
@ -351,14 +351,14 @@
},
"extensions/dicom-video": {
"name": "@ohif/extension-dicom-video",
"version": "3.13.0-beta.68",
"version": "3.13.0-beta.74",
"dependencies": {
"@babel/runtime": "7.28.2",
"classnames": "2.5.1",
},
"peerDependencies": {
"@ohif/core": "3.13.0-beta.68",
"@ohif/ui": "3.13.0-beta.68",
"@ohif/core": "3.13.0-beta.74",
"@ohif/ui": "3.13.0-beta.74",
"dcmjs": "0.49.4",
"dicom-parser": "1.8.21",
"hammerjs": "2.0.8",
@ -368,20 +368,20 @@
},
"extensions/measurement-tracking": {
"name": "@ohif/extension-measurement-tracking",
"version": "3.13.0-beta.68",
"version": "3.13.0-beta.74",
"dependencies": {
"@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": "4.38.3",
},
"peerDependencies": {
"@cornerstonejs/core": "4.22.3",
"@cornerstonejs/tools": "4.22.3",
"@ohif/core": "3.13.0-beta.68",
"@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.68",
"@ohif/extension-default": "3.13.0-beta.68",
"@ohif/ui": "3.13.0-beta.68",
"@cornerstonejs/core": "4.22.8",
"@cornerstonejs/tools": "4.22.8",
"@ohif/core": "3.13.0-beta.74",
"@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.74",
"@ohif/extension-default": "3.13.0-beta.74",
"@ohif/ui": "3.13.0-beta.74",
"classnames": "2.5.1",
"dcmjs": "0.49.4",
"lodash.debounce": "4.0.8",
@ -394,14 +394,14 @@
},
"extensions/test-extension": {
"name": "@ohif/extension-test",
"version": "3.13.0-beta.68",
"version": "3.13.0-beta.74",
"dependencies": {
"@babel/runtime": "7.28.2",
"classnames": "2.5.1",
},
"peerDependencies": {
"@ohif/core": "3.13.0-beta.68",
"@ohif/ui": "3.13.0-beta.68",
"@ohif/core": "3.13.0-beta.74",
"@ohif/ui": "3.13.0-beta.74",
"dcmjs": "0.49.4",
"dicom-parser": "1.8.21",
"hammerjs": "2.0.8",
@ -411,7 +411,7 @@
},
"extensions/tmtv": {
"name": "@ohif/extension-tmtv",
"version": "3.13.0-beta.68",
"version": "3.13.0-beta.74",
"dependencies": {
"@babel/runtime": "7.28.2",
"classnames": "2.5.1",
@ -428,16 +428,16 @@
},
"extensions/usAnnotation": {
"name": "@ohif/extension-ultrasound-pleura-bline",
"version": "3.13.0-beta.68",
"version": "3.13.0-beta.74",
"dependencies": {
"@babel/runtime": "7.28.2",
"@cornerstonejs/core": "4.22.3",
"@cornerstonejs/tools": "4.22.3",
"@ohif/core": "3.13.0-beta.68",
"@ohif/extension-cornerstone": "3.13.0-beta.68",
"@ohif/extension-default": "3.13.0-beta.68",
"@ohif/i18n": "3.13.0-beta.68",
"@ohif/ui-next": "3.13.0-beta.68",
"@cornerstonejs/core": "4.22.8",
"@cornerstonejs/tools": "4.22.8",
"@ohif/core": "3.13.0-beta.74",
"@ohif/extension-cornerstone": "3.13.0-beta.74",
"@ohif/extension-default": "3.13.0-beta.74",
"@ohif/i18n": "3.13.0-beta.74",
"@ohif/ui-next": "3.13.0-beta.74",
},
"devDependencies": {
"@babel/core": "7.28.0",
@ -450,7 +450,7 @@
"@babel/plugin-transform-regenerator": "7.28.1",
"@babel/plugin-transform-runtime": "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-typescript": "7.27.1",
"@svgr/webpack": "8.1.0",
@ -476,7 +476,7 @@
},
"modes/basic": {
"name": "@ohif/mode-basic",
"version": "3.13.0-beta.68",
"version": "3.13.0-beta.74",
"dependencies": {
"@babel/runtime": "7.28.2",
},
@ -485,19 +485,19 @@
"webpack-merge": "5.10.0",
},
"peerDependencies": {
"@ohif/core": "3.13.0-beta.68",
"@ohif/extension-cornerstone": "3.13.0-beta.68",
"@ohif/extension-cornerstone-dicom-rt": "3.13.0-beta.68",
"@ohif/extension-cornerstone-dicom-seg": "3.13.0-beta.68",
"@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.68",
"@ohif/extension-default": "3.13.0-beta.68",
"@ohif/extension-dicom-pdf": "3.13.0-beta.68",
"@ohif/extension-dicom-video": "3.13.0-beta.68",
"@ohif/core": "3.13.0-beta.74",
"@ohif/extension-cornerstone": "3.13.0-beta.74",
"@ohif/extension-cornerstone-dicom-rt": "3.13.0-beta.74",
"@ohif/extension-cornerstone-dicom-seg": "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-dicom-pdf": "3.13.0-beta.74",
"@ohif/extension-dicom-video": "3.13.0-beta.74",
},
},
"modes/basic-dev-mode": {
"name": "@ohif/mode-basic-dev-mode",
"version": "3.13.0-beta.68",
"version": "3.13.0-beta.74",
"dependencies": {
"@babel/runtime": "7.28.2",
"i18next": "17.3.1",
@ -507,17 +507,17 @@
"webpack-merge": "5.10.0",
},
"peerDependencies": {
"@ohif/core": "3.13.0-beta.68",
"@ohif/extension-cornerstone": "3.13.0-beta.68",
"@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.68",
"@ohif/extension-default": "3.13.0-beta.68",
"@ohif/extension-dicom-pdf": "3.13.0-beta.68",
"@ohif/extension-dicom-video": "3.13.0-beta.68",
"@ohif/core": "3.13.0-beta.74",
"@ohif/extension-cornerstone": "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-dicom-pdf": "3.13.0-beta.74",
"@ohif/extension-dicom-video": "3.13.0-beta.74",
},
},
"modes/basic-test-mode": {
"name": "@ohif/mode-test",
"version": "3.13.0-beta.68",
"version": "3.13.0-beta.74",
"dependencies": {
"@babel/runtime": "7.28.2",
"i18next": "17.3.1",
@ -527,19 +527,19 @@
"webpack-merge": "5.10.0",
},
"peerDependencies": {
"@ohif/core": "3.13.0-beta.68",
"@ohif/extension-cornerstone": "3.13.0-beta.68",
"@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.68",
"@ohif/extension-default": "3.13.0-beta.68",
"@ohif/extension-dicom-pdf": "3.13.0-beta.68",
"@ohif/extension-dicom-video": "3.13.0-beta.68",
"@ohif/extension-measurement-tracking": "3.13.0-beta.68",
"@ohif/extension-test": "3.13.0-beta.68",
"@ohif/core": "3.13.0-beta.74",
"@ohif/extension-cornerstone": "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-dicom-pdf": "3.13.0-beta.74",
"@ohif/extension-dicom-video": "3.13.0-beta.74",
"@ohif/extension-measurement-tracking": "3.13.0-beta.74",
"@ohif/extension-test": "3.13.0-beta.74",
},
},
"modes/longitudinal": {
"name": "@ohif/mode-longitudinal",
"version": "3.13.0-beta.68",
"version": "3.13.0-beta.74",
"dependencies": {
"@babel/runtime": "7.28.2",
"i18next": "17.3.1",
@ -549,33 +549,33 @@
"webpack-merge": "5.10.0",
},
"peerDependencies": {
"@ohif/core": "3.13.0-beta.68",
"@ohif/extension-cornerstone": "3.13.0-beta.68",
"@ohif/extension-cornerstone-dicom-rt": "3.13.0-beta.68",
"@ohif/extension-cornerstone-dicom-seg": "3.13.0-beta.68",
"@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.68",
"@ohif/extension-default": "3.13.0-beta.68",
"@ohif/extension-dicom-pdf": "3.13.0-beta.68",
"@ohif/extension-dicom-video": "3.13.0-beta.68",
"@ohif/extension-measurement-tracking": "3.13.0-beta.68",
"@ohif/mode-basic": "3.13.0-beta.68",
"@ohif/core": "3.13.0-beta.74",
"@ohif/extension-cornerstone": "3.13.0-beta.74",
"@ohif/extension-cornerstone-dicom-rt": "3.13.0-beta.74",
"@ohif/extension-cornerstone-dicom-seg": "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-dicom-pdf": "3.13.0-beta.74",
"@ohif/extension-dicom-video": "3.13.0-beta.74",
"@ohif/extension-measurement-tracking": "3.13.0-beta.74",
"@ohif/mode-basic": "3.13.0-beta.74",
},
},
"modes/microscopy": {
"name": "@ohif/mode-microscopy",
"version": "3.13.0-beta.68",
"version": "3.13.0-beta.74",
"dependencies": {
"@babel/runtime": "7.28.2",
"i18next": "17.3.1",
},
"peerDependencies": {
"@ohif/core": "3.13.0-beta.68",
"@ohif/extension-dicom-microscopy": "3.13.0-beta.68",
"@ohif/core": "3.13.0-beta.74",
"@ohif/extension-dicom-microscopy": "3.13.0-beta.74",
},
},
"modes/preclinical-4d": {
"name": "@ohif/mode-preclinical-4d",
"version": "3.13.0-beta.68",
"version": "3.13.0-beta.74",
"dependencies": {
"@babel/runtime": "7.28.2",
},
@ -594,7 +594,7 @@
},
"modes/segmentation": {
"name": "@ohif/mode-segmentation",
"version": "3.13.0-beta.68",
"version": "3.13.0-beta.74",
"dependencies": {
"@babel/runtime": "7.28.2",
"i18next": "17.3.1",
@ -609,7 +609,7 @@
"@babel/plugin-transform-regenerator": "7.28.1",
"@babel/plugin-transform-runtime": "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-typescript": "7.27.1",
"@svgr/webpack": "8.1.0",
@ -623,20 +623,20 @@
"webpack-merge": "5.10.0",
},
"peerDependencies": {
"@ohif/core": "3.13.0-beta.68",
"@ohif/extension-cornerstone": "3.13.0-beta.68",
"@ohif/extension-cornerstone-dicom-rt": "3.13.0-beta.68",
"@ohif/extension-cornerstone-dicom-seg": "3.13.0-beta.68",
"@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.68",
"@ohif/extension-default": "3.13.0-beta.68",
"@ohif/extension-dicom-pdf": "3.13.0-beta.68",
"@ohif/extension-dicom-video": "3.13.0-beta.68",
"@ohif/mode-basic": "3.13.0-beta.68",
"@ohif/core": "3.13.0-beta.74",
"@ohif/extension-cornerstone": "3.13.0-beta.74",
"@ohif/extension-cornerstone-dicom-rt": "3.13.0-beta.74",
"@ohif/extension-cornerstone-dicom-seg": "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-dicom-pdf": "3.13.0-beta.74",
"@ohif/extension-dicom-video": "3.13.0-beta.74",
"@ohif/mode-basic": "3.13.0-beta.74",
},
},
"modes/tmtv": {
"name": "@ohif/mode-tmtv",
"version": "3.13.0-beta.68",
"version": "3.13.0-beta.74",
"dependencies": {
"@babel/runtime": "7.28.2",
"i18next": "17.3.1",
@ -657,14 +657,14 @@
},
"modes/usAnnotation": {
"name": "@ohif/mode-ultrasound-pleura-bline",
"version": "3.13.0-beta.68",
"version": "3.13.0-beta.74",
"dependencies": {
"@babel/runtime": "7.28.2",
"@cornerstonejs/core": "4.22.3",
"@cornerstonejs/tools": "4.22.3",
"@ohif/core": "3.13.0-beta.68",
"@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.68",
"@ohif/extension-ultrasound-pleura-bline": "3.13.0-beta.68",
"@cornerstonejs/core": "4.22.8",
"@cornerstonejs/tools": "4.22.8",
"@ohif/core": "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",
"i18next": "17.3.1",
},
"devDependencies": {
@ -677,7 +677,7 @@
"@babel/plugin-transform-regenerator": "7.28.1",
"@babel/plugin-transform-runtime": "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-typescript": "7.27.1",
"@svgr/webpack": "8.1.0",
@ -693,34 +693,34 @@
},
"platform/app": {
"name": "@ohif/app",
"version": "3.13.0-beta.68",
"version": "3.13.0-beta.74",
"dependencies": {
"@babel/runtime": "7.28.2",
"@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",
"@cornerstonejs/dicom-image-loader": "4.22.3",
"@cornerstonejs/dicom-image-loader": "4.22.8",
"@emotion/serialize": "1.3.3",
"@ohif/core": "3.13.0-beta.68",
"@ohif/extension-cornerstone": "3.13.0-beta.68",
"@ohif/extension-cornerstone-dicom-rt": "3.13.0-beta.68",
"@ohif/extension-cornerstone-dicom-seg": "3.13.0-beta.68",
"@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.68",
"@ohif/extension-default": "3.13.0-beta.68",
"@ohif/extension-dicom-microscopy": "3.13.0-beta.68",
"@ohif/extension-dicom-pdf": "3.13.0-beta.68",
"@ohif/extension-dicom-video": "3.13.0-beta.68",
"@ohif/extension-test": "3.13.0-beta.68",
"@ohif/extension-ultrasound-pleura-bline": "3.13.0-beta.68",
"@ohif/i18n": "3.13.0-beta.68",
"@ohif/mode-basic-dev-mode": "3.13.0-beta.68",
"@ohif/mode-longitudinal": "3.13.0-beta.68",
"@ohif/mode-microscopy": "3.13.0-beta.68",
"@ohif/mode-test": "3.13.0-beta.68",
"@ohif/mode-ultrasound-pleura-bline": "3.13.0-beta.68",
"@ohif/ui": "3.13.0-beta.68",
"@ohif/ui-next": "3.13.0-beta.68",
"@ohif/core": "3.13.0-beta.74",
"@ohif/extension-cornerstone": "3.13.0-beta.74",
"@ohif/extension-cornerstone-dicom-rt": "3.13.0-beta.74",
"@ohif/extension-cornerstone-dicom-seg": "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-dicom-microscopy": "3.13.0-beta.74",
"@ohif/extension-dicom-pdf": "3.13.0-beta.74",
"@ohif/extension-dicom-video": "3.13.0-beta.74",
"@ohif/extension-test": "3.13.0-beta.74",
"@ohif/extension-ultrasound-pleura-bline": "3.13.0-beta.74",
"@ohif/i18n": "3.13.0-beta.74",
"@ohif/mode-basic-dev-mode": "3.13.0-beta.74",
"@ohif/mode-longitudinal": "3.13.0-beta.74",
"@ohif/mode-microscopy": "3.13.0-beta.74",
"@ohif/mode-test": "3.13.0-beta.74",
"@ohif/mode-ultrasound-pleura-bline": "3.13.0-beta.74",
"@ohif/ui": "3.13.0-beta.74",
"@ohif/ui-next": "3.13.0-beta.74",
"@svgr/webpack": "8.1.0",
"@types/react": "18.3.23",
"classnames": "2.5.1",
@ -772,7 +772,7 @@
},
"platform/cli": {
"name": "@ohif/cli",
"version": "3.13.0-beta.68",
"version": "3.13.0-beta.74",
"bin": {
"ohif-cli": "src/index.js",
},
@ -796,7 +796,7 @@
},
"platform/core": {
"name": "@ohif/core",
"version": "3.13.0-beta.68",
"version": "3.13.0-beta.74",
"dependencies": {
"@babel/runtime": "7.28.2",
"dcmjs": "0.49.4",
@ -821,16 +821,16 @@
"@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2",
"@cornerstonejs/codec-openjpeg": "1.3.0",
"@cornerstonejs/codec-openjph": "2.4.7",
"@cornerstonejs/core": "4.22.3",
"@cornerstonejs/dicom-image-loader": "4.22.3",
"@ohif/ui": "3.13.0-beta.68",
"@cornerstonejs/core": "4.22.8",
"@cornerstonejs/dicom-image-loader": "4.22.8",
"@ohif/ui": "3.13.0-beta.74",
"cornerstone-math": "0.1.10",
"dicom-parser": "1.8.21",
},
},
"platform/i18n": {
"name": "@ohif/i18n",
"version": "3.13.0-beta.68",
"version": "3.13.0-beta.74",
"dependencies": {
"@babel/runtime": "7.28.2",
"i18next-locize-backend": "2.2.2",
@ -855,7 +855,7 @@
},
"platform/ui": {
"name": "@ohif/ui",
"version": "3.13.0-beta.68",
"version": "3.13.0-beta.74",
"dependencies": {
"@testing-library/react": "13.4.0",
"browser-detect": "0.2.28",
@ -905,7 +905,7 @@
},
"platform/ui-next": {
"name": "@ohif/ui-next",
"version": "3.13.0-beta.68",
"version": "3.13.0-beta.74",
"dependencies": {
"@radix-ui/react-accordion": "1.2.11",
"@radix-ui/react-checkbox": "1.3.2",
@ -1245,9 +1245,9 @@
"@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=="],
@ -1259,15 +1259,15 @@
"@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=="],
@ -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/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=="],
"@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/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=="],
"@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": {
"@babel/runtime": "7.28.2",
"@cornerstonejs/adapters": "4.22.3",
"@cornerstonejs/core": "4.22.3",
"@cornerstonejs/adapters": "4.22.8",
"@cornerstonejs/core": "4.22.8",
"@kitware/vtk.js": "34.15.1"
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -42,8 +42,8 @@
},
"dependencies": {
"@babel/runtime": "7.28.2",
"@cornerstonejs/core": "4.22.3",
"@cornerstonejs/tools": "4.22.3",
"@cornerstonejs/core": "4.22.8",
"@cornerstonejs/tools": "4.22.8",
"@ohif/core": "3.13.0-beta.74",
"@ohif/extension-cornerstone": "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-runtime": "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-typescript": "7.27.1",
"@svgr/webpack": "8.1.0",

View File

@ -59,7 +59,7 @@
"@babel/plugin-transform-regenerator": "7.28.1",
"@babel/plugin-transform-runtime": "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-typescript": "7.27.1",
"@svgr/webpack": "8.1.0",

View File

@ -34,8 +34,8 @@
},
"dependencies": {
"@babel/runtime": "7.28.2",
"@cornerstonejs/core": "4.22.3",
"@cornerstonejs/tools": "4.22.3",
"@cornerstonejs/core": "4.22.8",
"@cornerstonejs/tools": "4.22.8",
"@ohif/core": "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",
@ -51,7 +51,7 @@
"@babel/plugin-transform-regenerator": "7.28.1",
"@babel/plugin-transform-runtime": "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-typescript": "7.27.1",
"@svgr/webpack": "8.1.0",

View File

@ -54,7 +54,7 @@
"@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2",
"@cornerstonejs/codec-openjpeg": "1.3.0",
"@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",
"@ohif/core": "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-runtime": "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-typescript": "^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-runtime": "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-typescript": "^7.27.1",
"babel-loader": "^8.0.0-beta.4",

View File

@ -37,8 +37,8 @@
"@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2",
"@cornerstonejs/codec-openjpeg": "1.3.0",
"@cornerstonejs/codec-openjph": "2.4.7",
"@cornerstonejs/core": "4.22.3",
"@cornerstonejs/dicom-image-loader": "4.22.3",
"@cornerstonejs/core": "4.22.8",
"@cornerstonejs/dicom-image-loader": "4.22.8",
"@ohif/ui": "3.13.0-beta.74",
"cornerstone-math": "0.1.10",
"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
key={`empty-${indent}`}
className="h-2"
data-cy="data-row-detail-line-empty"
></div>
);
}
@ -190,6 +191,7 @@ const DataRowComponent = React.forwardRef<HTMLDivElement, DataRowProps>(
<div
key={cleanText}
className="whitespace-pre-wrap"
data-cy="data-row-detail-line"
>
{indentation}
<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 hiddenLines = details.slice(4);
return (
<Tooltip>
<TooltipTrigger asChild>
<div className="cursor-help">
<div
className="cursor-help"
data-cy={`data-row-details-${variant}`}
>
<div className="flex flex-col space-y-1">
{visibleLines.map((line, lineIndex) =>
renderDetailText(line, line.startsWith(' ') ? 1 : 0)
@ -418,12 +423,15 @@ const DataRowComponent = React.forwardRef<HTMLDivElement, DataRowProps>(
{/* Details Section */}
{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">
{details.primary?.length > 0 && renderDetails(details.primary)}
{details.primary?.length > 0 && renderDetails(details.primary, 'primary')}
{details.secondary?.length > 0 && (
<div className="text-muted-foreground ml-auto text-sm">
{renderDetails(details.secondary)}
{renderDetails(details.secondary, 'secondary')}
</div>
)}
</div>

View File

@ -107,26 +107,28 @@ const Row = ({ item, index }: RowProps) => {
const { uid } = item;
return (
<DataRow
key={item.uid}
description={item.label}
number={index + 1}
title={item.label}
colorHex={item.colorHex}
isSelected={item.isSelected}
details={item.displayText}
onDelete={e => onAction(e, 'removeMeasurement', uid)}
onSelect={e => onAction(e, 'jumpToMeasurement', uid)}
onRename={e => onAction(e, 'renameMeasurement', uid)}
onToggleVisibility={e => onAction(e, 'toggleVisibilityMeasurement', uid)}
onToggleLocked={e => onAction(e, 'toggleLockMeasurement', uid)}
onColor={e => onAction(e, 'changeMeasurementColor', uid)}
disableEditing={disableEditing}
isVisible={item.isVisible}
isLocked={item.isLocked}
>
{item.isUnmapped && <DataRow.Status.Warning tooltip={item.statusTooltip} />}
</DataRow>
<div data-cy={`measurement-table-row-${index}`}>
<DataRow
key={item.uid}
description={item.label}
number={index + 1}
title={item.label}
colorHex={item.colorHex}
isSelected={item.isSelected}
details={item.displayText}
onDelete={e => onAction(e, 'removeMeasurement', uid)}
onSelect={e => onAction(e, 'jumpToMeasurement', uid)}
onRename={e => onAction(e, 'renameMeasurement', uid)}
onToggleVisibility={e => onAction(e, 'toggleVisibilityMeasurement', uid)}
onToggleLocked={e => onAction(e, 'toggleLockMeasurement', uid)}
onColor={e => onAction(e, 'changeMeasurementColor', uid)}
disableEditing={disableEditing}
isVisible={item.isVisible}
isLocked={item.isLocked}
>
{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('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 attemptAction(() => reduce3DViewportSize(page), 10, 100);
@ -24,7 +28,7 @@ test.describe('3D four up Test', async () => {
await checkForScreenshot(
page,
page,
viewportPageObject.grid,
screenShotPaths.threeDFourUp.threeDFourUpDisplayedCorrectly
);
});

View File

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

View File

@ -15,14 +15,18 @@ test.beforeEach(async ({ page }) => {
});
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 attemptAction(() => reduce3DViewportSize(page), 10, 100);
await waitForViewportsRendered(page);
await checkForScreenshot(
page,
page,
viewportPageObject.grid,
screenShotPaths.threeDPrimary.threeDPrimaryDisplayedCorrectly
);
});

View File

@ -20,5 +20,10 @@ test('should display the angle tool', async ({
{ x: 550, y: 300 },
]);
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('should render Axial Primary correctly.', async ({ page, mainToolbarPageObject }) => {
test('should render Axial Primary correctly.', async ({
page,
mainToolbarPageObject,
viewportPageObject,
}) => {
await mainToolbarPageObject.layoutSelection.axialPrimary.click();
await checkForScreenshot(
page,
page,
viewportPageObject.grid,
screenShotPaths.axialPrimary.axialPrimaryDisplayedCorrectly
);
});

View File

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

View File

@ -19,5 +19,9 @@ test('should display the circle tool', async ({
{ x: 488, y: 247 },
]);
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 },
]);
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 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 checkForScreenshot({
page,
locator: page,
locator: viewportPageObject.grid,
screenshotPath: screenShotPaths.contextMenu.contextMenuNearBottomEdgeNotClipped,
});
});

View File

@ -19,5 +19,10 @@ test('should display the ellipse tool', async ({
{ x: 508, y: 281 },
]);
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);
});
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 checkForScreenshot(
page,
page,
viewportPageObject.grid,
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 }) => {
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();
}
});
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);
});
test('should invert the image', async ({ page, mainToolbarPageObject }) => {
test('should invert the image', async ({ page, mainToolbarPageObject, viewportPageObject }) => {
await mainToolbarPageObject.moreTools.invert.click();
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();
// 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
await page.evaluate(() => {
@ -78,11 +82,19 @@ test('should hydrate in MPR correctly', async ({
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 checkForScreenshot(page, page, screenShotPaths.jumpToMeasurementMPR.jumpToMeasurementStack);
await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.jumpToMeasurementMPR.jumpToMeasurementStack
);
await mainToolbarPageObject.layoutSelection.MPR.click();
@ -93,19 +105,27 @@ test('should hydrate in MPR correctly', async ({
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 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 checkForScreenshot(
page,
page,
viewportPageObject.grid,
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
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.
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 },
});
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 ({
@ -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
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.
await rightPanelPageObject.labelMapSegmentationPanel.tools.eraser.click();
@ -114,7 +126,7 @@ test('should allow editing of label map segmentations when panelSegmentation.dis
await checkForScreenshot(
page,
page,
viewportPageObject.grid,
screenShotPaths.labelMapSegLocking.globalUnlockedSegPostEdit
);
});

View File

@ -19,5 +19,10 @@ test('should display the length tool', async ({
{ x: 544, y: 232 },
]);
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';
test.beforeEach(async ({ page }) => {
@ -24,7 +31,23 @@ test('should display the livewire tool', async ({
{ x: 383, y: 461 },
]);
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 ({

View File

@ -7,8 +7,17 @@ test.beforeEach(async ({ page }) => {
});
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 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(
page,
page,
viewportPageObject.grid,
screenShotPaths.mprThenRTOverlayNoHydration.mprPreRTOverlayNoHydration
);
@ -48,6 +48,7 @@ test('should launch MPR with unhydrated RTSTRUCT chosen from the data overlay me
await checkForScreenshot({
page,
locator: viewportPageObject.grid,
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
});

View File

@ -21,7 +21,7 @@ test('should launch MPR with unhydrated SEG chosen from the data overlay menu',
await checkForScreenshot(
page,
page,
viewportPageObject.grid,
screenShotPaths.mprThenSEGOverlayNoHydration.mprPreSEGOverlayNoHydration
);
@ -42,7 +42,7 @@ test('should launch MPR with unhydrated SEG chosen from the data overlay menu',
await checkForScreenshot(
page,
page,
viewportPageObject.grid,
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
await rightPanelPageObject.measurementsPanel.select();
const measurementRow = rightPanelPageObject.measurementsPanel.panel.nthMeasurement(0).locator;
await expect(measurementRow).toContainText('(empty)');
const measurementRow = rightPanelPageObject.measurementsPanel.panel.nthMeasurement(0);
await expect(measurementRow.title).toHaveText('(empty)');
// Expand and click rename
await rightPanelPageObject.measurementsPanel.panel.nthMeasurement(0).actions.rename(relabelText);
// Check dialog closed and renamed
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 ({
@ -98,8 +98,8 @@ test('checks if measurement item can be relabeled through the context menu on th
// Open measurement panel confirm default empty
await rightPanelPageObject.measurementsPanel.select();
const measurementRow = rightPanelPageObject.measurementsPanel.panel.nthMeasurement(0).locator;
await expect(measurementRow).toContainText('(empty)');
const measurementRow = rightPanelPageObject.measurementsPanel.panel.nthMeasurement(0);
await expect(measurementRow.title).toHaveText('(empty)');
// Right click and click rename
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
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 ({

View File

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

View File

@ -16,5 +16,10 @@ test('should display the probe tool', async ({
const activeViewport = await viewportPageObject.active;
await activeViewport.clickAt([{ x: 550, y: 200 }]);
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,
viewportPageObject,
}) => {
const dataOverlayPageObject = (await viewportPageObject.getById('default')).overlayMenu.dataOverlay;
const dataOverlayPageObject = (await viewportPageObject.getById('default')).overlayMenu
.dataOverlay;
await dataOverlayPageObject.toggle();
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(
page,
page,
viewportPageObject.grid,
screenShotPaths.rtDataOverlayForUnreferencedDisplaySetNoHydration.overlayFirstImage
);
@ -37,7 +38,7 @@ test('should overlay an unhydrated RTSTRUCT over a display set that the RTSTRUCT
await checkForScreenshot(
page,
page,
viewportPageObject.grid,
screenShotPaths.rtDataOverlayForUnreferencedDisplaySetNoHydration.overlayMiddleImage
);
});

View File

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

View File

@ -11,17 +11,30 @@ test('should hydrate RT reports correctly', async ({
DOMOverlayPageObject,
leftPanelPageObject,
rightPanelPageObject,
viewportPageObject,
}) => {
await rightPanelPageObject.toggle();
await leftPanelPageObject.loadSeriesByModality('RTSTRUCT');
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 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 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,
leftPanelPageObject,
rightPanelPageObject,
viewportPageObject,
}) => {
await rightPanelPageObject.toggle();
await leftPanelPageObject.loadSeriesByModality('RTSTRUCT');
await checkForScreenshot(page, page, screenShotPaths.rtHydration2.rtPreHydration);
await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.rtHydration2.rtPreHydration
);
// wait for 3 seconds
await page.evaluate(() => {
// 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
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,
mainToolbarPageObject,
rightPanelPageObject,
viewportPageObject,
}) => {
await rightPanelPageObject.toggle();
@ -19,25 +20,37 @@ test('should hydrate an RTSTRUCT from MPR', async ({
await page.waitForTimeout(10000);
await checkForScreenshot(page, page, screenShotPaths.rtHydrationFromMPR.mprBeforeRT);
await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.rtHydrationFromMPR.mprBeforeRT
);
await leftPanelPageObject.loadSeriesByModality('RTSTRUCT');
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 page.waitForTimeout(5000);
await checkForScreenshot(page, page, screenShotPaths.rtHydrationFromMPR.mprAfterRTHydrated);
await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.rtHydrationFromMPR.mprAfterRTHydrated
);
await mainToolbarPageObject.layoutSelection.axialPrimary.click();
await checkForScreenshot(
page,
page,
viewportPageObject.grid,
screenShotPaths.rtHydrationFromMPR.mprAfterRTHydratedAfterLayoutChange
);
});

View File

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

View File

@ -11,17 +11,26 @@ test('should launch MPR with unhydrated RTSTRUCT', async ({
leftPanelPageObject,
mainToolbarPageObject,
rightPanelPageObject,
viewportPageObject,
}) => {
await rightPanelPageObject.toggle();
await leftPanelPageObject.loadSeriesByModality('RTSTRUCT');
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 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 },
]);
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);
});
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.invert.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);
});
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 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,
}) => {
await rightPanelPageObject.toggle();
const dataOverlayPageObject = (await viewportPageObject.getById('default')).overlayMenu.dataOverlay;
const dataOverlayPageObject = (await viewportPageObject.getById('default')).overlayMenu
.dataOverlay;
await dataOverlayPageObject.toggle();
await dataOverlayPageObject.addSegmentation('Segmentation');
@ -28,7 +29,7 @@ test('should launch MPR with unhydrated SEG chosen from the data overlay menu',
await checkForScreenshot(
page,
page,
viewportPageObject.grid,
screenShotPaths.segDataOverlayNoHydrationThenMPR.segDataOverlayNoHydrationPreMPR
);
@ -38,7 +39,7 @@ test('should launch MPR with unhydrated SEG chosen from the data overlay menu',
await checkForScreenshot(
page,
page,
viewportPageObject.grid,
screenShotPaths.segDataOverlayNoHydrationThenMPR.segDataOverlayNoHydrationPostMPR
);

View File

@ -11,12 +11,17 @@ test('should hydrate SEG reports correctly', async ({
DOMOverlayPageObject,
leftPanelPageObject,
rightPanelPageObject,
viewportPageObject,
}) => {
await rightPanelPageObject.toggle();
await leftPanelPageObject.loadSeriesByDescription('SEG');
await page.waitForTimeout(5000);
await checkForScreenshot(page, page, screenShotPaths.segHydration.segPreHydration);
await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.segHydration.segPreHydration
);
await page.evaluate(() => {
// 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 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
);
let viewportRenderCycle = waitForViewportRenderCycle(page);
await leftPanelPageObject.loadSeriesByDescription('SEG');
await waitForViewportsRendered(page);
await viewportRenderCycle;
await checkForScreenshot(
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),
// 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();

View File

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

View File

@ -11,17 +11,26 @@ test('should launch MPR with unhydrated SEG', async ({
leftPanelPageObject,
mainToolbarPageObject,
rightPanelPageObject,
viewportPageObject,
}) => {
await rightPanelPageObject.toggle();
await leftPanelPageObject.loadSeriesByDescription('SEG');
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 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,
leftPanelPageObject,
rightPanelPageObject,
viewportPageObject,
}) => {
await rightPanelPageObject.toggle();
await rightPanelPageObject.measurementsPanel.select();
await leftPanelPageObject.loadSeriesByModality('SR');
await page.waitForTimeout(2000);
await checkForScreenshot(page, page, screenShotPaths.srHydration.srPreHydration);
await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.srHydration.srPreHydration
);
await page.evaluate(() => {
// 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 page.waitForTimeout(2000);
await checkForScreenshot(page, page, screenShotPaths.srHydration.srPostHydration);
await checkForScreenshot(
page,
viewportPageObject.grid,
screenShotPaths.srHydration.srPostHydration
);
await page.evaluate(() => {
// 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 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';
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 }) => {
const studyInstanceUID = '1.3.6.1.4.1.14519.5.2.1.7310.5101.860473186348887719777907797922';
const mode = 'viewer';
@ -92,19 +101,13 @@ test('should hydrate SCOORD3D probe measurements correctly', async ({
);
// Verify the measurements list has the correct probe measurements
const measurementRows = page.getByTestId('data-row');
const rowCount = await measurementRows.count();
expect(await rightPanelPageObject.measurementsPanel.panel.getMeasurementCount()).toBeGreaterThan(
0
);
expect(await rightPanelPageObject.measurementsPanel.panel.rows).not.toHaveCount(0);
const rowCount = await rightPanelPageObject.measurementsPanel.panel.getMeasurementCount();
// Verify that the measurements are probe measurements (not other types)
for (let i = 0; i < rowCount; i++) {
const measurementText = await rightPanelPageObject.measurementsPanel.panel
.nthMeasurement(i)
.locator.textContent();
// Probe measurements should be present, verify they're not other measurement types
expect(measurementText).toBeTruthy();
const measurement = rightPanelPageObject.measurementsPanel.panel.nthMeasurement(i);
await expect(measurement.title).not.toBeEmpty();
await expectNonEmptyDetailLines(measurement.stats.primary.lines);
}
// 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)
for (let i = 0; i < rowCount; i++) {
const measurementText = await rightPanelPageObject.measurementsPanel.panel
.nthMeasurement(i)
.locator.textContent();
// Probe measurements should be present, verify they're not other measurement types
expect(measurementText).toBeTruthy();
const measurement = rightPanelPageObject.measurementsPanel.panel.nthMeasurement(i);
await expect(measurement.title).not.toBeEmpty();
await expectNonEmptyDetailLines(measurement.stats.primary.lines);
}
});

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 }) => {
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();
expect(rowCount).toBeGreaterThan(0);
// Verify that the measurements are rectangle measurements (not other types)
for (let i = 0; i < rowCount; i++) {
const measurementText = await rightPanelPageObject.measurementsPanel.panel
.nthMeasurement(i)
.locator.textContent();
// Rectangle measurements should be present, verify they're not other measurement types
expect(measurementText).toBeTruthy();
const measurement = rightPanelPageObject.measurementsPanel.panel.nthMeasurement(i);
await expect(measurement.title).not.toBeEmpty();
await expectNonEmptyDetailLines(measurement.stats.primary.lines);
await expectNonEmptyDetailLines(measurement.stats.secondary.lines);
}
// 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();
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++) {
const measurementText = await rightPanelPageObject.measurementsPanel.panel
.nthMeasurement(i)
.locator.textContent();
// Rectangle measurements should be present, verify they're not other measurement types
expect(measurementText).toBeTruthy();
const measurement = rightPanelPageObject.measurementsPanel.panel.nthMeasurement(i);
await expect(measurement.title).not.toBeEmpty();
await expectNonEmptyDetailLines(measurement.stats.primary.lines);
await expectNonEmptyDetailLines(measurement.stats.secondary.lines);
}
});

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';
test.beforeEach(async ({ page }) => {
@ -24,7 +31,22 @@ test('should display the spline tool', async ({
{ x: 383, y: 461 },
]);
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 ({

View File

@ -112,30 +112,58 @@ export class RightPanelPageObject {
get measurementsPanel() {
const page = this.page;
const getMeasurementByIdx = (index: number) => this.getPanelRowByIdx(index);
const getMeasurementByText = (text: string) => this.getPanelRowByText(text);
const menuButton = page.getByTestId('trackedMeasurements-btn');
const trackedMeasurementsPanel = page.getByTestId('trackedMeasurements-panel').last();
const measurementTableRows = trackedMeasurementsPanel.locator(
'[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 {
menuButton,
panel: {
deleteAll: async () => {
await page.getByRole('button', { name: 'Delete' }).click();
},
getMeasurementCount: async () => {
return await page.getByTestId('data-row').count();
return await measurementTableRows.count();
},
rows: page.getByTestId('data-row'),
locator: page.getByTestId('trackedMeasurements-panel').last(),
rows: measurementTableRows,
locator: trackedMeasurementsPanel,
nthMeasurement(index: number) {
return getMeasurementByIdx(index);
},
measurementByText(text: string) {
return getMeasurementByText(text);
return getMeasurementDataRowAt(index);
},
},
select: async () => {
await menuButton.click();
await trackedMeasurementsMenu.click();
},
};
}
@ -414,7 +442,6 @@ export class RightPanelPageObject {
get microscopyPanel() {
const page = this.page;
const getMeasurementByIdx = (index: number) => this.getPanelRowByIdx(index);
const getMeasurementByText = (text: string) => this.getPanelRowByText(text);
return {
locator: page.getByTestId('measurements-panel'),
@ -424,9 +451,6 @@ export class RightPanelPageObject {
nthMeasurement(index: number) {
return getMeasurementByIdx(index);
},
measurementByText(text: string) {
return getMeasurementByText(text);
},
};
}
}

View File

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