Compare commits

..
Author SHA1 Message Date
ohif-bot 1a8db3b8c6 chore(version): Update package versions [skip ci] 2026-06-05 12:56:28 +00:00
ohif-bot ac3ff44a56 chore(version): version.json [skip ci] 2026-06-05 12:56:20 +00:00
Joe Boccanfuso 62917c2142 fix(security): Update axios to fix security vulnerabilities. Release 3.12.4 (#6064) 2026-06-05 08:45:52 -04:00
ohif-bot c31db6513b chore(version): Update package versions [skip ci] 2026-05-27 14:55:54 +00:00
ohif-bot c1d9d23f78 chore(version): version.json [skip ci] 2026-05-27 14:55:44 +00:00
Joe Boccanfuso fb4441ba71 fix(security): Add tmp as a resolution to fix security vulnerability. Trigger release 3.12.3. (#6045) 2026-05-27 10:44:11 -04:00
ohif-bot db16341a4f chore(version): Update package versions [skip ci] 2026-05-18 13:39:27 +00:00
ohif-bot 0fcf3a9dc1 chore(version): version.json [skip ci] 2026-05-18 13:39:19 +00:00
Joe Boccanfuso 75a24a3393 fix(security): Update various dependencies to fix security vulnerabilities. Release 3.12.2 (#6024) 2026-05-18 09:32:40 -04:00
ohif-bot 104de8d833 chore(version): version.json [skip ci] 2026-05-08 18:51:36 +00:00
Alireza 647fd025cf fix(release): make publish-version.mjs idempotent for re-runs
Skip the peer-dep commit when nothing is staged and skip the lerna
version step when the workspace is already at the target version.
Allows the release pipeline to be re-triggered after a partial run.
2026-05-08 14:42:57 -04:00
Alireza 3fc8706126 chore(version): Update package versions [skip ci] 2026-05-08 14:37:54 -04:00
ohif-bot 539ff44f47 chore(version): version.json [skip ci] 2026-05-07 23:52:54 +00:00
Joe Boccanfuso 146897f216 chore: release 3.12.1 (#6003) 2026-05-07 19:45:13 -04:00
Joe Boccanfuso a264413124 fix(security): Patch axios security vulnerabilities. (#5997)
Patch axios security vulnerabilities.
2026-05-06 13:37:37 -04:00
Joe Boccanfuso 838f51957e fix(configuration): Harden dynamic datasource URL trust boundaries and credential handling. 3.12 (#5978) 2026-04-29 14:38:55 -04:00
Joe Boccanfuso bab20143fd fix(security): Update axios and protobufjs to fix security vulnerabilities. (#5975) 2026-04-23 14:15:16 -04:00
Joe Boccanfuso 946735bf90 fix(security):Update yarn.lock that was missed in PR #5937. (#5939) 2026-04-03 13:16:47 -04:00
Joe Boccanfuso a5be4c3dce fix(security): update dependencies to fix security vulnerabilities (#5937) 2026-04-02 18:06:35 -04:00
Joe Boccanfuso 171ea857cf fix(security): Bump flattened version to address CVE-2026-32141 for release 3.12 (#5898) 2026-03-13 15:25:55 -04:00
Joe Boccanfuso 9754fc1e92 fix(security): Bump tar version to address CVE-2026-31802 in release/3.12 (#5896) 2026-03-13 08:49:13 -04:00
Joe Boccanfuso 6772deb4c6 fix(security): Bump svgo and tar to fix vulnerabilities in release 3.12 (#5881) 2026-03-06 08:26:16 -05:00
Joe Boccanfuso 1d0a8744b2 fix(security): Address various security vulnerabilities in the release/3.12 branch (#5872) 2026-03-04 14:54:17 -05:00
Joe Boccanfuso 555c87f1c5 chore(security): Updates for running bun audit during CI and dependabot PR version update settings (#5836)
chore(security): Update circleci config to only run bun audit for lockfile changes.

Disabled all dependabot pull requests for bun and npm version updates.
2026-02-23 16:26:49 -05:00
Joe Boccanfuso 51d267e707 fix(security): CVE-2026-27212 and CVE-2026-26996 addressed for release/3.12 (#5831)
* fix(security):  CVE-2026-27212 patched.
Various dependency updates as a result of CVE-2026-26996.
Ultimately CVE-2026-26996 was ignored because it is only exposed in itk-wasm via CLI and OHIF's other use of minimatch is limited to build/dev environments.

* Switched to eslint 9.39.3 for compatibility with .eslintrc.json.
2026-02-23 14:51:42 -05:00
Joe Boccanfuso c5c18f9516 fix(security): Bump tar to 7.5.9 and lerna to 9.0.4 to fix CVE-2026-26960. (#5825)
* fix(security): Bump tar to 7.5.9 and lerna to 9.0.4 to fix CVE-2026-26960.
Bump sharp to 0.34.5 to fix tar-fs vulnerabilities.

* Update node version to 20.19.0 in circleci config. Needed for lerna and cypress tests.

* Now installing bun for cypress tests in circleci config.

* Use node version 20.19.0 in netlify config.
2026-02-18 16:52:57 -05:00
Joe Boccanfuso 213a0974bb chore(deps): bump webpack from 5.95.0 to 5.105.0 to address CVE-2025-68458 and CVE-2025-68157 (#5822) 2026-02-18 12:31:13 -05:00
0d882a425d fix: Better handle octet stream case (#5789) (#5804)
* Better handle octet stream case

* Use data source config stack options

* Use immutability helper

---------

Co-authored-by: Igor Octaviano <igoroctaviano@gmail.com>
Co-authored-by: Bill Wallace <wayfarer3130@gmail.com>
2026-02-13 12:04:05 -05:00
Joe Boccanfuso 49ea3ac82b chore(deps): bump diff to 5.2.2 to path CVE-2026-24001 (#5812) 2026-02-11 09:39:32 -05:00
Joe Boccanfuso 99736b6437 chore(deps): bump lodash and lodash-es from 4.17.21 to 4.17.23 to address CVE-2025-13465 (#5803) 2026-02-10 14:28:08 -05:00
Joe Boccanfuso 7fb67d2396 fix(security): Use a resolution for axios to address CVE-2026-25639. (#5794) 2026-02-09 16:44:12 -05:00
ohif-bot 04b121c1ba chore(version): Update package versions [skip ci] 2026-02-06 17:45:00 +00:00
ohif-bot 9782980a7a chore(version): version.json [skip ci] 2026-02-06 17:44:53 +00:00
Joe Boccanfuso 27b1afe040 chore: release 3.12.0 2026-02-06 10:03:53 -05:00
417 changed files with 3054 additions and 26763 deletions

No files matched your search

+56 -67
View File
@@ -112,6 +112,62 @@ jobs:
- checkout
- attach_workspace:
at: ~/repo
# SECURITY AUDIT - only when bun.lock has changed
- run:
name: 'Security Audit - High Risk Vulnerabilities'
command: |
git fetch origin master 2>/dev/null || true
BASE_REF=$(git merge-base HEAD origin/master 2>/dev/null)
if [[ -z "$BASE_REF" ]]; then
echo "Could not determine base ref (e.g. shallow clone or no origin/master), skipping security audit."
exit 0
fi
CHANGED_FILES=$(git diff --name-only origin/master...HEAD 2>/dev/null || echo "")
if ! echo "$CHANGED_FILES" | grep -qx 'bun.lock'; then
echo "⏭️ bun.lock unchanged - skipping security audit."
exit 0
fi
echo "🔍 bun.lock changed - running bun audit for security vulnerabilities..."
echo "Checking for HIGH-RISK vulnerabilities..."
# Define ignored vulnerabilities with comments
IGNORED_VULNS=(
"GHSA-3ppc-4f35-3m26" # CVE-2026-26996 - minimatch via itk-wasm and glob is safe because it does NOT use the CLI
# CVE-2026-26996 - minimatch via other packages are strictly for building and CI/CD purposes; no user supplied expressions are passed to minimatch
"GHSA-7r86-cg39-jmmj" # CVE-2026-27903 - minimatch same as above
"GHSA-23c5-xmqv-rm74" # CVE-2026-27904 - minimatch same as above
"GHSA-c2c7-rcm5-vvqj" # CVE-2026-33671 - picomatch is generally used for development and CI/CD purposes
)
# Build ignore flags
IGNORE_FLAGS=""
for vuln in "${IGNORED_VULNS[@]}"; do
IGNORE_FLAGS="$IGNORE_FLAGS --ignore=$vuln"
done
if bun audit $IGNORE_FLAGS --audit-level high; then
echo "✅ No high-risk vulnerabilities found"
echo "🎉 Security audit passed!"
else
echo ""
echo "❌ HIGH-RISK VULNERABILITIES DETECTED!"
echo "======================================"
echo ""
echo "🔧 To fix these issues:"
echo " 1. Run: bun audit"
echo " 2. Review the vulnerability details"
echo " 3. Update affected packages to secure versions"
echo " 4. Test your changes"
echo " 5. Re-run: bun audit --audit-level high"
echo ""
echo "📋 Full audit report:"
bun audit $IGNORE_FLAGS --audit-level low || true
echo ""
echo "❌ This build cannot proceed until high-risk vulnerabilities are resolved."
exit 1
fi
- run:
name: Install Dependencies
command: bun install --frozen-lockfile
@@ -350,69 +406,6 @@ jobs:
npx wait-on@latest http://localhost:3000 && cd platform/app && npx cypress run --record --parallel
start-command: yarn run test:data && yarn run test:e2e:serve
SECURITY_AUDIT:
<<: *defaults
resource_class: large
steps:
- install_bun
- checkout
- run:
name: 'Security Audit - High Risk Vulnerabilities'
command: |
git fetch origin master 2>/dev/null || true
BASE_REF=$(git merge-base HEAD origin/master 2>/dev/null)
if [[ -z "$BASE_REF" ]]; then
echo "Could not determine base ref (e.g. shallow clone or no origin/master), skipping security audit."
exit 0
fi
CHANGED_FILES=$(git diff --name-only origin/master...HEAD 2>/dev/null || echo "")
if ! echo "$CHANGED_FILES" | grep -qx 'bun.lock'; then
echo "⏭️ bun.lock unchanged - skipping security audit."
exit 0
fi
echo "🔍 bun.lock changed - running bun audit for security vulnerabilities..."
echo "Checking for HIGH-RISK vulnerabilities..."
# Define ignored vulnerabilities with comments
IGNORED_VULNS=(
"GHSA-3ppc-4f35-3m26" # CVE-2026-26996 - minimatch via itk-wasm and glob is safe because it does NOT use the CLI
# CVE-2026-26996 - minimatch via other packages are strictly for building and CI/CD purposes; no user supplied expressions are passed to minimatch
"GHSA-7r86-cg39-jmmj" # CVE-2026-27903 - minimatch same as above
"GHSA-23c5-xmqv-rm74" # CVE-2026-27904 - minimatch same as above
"GHSA-c2c7-rcm5-vvqj" # CVE-2026-33671 - picomatch is generally used for development and CI/CD purposes
)
# Build ignore flags
IGNORE_FLAGS=""
for vuln in "${IGNORED_VULNS[@]}"; do
IGNORE_FLAGS="$IGNORE_FLAGS --ignore=$vuln"
done
if bun audit $IGNORE_FLAGS --audit-level high; then
echo "✅ No high-risk vulnerabilities found"
echo "🎉 Security audit passed!"
exit 0
else
echo ""
echo "❌ HIGH-RISK VULNERABILITIES DETECTED!"
echo "======================================"
echo ""
echo "🔧 To fix these issues:"
echo " 1. Run: bun audit"
echo " 2. Review the vulnerability details"
echo " 3. Update affected packages to secure versions"
echo " 4. Test your changes"
echo " 5. Re-run: bun audit --audit-level high"
echo ""
echo "📋 Full audit report:"
bun audit $IGNORE_FLAGS --audit-level low || true
echo ""
echo "❌ This build cannot proceed until high-risk vulnerabilities are resolved."
exit 1
fi
DOCKER_MULTIARCH_MANIFEST:
<<: *defaults
resource_class: large
@@ -502,10 +495,6 @@ workflows:
- CYPRESS:
name: 'Cypress Tests'
context: cypress
- SECURITY_AUDIT:
filters:
branches:
ignore: master
# viewer-dev.ohif.org
DEPLOY_MASTER:
+1 -152
View File
@@ -2,19 +2,6 @@ name: Playwright Tests
on:
pull_request:
branches: [master, release/*]
workflow_dispatch:
inputs:
cs3d_ref:
description: >-
CS3D branch (e.g. main, origin:feat/foo) or version (e.g. 4.18.2, 4.19+, 4.x). Only used
when ohif-integration label is present or via workflow_dispatch.
required: false
default: '4.19+'
permissions:
contents: read
pull-requests: read
issues: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
@@ -22,7 +9,7 @@ concurrency:
jobs:
playwright-tests:
timeout-minutes: 120
timeout-minutes: 60
runs-on: self-hosted
strategy:
fail-fast: false
@@ -38,85 +25,14 @@ jobs:
node-version: ${{ matrix.node-version }}
- name: Install Yarn
run: npm install -g yarn@1.22.22
# ── CS3D integration: detect label and ref type ──────────────────────
- name: Check for CS3D integration label
id: cs3d-check
run: bash .scripts/ci/cs3d-check-integration.sh
env:
GH_TOKEN: ${{ github.token }}
EVENT_NAME: ${{ github.event_name }}
CS3D_REF_INPUT: ${{ github.event.inputs.cs3d_ref || '4.19+' }}
REPO: ${{ github.repository }}
PR_NUMBER: ${{ github.event.pull_request.number }}
- name: Detect CS3D ref type
id: cs3d-ref
if: steps.cs3d-check.outputs.enabled == 'true'
run: |
REF="${CS3D_REF}"
if [[ "$REF" =~ ^[0-9]+\.[0-9x]+\+?(\.[0-9x]+)?(-[a-zA-Z0-9._]+)?$ ]]; then
echo "type=version" >> "$GITHUB_OUTPUT"
RESOLVED=$(node .scripts/cs3d-resolve-version.mjs "$REF")
echo "version=$RESOLVED" >> "$GITHUB_OUTPUT"
echo "::notice::CS3D version: $REF -> $RESOLVED"
else
echo "type=branch" >> "$GITHUB_OUTPUT"
echo "::notice::CS3D branch: $REF"
fi
env:
CS3D_REF: ${{ steps.cs3d-check.outputs.cs3d_ref }}
# ── CS3D branch path: clone and build before OHIF install ───────────
- name: Clone CS3D
if: steps.cs3d-check.outputs.enabled == 'true' && steps.cs3d-ref.outputs.type == 'branch'
run: |
REF="${CS3D_REF}"
if [[ "$REF" == *:* ]]; then
REPO="https://github.com/${REF%%:*}/cornerstone3D.git"
BRANCH="${REF#*:}"
else
REPO="https://github.com/cornerstonejs/cornerstone3D.git"
BRANCH="$REF"
fi
echo "::notice::Cloning CS3D from $REPO branch $BRANCH"
git clone --depth 1 --branch "$BRANCH" "$REPO" libs/@cornerstonejs
env:
CS3D_REF: ${{ steps.cs3d-check.outputs.cs3d_ref }}
- name: Install & Build CS3D
if: steps.cs3d-check.outputs.enabled == 'true' && steps.cs3d-ref.outputs.type == 'branch'
working-directory: libs/@cornerstonejs
run: bun install --frozen-lockfile && bun run build:esm
# ── Common: install OHIF dependencies ───────────────────────────────
- name: Install dependencies
run: bun install --frozen-lockfile
# ── CS3D branch path: link packages after OHIF install ──────────────
- name: Link CS3D packages
if: steps.cs3d-check.outputs.enabled == 'true' && steps.cs3d-ref.outputs.type == 'branch'
working-directory: libs/@cornerstonejs
run: node scripts/link-ohif-cornerstone-node-modules.mjs "$GITHUB_WORKSPACE"
# ── CS3D version path: update versions after OHIF install ───────────
- name: Set CS3D version
if: steps.cs3d-check.outputs.enabled == 'true' && steps.cs3d-ref.outputs.type == 'version'
run: |
node .scripts/cs3d-set-version.mjs "${CS3D_VERSION}"
bun install --config=./bunfig.update-lockfile.toml
env:
CS3D_VERSION: ${{ steps.cs3d-ref.outputs.version }}
# ── Common: run tests ───────────────────────────────────────────────
- name: Install Playwright browsers
run: npx playwright install
- name: Run Playwright tests
run: |
export NODE_OPTIONS="--max_old_space_size=10192"
bun run test:e2e:coverage
# ── Common: collect test results and coverage ───────────────────────
- name: Create directory of test results
if: ${{ !cancelled() }}
run: |
@@ -140,70 +56,3 @@ jobs:
name: coverage-report-pr
path: coverage
retention-days: 3
# ── CS3D: build and deploy preview to Netlify ───────────────────────
- name: Log build context (OHIF/CS3D branch and version for build diagnosis)
if: steps.cs3d-check.outputs.enabled == 'true'
run: |
if [[ "$CS3D_REF_TYPE" == "branch" ]]; then
echo "::notice::Build type: ohif-downstream | OHIF: ${{ github.repository }}@${{ github.ref }} (${{ github.sha }}) | CS3D: branch ${{ steps.cs3d-check.outputs.cs3d_ref }}"
else
echo "::notice::Build type: ohif-upstream | OHIF: ${{ github.repository }}@${{ github.ref }} (${{ github.sha }}) | CS3D: version ${{ steps.cs3d-ref.outputs.version }}"
fi
node .scripts/log-build-context.mjs
env:
BUILD_TYPE: ${{ steps.cs3d-ref.outputs.type == 'branch' && 'ohif-downstream' || 'ohif-upstream' }}
CS3D_REF_TYPE: ${{ steps.cs3d-ref.outputs.type }}
- name: Build OHIF viewer (CS3D preview)
if: steps.cs3d-check.outputs.enabled == 'true'
run: bun run build:ci
- name: Deploy CS3D preview to Netlify
if: steps.cs3d-check.outputs.enabled == 'true'
run: |
RESULT=$(npx netlify-cli deploy --dir=platform/app/dist --alias="cs3d-pr-${PR_NUM}" --json --filter=@ohif/app) || {
echo "::error::Netlify deploy command failed"
exit 1
}
URL=$(echo "$RESULT" | jq -r '.deploy_url')
if [[ -z "$URL" || "$URL" == "null" ]]; then
echo "::error::Netlify deploy did not return a valid URL"
echo "$RESULT"
exit 1
fi
echo "::notice::CS3D preview deployed: $URL"
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
PR_NUM: ${{ github.event.pull_request.number || 'manual' }}
# ── CS3D: log results ───────────────────────────────────────────────
- name: Log CS3D build used
if: steps.cs3d-check.outputs.enabled == 'true'
run: |
if [[ "$CS3D_REF_TYPE" == "branch" ]]; then
echo "::notice::CS3D integration PASSED with branch ${CS3D_REF} (linked from libs/@cornerstonejs)"
else
echo "::notice::CS3D integration PASSED with @cornerstonejs/*@${CS3D_VERSION}"
fi
env:
CS3D_REF_TYPE: ${{ steps.cs3d-ref.outputs.type }}
CS3D_REF: ${{ steps.cs3d-check.outputs.cs3d_ref }}
CS3D_VERSION: ${{ steps.cs3d-ref.outputs.version }}
# ── Separate job: block merge when using a CS3D branch ─────────────
cs3d-branch-merge-guard:
name: "CS3D Branch Merge Guard"
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v4
- name: Check for CS3D branch usage
run: bash .scripts/ci/cs3d-branch-merge-guard.sh
env:
GH_TOKEN: ${{ github.token }}
EVENT_NAME: ${{ github.event_name }}
CS3D_REF_INPUT: ${{ github.event.inputs.cs3d_ref || '4.19+' }}
REPO: ${{ github.repository }}
PR_NUMBER: ${{ github.event.pull_request.number }}
-9
View File
@@ -61,14 +61,5 @@ tests/playwright-report/
**/.claude/settings.local.json
# cornerstone3D local linking
libs/
# Backup files
*~
# cornerstone3D local linking
libs/
link-cs3d.js
unlink-cs3d.js
auth.json
-42
View File
@@ -1,42 +0,0 @@
#!/usr/bin/env bash
# CS3D branch merge guard: blocks merge when tests ran against a CS3D branch (not a version).
# Exits 0 when merge is allowed or guard is skipped; exits 1 when merge must be blocked.
#
# Required env: GH_TOKEN, EVENT_NAME, REPO, PR_NUMBER
# Optional env: CS3D_REF_INPUT (for workflow_dispatch, default 4.19+)
set -e
if [[ "$EVENT_NAME" == "workflow_dispatch" ]]; then
echo "::notice::workflow_dispatch — no merge to block, skipping guard."
exit 0
elif [[ "$EVENT_NAME" == "pull_request" ]]; then
LABELS=$(gh api "repos/${REPO}/issues/${PR_NUMBER}/labels" --jq '.[].name')
if echo "$LABELS" | grep -q "ohif-integration"; then
ENABLED=true
CS3D_REF=$(gh api "repos/${REPO}/pulls/${PR_NUMBER}" --jq '.body' \
| sed -n 's/^[[:space:]]*CS3D_REF:[[:space:]]*\([^[:space:]]*\).*/\1/p' | head -1)
if [[ -z "$CS3D_REF" ]]; then
CS3D_REF="4.19+"
fi
else
ENABLED=false
fi
else
ENABLED=false
fi
if [[ "$ENABLED" != "true" ]]; then
echo "::notice::No ohif-integration label — skipping merge guard."
exit 0
fi
# Check if the ref is a branch (not a version)
if [[ "$CS3D_REF" =~ ^[0-9]+\.[0-9x]+\+?(\.[0-9x]+)?(-[a-zA-Z0-9._]+)?$ ]]; then
echo "::notice::CS3D ref '$CS3D_REF' is a version — merge allowed."
exit 0
fi
echo "::error::Tests ran against CS3D branch '${CS3D_REF}' — this build cannot be merged."
echo "::error::Re-run with a published CS3D version (e.g. 4.19+) before merging."
exit 1
-29
View File
@@ -1,29 +0,0 @@
#!/usr/bin/env bash
# CS3D integration check: detects ohif-integration label and parses CS3D_REF.
# Writes to GITHUB_OUTPUT: enabled (true|false), cs3d_ref (when enabled).
#
# Required env: GH_TOKEN, EVENT_NAME, REPO, PR_NUMBER, GITHUB_OUTPUT
# Optional env: CS3D_REF_INPUT (for workflow_dispatch, default 4.19+)
set -e
if [[ "$EVENT_NAME" == "workflow_dispatch" ]]; then
echo "enabled=true" >> "$GITHUB_OUTPUT"
echo "cs3d_ref=${CS3D_REF_INPUT:-4.19+}" >> "$GITHUB_OUTPUT"
elif [[ "$EVENT_NAME" == "pull_request" ]]; then
LABELS=$(gh api "repos/${REPO}/issues/${PR_NUMBER}/labels" --jq '.[].name')
if echo "$LABELS" | grep -q "ohif-integration"; then
echo "enabled=true" >> "$GITHUB_OUTPUT"
REF=$(gh api "repos/${REPO}/pulls/${PR_NUMBER}" --jq '.body' \
| sed -n 's/^[[:space:]]*CS3D_REF:[[:space:]]*\([^[:space:]]*\).*/\1/p' | head -1)
if [[ -z "$REF" ]]; then
REF="4.19+"
fi
echo "cs3d_ref=${REF}" >> "$GITHUB_OUTPUT"
echo "::notice::CS3D ref from PR body: ${REF}"
else
echo "enabled=false" >> "$GITHUB_OUTPUT"
fi
else
echo "enabled=false" >> "$GITHUB_OUTPUT"
fi
-55
View File
@@ -1,55 +0,0 @@
import fs from 'node:fs';
import path from 'node:path';
import { execSync } from 'node:child_process';
const workflowPath = path.resolve(
process.cwd(),
'libs',
'@cornerstonejs',
'.github',
'workflows',
'ohif-downstream.yml'
);
if (!fs.existsSync(workflowPath)) {
console.error(`[cs3d:check] Workflow file not found: ${workflowPath}`);
process.exit(1);
}
const workflowText = fs.readFileSync(workflowPath, 'utf8');
const ohifRefMatch = workflowText.match(/^\s*OHIF_REF:\s*["']?([^"'\r\n]+)["']?\s*$/m);
if (!ohifRefMatch) {
console.error('[cs3d:check] Could not find OHIF_REF in ohif-downstream workflow.');
process.exit(1);
}
const expectedBranch = ohifRefMatch[1].trim();
let currentBranch = '';
try {
currentBranch = execSync('git rev-parse --abbrev-ref HEAD', {
cwd: process.cwd(),
encoding: 'utf8',
}).trim();
} catch (error) {
console.error('[cs3d:check] Failed to determine current git branch.');
process.exit(1);
}
if (currentBranch !== expectedBranch) {
console.error(
`[cs3d:check] Branch mismatch: current='${currentBranch}', expected='${expectedBranch}' from ${path.relative(
process.cwd(),
workflowPath
)}`
);
process.exit(1);
}
console.log(
`[cs3d:check] OK: current branch '${currentBranch}' matches OHIF_REF in ${path.relative(
process.cwd(),
workflowPath
)}`
);
-63
View File
@@ -1,63 +0,0 @@
#!/usr/bin/env node
/**
* Resolves a version pattern to a concrete npm version of @cornerstonejs/core.
*
* Patterns:
* 4.18.2 -> 4.18.2 (exact, returned as-is)
* 4.18.2-beta.3 -> 4.18.2-beta.3 (exact prerelease)
* 4.x -> latest 4.* from npm
* 4.17.x -> latest 4.17.* from npm
* 4.19+ -> latest >=4.19.0 <5.0.0-0 from npm (4.19 and later, same major)
*
* Prints the resolved version to stdout.
*/
import { execSync } from 'child_process';
const pattern = process.argv[2];
if (!pattern) {
console.error('Usage: cs3d-resolve-version.mjs <pattern>');
console.error(' e.g. 4.x, 4.17.x, 4.19+, 4.18.2, 4.18.2-beta.3');
process.exit(1);
}
// Exact version (no wildcard or range) — pass through unchanged
if (!pattern.includes('x') && !pattern.endsWith('+')) {
console.log(pattern);
process.exit(0);
}
// Convert "M.m+" to npm semver range ">=M.m.0 <(M+1).0.0-0"
let npmRange = pattern;
const plusMatch = pattern.match(/^(\d+)\.(\d+)\+$/);
if (plusMatch) {
const major = Number(plusMatch[1]);
const minor = Number(plusMatch[2]);
npmRange = `>=${major}.${minor}.0 <${major + 1}.0.0-0`;
}
try {
// Let npm resolve the range: @package@<range> → concrete version
const raw = execSync(`npm view @cornerstonejs/core@"${npmRange}" version --json`, {
encoding: 'utf8',
timeout: 30_000,
});
const resolved = JSON.parse(raw);
if (!resolved) {
console.error(`npm returned no version when resolving @cornerstonejs/core@${npmRange}`);
process.exit(1);
}
// npm may return an array of versions for ranges; pick the latest (last) one
const version = Array.isArray(resolved) ? resolved[resolved.length - 1] : resolved;
console.log(version);
} catch (err) {
const message =
(err && (err.stderr?.toString() || err.message || String(err))) ||
`Unknown error resolving @cornerstonejs/core@${pattern}`;
console.error(`Failed to resolve @cornerstonejs/core version for pattern "${pattern}":`);
console.error(message);
process.exit(1);
}
-130
View File
@@ -1,130 +0,0 @@
#!/usr/bin/env node
/**
* Updates all @cornerstonejs/* package versions across the OHIF workspace.
*
* Usage: node .scripts/cs3d-set-version.mjs <version>
*
* Only updates the 8 main CS3D packages (not codec packages):
* adapters, ai, core, dicom-image-loader, labelmap-interpolation,
* nifti-volume-loader, polymorphic-segmentation, tools
*/
import { readFileSync, writeFileSync, existsSync, readdirSync } from 'fs';
import { resolve, dirname, join } from 'path';
import { fileURLToPath } from 'url';
const __dirname = dirname(fileURLToPath(import.meta.url));
const rootDir = resolve(__dirname, '..');
const version = process.argv[2];
if (!version) {
console.error('Usage: cs3d-set-version.mjs <version>');
console.error(' e.g. 4.18.2, 4.19.0-beta.1');
process.exit(1);
}
// The 8 CS3D packages that are built from source (not codecs)
const CS3D_PACKAGES = [
'@cornerstonejs/adapters',
'@cornerstonejs/ai',
'@cornerstonejs/core',
'@cornerstonejs/dicom-image-loader',
'@cornerstonejs/labelmap-interpolation',
'@cornerstonejs/nifti-volume-loader',
'@cornerstonejs/polymorphic-segmentation',
'@cornerstonejs/tools',
];
// Read root package.json to get workspace globs
const rootPkgPath = resolve(rootDir, 'package.json');
const rootPkg = JSON.parse(readFileSync(rootPkgPath, 'utf8'));
const workspaceGlobs = rootPkg.workspaces?.packages || rootPkg.workspaces || [];
// Collect all package.json paths from workspace globs
function findWorkspacePackageJsons() {
const paths = [rootPkgPath]; // include root
for (const pattern of workspaceGlobs) {
const parts = pattern.split('/');
let searchDir = rootDir;
let hasWildcard = false;
for (const part of parts) {
if (part === '*') {
hasWildcard = true;
break;
}
searchDir = join(searchDir, part);
}
if (hasWildcard) {
try {
const entries = readdirSync(searchDir, { withFileTypes: true });
for (const entry of entries) {
if (entry.isDirectory()) {
const pkgJson = join(searchDir, entry.name, 'package.json');
if (existsSync(pkgJson)) {
paths.push(pkgJson);
}
}
}
} catch {
// directory doesn't exist, skip
}
} else {
const pkgJson = join(rootDir, pattern, 'package.json');
if (existsSync(pkgJson)) {
paths.push(pkgJson);
}
}
}
return paths;
}
// Update a dependencies object, returning count of changes
function updateDeps(deps, targetVersion) {
let count = 0;
if (!deps) return count;
for (const pkg of CS3D_PACKAGES) {
if (pkg in deps && deps[pkg] !== targetVersion) {
deps[pkg] = targetVersion;
count++;
}
}
return count;
}
const pkgPaths = findWorkspacePackageJsons();
let totalChanges = 0;
for (const pkgPath of pkgPaths) {
const content = readFileSync(pkgPath, 'utf8');
const pkg = JSON.parse(content);
let changes = 0;
changes += updateDeps(pkg.dependencies, version);
changes += updateDeps(pkg.devDependencies, version);
changes += updateDeps(pkg.peerDependencies, version);
changes += updateDeps(pkg.resolutions, version);
if (changes > 0) {
// Preserve original formatting (detect indent)
const indent = content.match(/^(\s+)/m)?.[1] || ' ';
writeFileSync(pkgPath, JSON.stringify(pkg, null, indent) + '\n');
const rel = pkgPath.replace(rootDir + '/', '').replace(rootDir + '\\', '');
console.log(` Updated ${rel} (${changes} packages)`);
totalChanges += changes;
}
}
console.log(
`\nDone: ${totalChanges} version(s) updated to ${version} across ${pkgPaths.length} package files.`
);
console.log(
'This step changes package.json; the following install must not use a frozen Bun lockfile ' +
'(OHIF+CS3D combined “version” CI does: `bun install --config=./bunfig.update-lockfile.toml`). ' +
'Other installs stay frozen. Locally after this script, use that bun command and/or ' +
'`bun run install:update-lockfile` when you intend to commit lockfile updates.\n'
);
-108
View File
@@ -1,108 +0,0 @@
#!/usr/bin/env node
/**
* Logs build context (OHIF branch/version, CS3D source) for diagnosing build issues on GitHub.
* Run from repo root. Used by version.mjs and can be invoked from CI workflows.
*/
import { execa } from 'execa';
import fs from 'fs/promises';
import path from 'path';
import { fileURLToPath } from 'url';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const REPO_ROOT = path.resolve(__dirname, '..');
function log(msg) {
console.log(`[build-context] ${msg}`);
}
async function detectCs3dSource() {
const libsCs3d = path.join(REPO_ROOT, 'libs/@cornerstonejs');
const coreInNodeModules = path.join(REPO_ROOT, 'node_modules/@cornerstonejs/core');
try {
const libsExists = await fs.access(libsCs3d).then(() => true).catch(() => false);
if (!libsExists) {
return { source: 'npm', detail: 'published @cornerstonejs packages (no libs/@cornerstonejs)' };
}
const coreStat = await fs.lstat(coreInNodeModules).catch(() => null);
const isSymlink = coreStat?.isSymbolicLink();
if (isSymlink) {
const target = await fs.readlink(coreInNodeModules);
return { source: 'integrated', detail: `linked from libs/@cornerstonejs (→ ${target})` };
}
return { source: 'npm', detail: 'published @cornerstonejs packages (libs exists but not linked)' };
} catch {
return { source: 'unknown', detail: 'could not detect' };
}
}
async function getCs3dVersion() {
try {
const corePkg = path.join(REPO_ROOT, 'node_modules/@cornerstonejs/core/package.json');
const pkg = JSON.parse(await fs.readFile(corePkg, 'utf-8'));
return pkg.version || 'unknown';
} catch {
return 'unknown';
}
}
async function getCs3dBranchFromLibs() {
try {
const libsCs3d = path.join(REPO_ROOT, 'libs/@cornerstonejs');
const { stdout } = await execa('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {
cwd: libsCs3d,
});
return stdout;
} catch {
return null;
}
}
async function run() {
const inCI = process.env.GITHUB_ACTIONS === 'true';
const buildType = inCI ? (process.env.BUILD_TYPE || 'ohif-upstream') : 'local';
log('═══════════════════════════════════════════════════════════════');
log('Build context (for diagnosing GitHub build issues)');
log('═══════════════════════════════════════════════════════════════');
if (inCI) {
log(`Build type: ${process.env.BUILD_TYPE || 'ohif-upstream'}`);
log(`GitHub repo: ${process.env.GITHUB_REPOSITORY || 'unknown'}`);
log(`GitHub ref: ${process.env.GITHUB_REF || 'unknown'}`);
log(`GitHub SHA: ${process.env.GITHUB_SHA || 'unknown'}`);
log(`Workflow: ${process.env.GITHUB_WORKFLOW || 'unknown'}`);
}
try {
const { stdout: branch } = await execa('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {
cwd: REPO_ROOT,
});
const { stdout: sha } = await execa('git', ['rev-parse', '--short', 'HEAD'], {
cwd: REPO_ROOT,
});
log(`OHIF branch: ${branch} (${sha})`);
} catch {
log('OHIF branch: (not a git repo or error)');
}
const cs3d = await detectCs3dSource();
log(`CS3D source: ${cs3d.source} — ${cs3d.detail}`);
if (cs3d.source === 'integrated') {
const branch = await getCs3dBranchFromLibs();
if (branch) log(`CS3D branch (libs/@cornerstonejs): ${branch}`);
} else {
const ver = await getCs3dVersion();
log(`CS3D version (@cornerstonejs/core): ${ver}`);
}
log('═══════════════════════════════════════════════════════════════');
}
run().catch((err) => {
console.error('[build-context] Error:', err.message);
process.exitCode = 1;
});
+8 -671
View File
@@ -3,704 +3,41 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.13.0-beta.66](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.65...v3.13.0-beta.66) (2026-04-29)
## [3.12.4](https://github.com/OHIF/Viewers/compare/v3.12.3...v3.12.4) (2026-06-05)
### Bug Fixes
* **config url:** Hardening fetch options. ([#5985](https://github.com/OHIF/Viewers/issues/5985)) ([468e573](https://github.com/OHIF/Viewers/commit/468e5734a9ab02516430cc0dab5d7f2106dea950))
* **security:** Update axios to fix security vulnerabilities. Release 3.12.4 ([#6064](https://github.com/OHIF/Viewers/issues/6064)) ([62917c2](https://github.com/OHIF/Viewers/commit/62917c214246233b7b76aa8926fdfd645a2385a7))
# [3.13.0-beta.65](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.64...v3.13.0-beta.65) (2026-04-29)
**Note:** Version bump only for package ohif-monorepo-root
# [3.13.0-beta.64](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.63...v3.13.0-beta.64) (2026-04-27)
## [3.12.3](https://github.com/OHIF/Viewers/compare/v3.12.2...v3.12.3) (2026-05-27)
### Bug Fixes
* **seg:** prevent segmentations from spreading to all viewports before hydration confirmation in 3D four-up ([#5967](https://github.com/OHIF/Viewers/issues/5967)) ([f8ccf9f](https://github.com/OHIF/Viewers/commit/f8ccf9ff2ea9ab7c38bd427514a8ae87902822a3))
* **security:** Add tmp as a resolution to fix security vulnerability. Trigger release 3.12.3. ([#6045](https://github.com/OHIF/Viewers/issues/6045)) ([fb4441b](https://github.com/OHIF/Viewers/commit/fb4441ba71ec95dd494d120152a61df9261024cb))
# [3.13.0-beta.63](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.62...v3.13.0-beta.63) (2026-04-27)
## [3.12.2](https://github.com/OHIF/Viewers/compare/v3.12.1...v3.12.2) (2026-05-18)
### Bug Fixes
* **security:** refine dynamic config URL trust policy and document trusted-origin behavior ([#5973](https://github.com/OHIF/Viewers/issues/5973)) ([f3cca21](https://github.com/OHIF/Viewers/commit/f3cca21e49729fbf4bab85aa1de64b9dcfebd0ce))
* **release:** make publish-version.mjs idempotent for re-runs ([647fd02](https://github.com/OHIF/Viewers/commit/647fd025cf7212acc03b66807974f5d0f8ba0708))
* **security:** Update various dependencies to fix security vulnerabilities. Release 3.12.2 ([#6024](https://github.com/OHIF/Viewers/issues/6024)) ([75a24a3](https://github.com/OHIF/Viewers/commit/75a24a33935bda8779da30ef9b725b387d80723d))
# [3.13.0-beta.62](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.61...v3.13.0-beta.62) (2026-04-23)
### Bug Fixes
* **security:** Patch protobufjs for CVE-2026-41242. ([#5974](https://github.com/OHIF/Viewers/issues/5974)) ([1fc97fe](https://github.com/OHIF/Viewers/commit/1fc97fea43cc5e6689bd0076b77a278c67252af7))
# [3.13.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.60...v3.13.0-beta.61) (2026-04-23)
### Features
* **slice scrollbar:** Integrate ViewportSliceProgressScrollbar with customizations and docs ([#5960](https://github.com/OHIF/Viewers/issues/5960)) ([8fc0dc1](https://github.com/OHIF/Viewers/commit/8fc0dc16e97f3262fdac902ecf2d7c20cb8f78cc))
# [3.13.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.59...v3.13.0-beta.60) (2026-04-21)
### Bug Fixes
* **configuration:** Harden dynamic datasource URL trust boundaries and credential handling. ([#5963](https://github.com/OHIF/Viewers/issues/5963)) ([eede569](https://github.com/OHIF/Viewers/commit/eede569a88ed6a3177bbdea8552dfb93ca13cac5))
# [3.13.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.58...v3.13.0-beta.59) (2026-04-16)
### Bug Fixes
* Use newer ONNX version and load without errors ([#5854](https://github.com/OHIF/Viewers/issues/5854)) ([cc5dc20](https://github.com/OHIF/Viewers/commit/cc5dc201649bcbfb4cfad21141dbd56000d30f53)), closes [#5875](https://github.com/OHIF/Viewers/issues/5875) [#5884](https://github.com/OHIF/Viewers/issues/5884) [#5886](https://github.com/OHIF/Viewers/issues/5886) [#5893](https://github.com/OHIF/Viewers/issues/5893) [#5874](https://github.com/OHIF/Viewers/issues/5874) [#5865](https://github.com/OHIF/Viewers/issues/5865)
# [3.13.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.57...v3.13.0-beta.58) (2026-04-14)
**Note:** Version bump only for package ohif-monorepo-root
# [3.13.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.56...v3.13.0-beta.57) (2026-04-13)
### Bug Fixes
* Enhance multiframe instance handling and improve instance valida… ([#5956](https://github.com/OHIF/Viewers/issues/5956)) ([f5a66b9](https://github.com/OHIF/Viewers/commit/f5a66b9eea236cd3291eac857208d7465516c89a))
# [3.13.0-beta.56](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.55...v3.13.0-beta.56) (2026-04-10)
### Bug Fixes
* A couple of changes to enable cs3d integration build ([#5944](https://github.com/OHIF/Viewers/issues/5944)) ([f6bbd5c](https://github.com/OHIF/Viewers/commit/f6bbd5c779e4692dc47c93327a890661b8dcc174))
# [3.13.0-beta.55](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.54...v3.13.0-beta.55) (2026-04-10)
### Bug Fixes
* ignore auth in git ([#5955](https://github.com/OHIF/Viewers/issues/5955)) ([961eea1](https://github.com/OHIF/Viewers/commit/961eea1c39c37a940c1707c3dfafcede5f4af994))
# [3.13.0-beta.54](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.53...v3.13.0-beta.54) (2026-04-08)
### Bug Fixes
* **cornerstone:** read FrameOfReferenceUID from display set in viewport service ([#5950](https://github.com/OHIF/Viewers/issues/5950)) ([d219171](https://github.com/OHIF/Viewers/commit/d219171e25caf5a7c575080f63819d6f4fe45016))
# [3.13.0-beta.53](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.52...v3.13.0-beta.53) (2026-04-06)
### Reverts
* rename DisplaySet.frameOfReferenceUID back to FrameOfReferenceUID ([#5943](https://github.com/OHIF/Viewers/issues/5943)) ([0e933c2](https://github.com/OHIF/Viewers/commit/0e933c256e07b7cda35ed2ba3cfb1ab35d895d57))
# [3.13.0-beta.52](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.51...v3.13.0-beta.52) (2026-04-06)
### Bug Fixes
* **defaultRouteInit:** pass sorted display sets to hanging protocol for deterministic viewport order ([#5933](https://github.com/OHIF/Viewers/issues/5933)) ([68b10d3](https://github.com/OHIF/Viewers/commit/68b10d365a72d656c83a1c61624dcbd245fff5db))
### Features
* **component:** Adds SmartScrollbar to ui-next - OHIF-2558 ([#5924](https://github.com/OHIF/Viewers/issues/5924)) ([91a8715](https://github.com/OHIF/Viewers/commit/91a8715795c1501b271f10b361382331eb836bf9))
# [3.13.0-beta.51](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.50...v3.13.0-beta.51) (2026-04-03)
### Bug Fixes
* **security:** Update yarn.lock that was missed in PR [#5936](https://github.com/OHIF/Viewers/issues/5936). ([#5940](https://github.com/OHIF/Viewers/issues/5940)) ([84ddf78](https://github.com/OHIF/Viewers/commit/84ddf78c879a7cb1aa62c3aaef4428adf67065da))
# [3.13.0-beta.50](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.49...v3.13.0-beta.50) (2026-04-02)
### Bug Fixes
* **security:** update dependencies to fix security vulnerabilities ([#5936](https://github.com/OHIF/Viewers/issues/5936)) ([5358a39](https://github.com/OHIF/Viewers/commit/5358a3985a1fa87eb1e3e7493dd61254f790b6d8))
# [3.13.0-beta.49](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.48...v3.13.0-beta.49) (2026-04-02)
### Bug Fixes
* **segmentation:** restrict overlay segmentation menu to same frame of reference as viewport background display set ([#5900](https://github.com/OHIF/Viewers/issues/5900)) ([b9029ef](https://github.com/OHIF/Viewers/commit/b9029ef6f8d63a0e36ec929310c1c5ad3f563ef8))
# [3.13.0-beta.48](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.47...v3.13.0-beta.48) (2026-04-01)
### Bug Fixes
* **measurement:** Restore viewport interactivity when deleting in-progress Spline or Livewire measurement ([#5905](https://github.com/OHIF/Viewers/issues/5905)) ([7929f08](https://github.com/OHIF/Viewers/commit/7929f0898f1bf882682a912b1c32d93d0944726f))
# [3.13.0-beta.47](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.46...v3.13.0-beta.47) (2026-03-28)
### Bug Fixes
* prevent black viewport when navigating series with client-created segmentation ([#5919](https://github.com/OHIF/Viewers/issues/5919)) ([e66fb5a](https://github.com/OHIF/Viewers/commit/e66fb5a2b8c93a60ea20d315f73def7a02ea205f))
# [3.13.0-beta.46](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.45...v3.13.0-beta.46) (2026-03-27)
**Note:** Version bump only for package ohif-monorepo-root
# [3.13.0-beta.45](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.44...v3.13.0-beta.45) (2026-03-27)
**Note:** Version bump only for package ohif-monorepo-root
# [3.13.0-beta.44](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.43...v3.13.0-beta.44) (2026-03-27)
**Note:** Version bump only for package ohif-monorepo-root
# [3.13.0-beta.43](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.42...v3.13.0-beta.43) (2026-03-17)
### Bug Fixes
* **SR:** Added support for spline and live wire SR items. ([#5870](https://github.com/OHIF/Viewers/issues/5870)) ([1d4802c](https://github.com/OHIF/Viewers/commit/1d4802c2a38dd75dca7afca87913e100453c9135))
# [3.13.0-beta.42](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.41...v3.13.0-beta.42) (2026-03-17)
### Features
* Add combined build ([#5895](https://github.com/OHIF/Viewers/issues/5895)) ([1df671e](https://github.com/OHIF/Viewers/commit/1df671e9ab67d43f98bf09f6838ddc0a5f220277))
# [3.13.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.40...v3.13.0-beta.41) (2026-03-16)
### Bug Fixes
* **sr-hydration:** enable hydration and arrow navigation for 3D SR measurements ([#5887](https://github.com/OHIF/Viewers/issues/5887)) ([7a38903](https://github.com/OHIF/Viewers/commit/7a38903b1977b1cf0f3a0ba8a4a823fac5e8fdeb))
# [3.13.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.39...v3.13.0-beta.40) (2026-03-13)
### Bug Fixes
* **security:** Bump flattened version to address CVE-2026-32141. ([#5897](https://github.com/OHIF/Viewers/issues/5897)) ([d8d376e](https://github.com/OHIF/Viewers/commit/d8d376edaf9c2b7af237182657e3e2203cca5abb))
# [3.13.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.38...v3.13.0-beta.39) (2026-03-13)
### Bug Fixes
* **window level:** The window level value is not displayed by default on all the viewports when selecting common/custom layout and TMTV. ([#5865](https://github.com/OHIF/Viewers/issues/5865)) ([fe1ecfe](https://github.com/OHIF/Viewers/commit/fe1ecfe0cc5d1bcf82686d821f356da8936a8c4b))
# [3.13.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.37...v3.13.0-beta.38) (2026-03-12)
### Bug Fixes
* **segmentation:** Display "No description S:{series number} {modality}" for segmentations with no label. ([#5874](https://github.com/OHIF/Viewers/issues/5874)) ([7b5d0ce](https://github.com/OHIF/Viewers/commit/7b5d0ce40e5422ccfce6091ac3d7559586cbe57e))
# [3.13.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.36...v3.13.0-beta.37) (2026-03-12)
### Bug Fixes
* **security:** Bump tar version to address CVE-2026-31802. ([#5893](https://github.com/OHIF/Viewers/issues/5893)) ([d015b2e](https://github.com/OHIF/Viewers/commit/d015b2e32a418042034c4f557c5a36499c72f702))
# [3.13.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.35...v3.13.0-beta.36) (2026-03-11)
### Bug Fixes
* Modalities in study list should select starts with as primary ([#5886](https://github.com/OHIF/Viewers/issues/5886)) ([b83e978](https://github.com/OHIF/Viewers/commit/b83e978df8c9ffda3759378318267b8d0020653c))
# [3.13.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.34...v3.13.0-beta.35) (2026-03-09)
### Bug Fixes
* **Threshold tool:** Threshold tool no longer becomes deselected when the Dynamic option is selected ([#5884](https://github.com/OHIF/Viewers/issues/5884)) ([889026f](https://github.com/OHIF/Viewers/commit/889026f8a9c20cd21c31b4a02128afd5f057b14b))
# [3.13.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.33...v3.13.0-beta.34) (2026-03-09)
### Bug Fixes
* **seg hydration:** auto-hydrate RT struct on second load with disableConfirmationPrompts ([#5875](https://github.com/OHIF/Viewers/issues/5875)) ([6f773f9](https://github.com/OHIF/Viewers/commit/6f773f997214c388409f3af3e9fc0e5b84debc10))
# [3.13.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.32...v3.13.0-beta.33) (2026-03-05)
### Bug Fixes
* **security:** Bump svgo and tar to fix vulnerabilities. ([#5877](https://github.com/OHIF/Viewers/issues/5877)) ([61a1fcc](https://github.com/OHIF/Viewers/commit/61a1fccd7d47965831a6c80357219eed979ce4d6))
# [3.13.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.31...v3.13.0-beta.32) (2026-03-05)
### Features
* **ecg:** add DICOM ECG waveform extension ([#5856](https://github.com/OHIF/Viewers/issues/5856)) ([70f76ae](https://github.com/OHIF/Viewers/commit/70f76aeba1b27f8e4de5ec73a7b831428e38e3d2))
# [3.13.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.30...v3.13.0-beta.31) (2026-03-04)
### Bug Fixes
* **microscopy:** rename measurement in microscopy mode ([#5866](https://github.com/OHIF/Viewers/issues/5866)) ([2358a73](https://github.com/OHIF/Viewers/commit/2358a73c3cd24953430064480fb9e66bfe36ea69))
# [3.13.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.29...v3.13.0-beta.30) (2026-03-04)
### Bug Fixes
* **segmentation:** segment bidirectional tool error and show toast notification when no segment is drawn ([#5861](https://github.com/OHIF/Viewers/issues/5861)) ([7e10830](https://github.com/OHIF/Viewers/commit/7e10830d5802e22bda4df6a3f8008e9a414b4cd4))
# [3.13.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.28...v3.13.0-beta.29) (2026-03-04)
### Bug Fixes
* **security:** Address various security vulnerabilities. ([#5869](https://github.com/OHIF/Viewers/issues/5869)) ([be8e266](https://github.com/OHIF/Viewers/commit/be8e266a80f13d03ce9dc4a21a0227d3e1bc36ac))
# [3.13.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.27...v3.13.0-beta.28) (2026-03-03)
**Note:** Version bump only for package ohif-monorepo-root
# [3.13.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.26...v3.13.0-beta.27) (2026-03-02)
**Note:** Version bump only for package ohif-monorepo-root
# [3.13.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.25...v3.13.0-beta.26) (2026-02-28)
**Note:** Version bump only for package ohif-monorepo-root
# [3.13.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.24...v3.13.0-beta.25) (2026-02-26)
### Bug Fixes
* Update CS3D 4.18.2 ([#5837](https://github.com/OHIF/Viewers/issues/5837)) ([5370b93](https://github.com/OHIF/Viewers/commit/5370b9382e7bfddeadd69bab9e653f5f997a6e19))
# [3.13.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.23...v3.13.0-beta.24) (2026-02-24)
### Bug Fixes
* prevent viewer crash when opening DICOM Tag Browser from empty viewport ([#5827](https://github.com/OHIF/Viewers/issues/5827)) ([d11d6d4](https://github.com/OHIF/Viewers/commit/d11d6d401bc92a3870ec1089d97235b01a6b27c3))
* **ui-next:** Add validation for opacity and border inputs in the segmentation panel - OHIF-2332 ([#5819](https://github.com/OHIF/Viewers/issues/5819)) ([a8f7099](https://github.com/OHIF/Viewers/commit/a8f709982f16983a11c780e696521df5aa05b604))
# [3.13.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.22...v3.13.0-beta.23) (2026-02-23)
### Bug Fixes
* palette color 8 encoded 16 ([#5823](https://github.com/OHIF/Viewers/issues/5823)) ([eeca1f7](https://github.com/OHIF/Viewers/commit/eeca1f7a7b529d1700f5d281a6fd98074547ffe9)), closes [#5813](https://github.com/OHIF/Viewers/issues/5813)
# [3.13.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.21...v3.13.0-beta.22) (2026-02-23)
**Note:** Version bump only for package ohif-monorepo-root
# [3.13.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.20...v3.13.0-beta.21) (2026-02-23)
### Bug Fixes
* **RTStruct:** RTSTRUCT contours rendered on first slice for multi-frame images without IPP ([#5811](https://github.com/OHIF/Viewers/issues/5811)) ([b5573ca](https://github.com/OHIF/Viewers/commit/b5573caaa65d0d7ff3e83df0ec70b4aa7ea898ca))
# [3.13.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.19...v3.13.0-beta.20) (2026-02-21)
### Bug Fixes
* Published version should match ([#5813](https://github.com/OHIF/Viewers/issues/5813)) ([d359a3b](https://github.com/OHIF/Viewers/commit/d359a3b784227b248c5b09548db363c7f8adbcb8))
# [3.13.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.18...v3.13.0-beta.19) (2026-02-20)
### Bug Fixes
* **security:** CVE-2026-27212 patched. Various dependency updates as a result of CVE-2026-26996. ([#5830](https://github.com/OHIF/Viewers/issues/5830)) ([2722960](https://github.com/OHIF/Viewers/commit/27229609cda3162e37573418ef82ca5d4e365075))
# [3.13.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.17...v3.13.0-beta.18) (2026-02-19)
### Bug Fixes
* **segmentation overlay:** update viewport ds list upon seg delete - OHIF-2425 ([#5729](https://github.com/OHIF/Viewers/issues/5729)) ([b353541](https://github.com/OHIF/Viewers/commit/b35354120a01d89b27844f967c32c052bba8b096))
# [3.13.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.16...v3.13.0-beta.17) (2026-02-19)
### Bug Fixes
* Add copy to clipboard option for capture ([#5720](https://github.com/OHIF/Viewers/issues/5720)) ([53c67f3](https://github.com/OHIF/Viewers/commit/53c67f361234a0b4160c1b11fafcb143a0723336))
# [3.13.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.15...v3.13.0-beta.16) (2026-02-18)
### Bug Fixes
* **security:** Bump tar to 7.5.9 and lerna to 9.0.4 to fix CVE-2026-26960. ([#5824](https://github.com/OHIF/Viewers/issues/5824)) ([3d59c0d](https://github.com/OHIF/Viewers/commit/3d59c0d9d3783336eaa8d37cfc0172818942bf00))
# [3.13.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.14...v3.13.0-beta.15) (2026-02-17)
### Bug Fixes
* **dicom-tag-browser:** Prevent long series names from overlapping - OHIF-2406 ([#5809](https://github.com/OHIF/Viewers/issues/5809)) ([cca1a86](https://github.com/OHIF/Viewers/commit/cca1a8683bc7d392a3a07268f24585642d13b1cd))
# [3.13.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.13...v3.13.0-beta.14) (2026-02-13)
**Note:** Version bump only for package ohif-monorepo-root
# [3.13.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.12...v3.13.0-beta.13) (2026-02-12)
### Bug Fixes
* **colors:** Replace hardcoded black with background color token ([#5815](https://github.com/OHIF/Viewers/issues/5815)) ([dbc31a5](https://github.com/OHIF/Viewers/commit/dbc31a5d4ec5b2238683a580af96aff23d9fafeb))
# [3.13.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.11...v3.13.0-beta.12) (2026-02-12)
### Bug Fixes
* **usAnnotation:** Prevent error after JSON download ([#5814](https://github.com/OHIF/Viewers/issues/5814)) ([739e323](https://github.com/OHIF/Viewers/commit/739e3239cf5765711050b673b373c0145747824f))
# [3.13.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.10...v3.13.0-beta.11) (2026-02-12)
### Bug Fixes
* **colors:** Replaces legacy colors with ui-next colors ([#5351](https://github.com/OHIF/Viewers/issues/5351)) ([9a2691a](https://github.com/OHIF/Viewers/commit/9a2691a71fe3723bb05cbd148968b64e5d0fa951))
# [3.13.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.9...v3.13.0-beta.10) (2026-02-11)
### Bug Fixes
* **microscopy:** Prevent measurement clearing on viewport resize ([#5796](https://github.com/OHIF/Viewers/issues/5796)) ([baef707](https://github.com/OHIF/Viewers/commit/baef707e46fd76b50f8b510b45da64e12d71ed0e))
# [3.13.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.9) (2026-02-11)
### Bug Fixes
* Add a single version number with commit process ([#5746](https://github.com/OHIF/Viewers/issues/5746)) ([fb7329f](https://github.com/OHIF/Viewers/commit/fb7329f3fe0edc04833f15cd515522353d465912))
* Missing tag ([#5808](https://github.com/OHIF/Viewers/issues/5808)) ([c92bdd5](https://github.com/OHIF/Viewers/commit/c92bdd5b48b8805e9ea4cbac72007391b9ba0efe))
# [3.13.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.8) (2026-02-11)
### Bug Fixes
* Add a single version number with commit process ([#5746](https://github.com/OHIF/Viewers/issues/5746)) ([fb7329f](https://github.com/OHIF/Viewers/commit/fb7329f3fe0edc04833f15cd515522353d465912))
# [3.13.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.7) (2026-02-10)
### Bug Fixes
* Add a single version number with commit process ([#5746](https://github.com/OHIF/Viewers/issues/5746)) ([fb7329f](https://github.com/OHIF/Viewers/commit/fb7329f3fe0edc04833f15cd515522353d465912))
# [3.13.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.5...v3.13.0-beta.6) (2026-02-10)
**Note:** Version bump only for package ohif-monorepo-root
# [3.13.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.4...v3.13.0-beta.5) (2026-02-10)
**Note:** Version bump only for package ohif-monorepo-root
# [3.13.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.3...v3.13.0-beta.4) (2026-02-10)
### Bug Fixes
* Better handle octet stream case ([#5789](https://github.com/OHIF/Viewers/issues/5789)) ([037402f](https://github.com/OHIF/Viewers/commit/037402f7f6a1fc07593be302e4f578f6c4870c6e))
# [3.13.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.2...v3.13.0-beta.3) (2026-02-10)
### Bug Fixes
* **app:** display study not found message for all modes ([#5752](https://github.com/OHIF/Viewers/issues/5752)) ([7f9e59e](https://github.com/OHIF/Viewers/commit/7f9e59ee3074e3511d22c7f0075856a7bd2cc32e))
# [3.13.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.1...v3.13.0-beta.2) (2026-02-10)
### Bug Fixes
* **cine:** prevent crash on second view/hydration of SR series ([#5724](https://github.com/OHIF/Viewers/issues/5724)) ([f70c9b9](https://github.com/OHIF/Viewers/commit/f70c9b932db2bb14173acae675d38ce250d244fa))
# [3.13.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.0...v3.13.0-beta.1) (2026-02-09)
### Bug Fixes
* **security:** Use a resolution for axios to address CVE-2026-25639. ([#5793](https://github.com/OHIF/Viewers/issues/5793)) ([94c9e16](https://github.com/OHIF/Viewers/commit/94c9e162f3d17840c7e9659557f685ca8642d06f))
# [3.13.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.13.0-beta.0) (2026-02-07)
# [3.12.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.12.0) (2026-02-06)
**Note:** Version bump only for package ohif-monorepo-root
+1 -59
View File
@@ -49,7 +49,6 @@ provided by the <a href="https://ohif.org/">Open Health Imaging Foundation (OHIF
| <img src="https://github.com/OHIF/Viewers/blob/master/platform/docs/docs/assets/img/demo-4d.webp?raw=true" alt="4D" width="350"/> | 4D | [Demo](https://viewer.ohif.org/dynamic-volume?StudyInstanceUIDs=2.25.232704420736447710317909004159492840763) |
| <img src="https://github.com/OHIF/Viewers/blob/master/platform/docs/docs/assets/img/demo-video.webp?raw=true" alt="VIDEO" width="350"/> | Video | [Demo](https://viewer.ohif.org/viewer?StudyInstanceUIDs=2.25.96975534054447904995905761963464388233) |
| <img src="https://github.com/OHIF/Viewers/blob/master/platform/docs/docs/assets/img/microscopy.webp?raw=true" alt="microscopy" width="350"/> | Slide Microscopy | [Demo](https://viewer.ohif.org/microscopy?StudyInstanceUIDs=2.25.141277760791347900862109212450152067508) |
| <img src="https://github.com/OHIF/Viewers/blob/master/platform/docs/docs/assets/img/demo-ecg.webp?raw=true" alt="ECG" width="350"/> | ECG Waveform | [Demo](https://viewer-dev.ohif.org/viewer?StudyInstanceUIDs=2.25.209974489360710696739324151261716440238) |
## About
@@ -105,6 +104,7 @@ For commercial support, academic collaborations, and answers to common
questions; please use [Get Support](https://ohif.org/get-support/) to contact
us.
## Developing
### Branches
@@ -168,64 +168,6 @@ yarn config set workspaces-experimental true
yarn install --frozen-lockfile
```
### Cornerstone3D Integration Testing
OHIF's Playwright end-to-end tests can run against a **CS3D branch** or a
**published CS3D version**, allowing changes that span both repositories to be
validated together before merging.
#### Setting up an integration build
1. Add the **`ohif-integration`** label to your OHIF pull request.
2. In the PR body, add a line specifying the CS3D ref:
```
CS3D_REF: feat/my-feature
```
- **Version ref** (e.g. `4.19+`, `4.18.2`) — the workflow resolves it to an
exact published version and swaps the CS3D dependency via npm.
- **Branch ref** (e.g. `main`, `cornerstonejs:feat/foo`) — the workflow
clones the branch, builds CS3D from source with `bun run build:esm`, and
symlinks the built packages into OHIF's `node_modules`.
- For forks, use the `<owner>:<branch>` format
(e.g. `myGithubUser:feat/foo`).
- If no `CS3D_REF` is specified, the default is `4.19+`.
3. The workflow can also be triggered manually via **workflow_dispatch** with a
`cs3d_ref` input.
#### What happens in CI
The [Playwright workflow](.github/workflows/playwright.yml) runs two jobs:
| Job | Purpose |
|-----|---------|
| **Playwright Tests** | Builds OHIF (with CS3D linked or version-swapped), runs the full Playwright suite, uploads test results and coverage, and deploys a Netlify preview when `ohif-integration` is active. |
| **CS3D Branch Merge Guard** | A lightweight check that **fails** when the `ohif-integration` label is present and `CS3D_REF` points to a branch (not a version). This prevents merging while still letting the Playwright tests show green so you can see whether the code actually works. |
#### Testing changes that span both repos
If a feature requires changes in both Cornerstone3D and OHIF:
1. Create your feature branch in CS3D and push it.
2. Create a matching branch in OHIF.
3. Add the `ohif-integration` label to the OHIF pull request.
4. In the PR body, add: `CS3D_REF: <your-cs3d-branch>`.
5. Playwright tests will build CS3D from source, link it, and run the full
suite. The merge guard will block merge until you switch to a published
version — but you can see the test results and the preview deploy while
iterating.
6. Once the CS3D side is merged and published, update the PR body to reference
the published version (e.g. `CS3D_REF: 4.19+`). The tests will run against
the registry version and the merge guard will pass.
#### Preview deploys
When `ohif-integration` is active, the Playwright workflow also builds the OHIF
viewer and deploys it to Netlify as a preview. This gives you a live URL to
manually test the combined CS3D + OHIF changes without running anything locally.
For details on linking CS3D locally for development, see the
[Cornerstone3D README](libs/@cornerstonejs/README.md#local-development-linking--unlinking).
## Commands
These commands are available from the root directory. Each project directory
+4 -514
View File
@@ -3,7 +3,7 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.13.0-beta.66](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.65...v3.13.0-beta.66) (2026-04-29)
## [3.12.4](https://github.com/OHIF/Viewers/compare/v3.12.3...v3.12.4) (2026-06-05)
**Note:** Version bump only for package @externals/devDependencies
@@ -11,7 +11,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
# [3.13.0-beta.65](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.64...v3.13.0-beta.65) (2026-04-29)
## [3.12.3](https://github.com/OHIF/Viewers/compare/v3.12.2...v3.12.3) (2026-05-27)
**Note:** Version bump only for package @externals/devDependencies
@@ -19,7 +19,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
# [3.13.0-beta.64](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.63...v3.13.0-beta.64) (2026-04-27)
## [3.12.2](https://github.com/OHIF/Viewers/compare/v3.12.1...v3.12.2) (2026-05-18)
**Note:** Version bump only for package @externals/devDependencies
@@ -27,517 +27,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
# [3.13.0-beta.63](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.62...v3.13.0-beta.63) (2026-04-27)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.62](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.61...v3.13.0-beta.62) (2026-04-23)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.60...v3.13.0-beta.61) (2026-04-23)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.59...v3.13.0-beta.60) (2026-04-21)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.58...v3.13.0-beta.59) (2026-04-16)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.57...v3.13.0-beta.58) (2026-04-14)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.56...v3.13.0-beta.57) (2026-04-13)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.56](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.55...v3.13.0-beta.56) (2026-04-10)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.55](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.54...v3.13.0-beta.55) (2026-04-10)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.54](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.53...v3.13.0-beta.54) (2026-04-08)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.53](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.52...v3.13.0-beta.53) (2026-04-06)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.52](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.51...v3.13.0-beta.52) (2026-04-06)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.51](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.50...v3.13.0-beta.51) (2026-04-03)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.50](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.49...v3.13.0-beta.50) (2026-04-02)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.49](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.48...v3.13.0-beta.49) (2026-04-02)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.48](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.47...v3.13.0-beta.48) (2026-04-01)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.47](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.46...v3.13.0-beta.47) (2026-03-28)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.46](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.45...v3.13.0-beta.46) (2026-03-27)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.45](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.44...v3.13.0-beta.45) (2026-03-27)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.44](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.43...v3.13.0-beta.44) (2026-03-27)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.43](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.42...v3.13.0-beta.43) (2026-03-17)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.42](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.41...v3.13.0-beta.42) (2026-03-17)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.40...v3.13.0-beta.41) (2026-03-16)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.39...v3.13.0-beta.40) (2026-03-13)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.38...v3.13.0-beta.39) (2026-03-13)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.37...v3.13.0-beta.38) (2026-03-12)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.36...v3.13.0-beta.37) (2026-03-12)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.35...v3.13.0-beta.36) (2026-03-11)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.34...v3.13.0-beta.35) (2026-03-09)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.33...v3.13.0-beta.34) (2026-03-09)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.32...v3.13.0-beta.33) (2026-03-05)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.31...v3.13.0-beta.32) (2026-03-05)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.30...v3.13.0-beta.31) (2026-03-04)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.29...v3.13.0-beta.30) (2026-03-04)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.28...v3.13.0-beta.29) (2026-03-04)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.27...v3.13.0-beta.28) (2026-03-03)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.26...v3.13.0-beta.27) (2026-03-02)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.25...v3.13.0-beta.26) (2026-02-28)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.24...v3.13.0-beta.25) (2026-02-26)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.23...v3.13.0-beta.24) (2026-02-24)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.22...v3.13.0-beta.23) (2026-02-23)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.21...v3.13.0-beta.22) (2026-02-23)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.20...v3.13.0-beta.21) (2026-02-23)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.19...v3.13.0-beta.20) (2026-02-21)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.18...v3.13.0-beta.19) (2026-02-20)
### Bug Fixes
* **security:** CVE-2026-27212 patched. Various dependency updates as a result of CVE-2026-26996. ([#5830](https://github.com/OHIF/Viewers/issues/5830)) ([2722960](https://github.com/OHIF/Viewers/commit/27229609cda3162e37573418ef82ca5d4e365075))
# [3.13.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.17...v3.13.0-beta.18) (2026-02-19)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.16...v3.13.0-beta.17) (2026-02-19)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.15...v3.13.0-beta.16) (2026-02-18)
### Bug Fixes
* **security:** Bump tar to 7.5.9 and lerna to 9.0.4 to fix CVE-2026-26960. ([#5824](https://github.com/OHIF/Viewers/issues/5824)) ([3d59c0d](https://github.com/OHIF/Viewers/commit/3d59c0d9d3783336eaa8d37cfc0172818942bf00))
# [3.13.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.14...v3.13.0-beta.15) (2026-02-17)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.13...v3.13.0-beta.14) (2026-02-13)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.12...v3.13.0-beta.13) (2026-02-12)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.11...v3.13.0-beta.12) (2026-02-12)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.10...v3.13.0-beta.11) (2026-02-12)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.9...v3.13.0-beta.10) (2026-02-11)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.9) (2026-02-11)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.8) (2026-02-11)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.7) (2026-02-10)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.5...v3.13.0-beta.6) (2026-02-10)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.4...v3.13.0-beta.5) (2026-02-10)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.3...v3.13.0-beta.4) (2026-02-10)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.2...v3.13.0-beta.3) (2026-02-10)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.1...v3.13.0-beta.2) (2026-02-10)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.0...v3.13.0-beta.1) (2026-02-09)
**Note:** Version bump only for package @externals/devDependencies
# [3.13.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.13.0-beta.0) (2026-02-07)
# [3.12.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.12.0) (2026-02-06)
**Note:** Version bump only for package @externals/devDependencies
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@externals/devDependencies",
"description": "External dev dependencies - put dev build dependencies here",
"version": "3.13.0-beta.66",
"version": "3.12.4",
"license": "MIT",
"private": true,
"engines": {
+4 -508
View File
@@ -3,7 +3,7 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.13.0-beta.66](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.65...v3.13.0-beta.66) (2026-04-29)
## [3.12.4](https://github.com/OHIF/Viewers/compare/v3.12.3...v3.12.4) (2026-06-05)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
@@ -11,7 +11,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
# [3.13.0-beta.65](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.64...v3.13.0-beta.65) (2026-04-29)
## [3.12.3](https://github.com/OHIF/Viewers/compare/v3.12.2...v3.12.3) (2026-05-27)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
@@ -19,7 +19,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
# [3.13.0-beta.64](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.63...v3.13.0-beta.64) (2026-04-27)
## [3.12.2](https://github.com/OHIF/Viewers/compare/v3.12.1...v3.12.2) (2026-05-18)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
@@ -27,511 +27,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
# [3.13.0-beta.63](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.62...v3.13.0-beta.63) (2026-04-27)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.62](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.61...v3.13.0-beta.62) (2026-04-23)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.60...v3.13.0-beta.61) (2026-04-23)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.59...v3.13.0-beta.60) (2026-04-21)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.58...v3.13.0-beta.59) (2026-04-16)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.57...v3.13.0-beta.58) (2026-04-14)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.56...v3.13.0-beta.57) (2026-04-13)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.56](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.55...v3.13.0-beta.56) (2026-04-10)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.55](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.54...v3.13.0-beta.55) (2026-04-10)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.54](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.53...v3.13.0-beta.54) (2026-04-08)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.53](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.52...v3.13.0-beta.53) (2026-04-06)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.52](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.51...v3.13.0-beta.52) (2026-04-06)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.51](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.50...v3.13.0-beta.51) (2026-04-03)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.50](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.49...v3.13.0-beta.50) (2026-04-02)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.49](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.48...v3.13.0-beta.49) (2026-04-02)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.48](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.47...v3.13.0-beta.48) (2026-04-01)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.47](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.46...v3.13.0-beta.47) (2026-03-28)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.46](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.45...v3.13.0-beta.46) (2026-03-27)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.45](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.44...v3.13.0-beta.45) (2026-03-27)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.44](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.43...v3.13.0-beta.44) (2026-03-27)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.43](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.42...v3.13.0-beta.43) (2026-03-17)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.42](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.41...v3.13.0-beta.42) (2026-03-17)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.40...v3.13.0-beta.41) (2026-03-16)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.39...v3.13.0-beta.40) (2026-03-13)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.38...v3.13.0-beta.39) (2026-03-13)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.37...v3.13.0-beta.38) (2026-03-12)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.36...v3.13.0-beta.37) (2026-03-12)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.35...v3.13.0-beta.36) (2026-03-11)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.34...v3.13.0-beta.35) (2026-03-09)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.33...v3.13.0-beta.34) (2026-03-09)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.32...v3.13.0-beta.33) (2026-03-05)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.31...v3.13.0-beta.32) (2026-03-05)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.30...v3.13.0-beta.31) (2026-03-04)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.29...v3.13.0-beta.30) (2026-03-04)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.28...v3.13.0-beta.29) (2026-03-04)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.27...v3.13.0-beta.28) (2026-03-03)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.26...v3.13.0-beta.27) (2026-03-02)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.25...v3.13.0-beta.26) (2026-02-28)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.24...v3.13.0-beta.25) (2026-02-26)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.23...v3.13.0-beta.24) (2026-02-24)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.22...v3.13.0-beta.23) (2026-02-23)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.21...v3.13.0-beta.22) (2026-02-23)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.20...v3.13.0-beta.21) (2026-02-23)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.19...v3.13.0-beta.20) (2026-02-21)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.18...v3.13.0-beta.19) (2026-02-20)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.17...v3.13.0-beta.18) (2026-02-19)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.16...v3.13.0-beta.17) (2026-02-19)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.15...v3.13.0-beta.16) (2026-02-18)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.14...v3.13.0-beta.15) (2026-02-17)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.13...v3.13.0-beta.14) (2026-02-13)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.12...v3.13.0-beta.13) (2026-02-12)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.11...v3.13.0-beta.12) (2026-02-12)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.10...v3.13.0-beta.11) (2026-02-12)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.9...v3.13.0-beta.10) (2026-02-11)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.9) (2026-02-11)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.8) (2026-02-11)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.7) (2026-02-10)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.5...v3.13.0-beta.6) (2026-02-10)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.4...v3.13.0-beta.5) (2026-02-10)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.3...v3.13.0-beta.4) (2026-02-10)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.2...v3.13.0-beta.3) (2026-02-10)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.1...v3.13.0-beta.2) (2026-02-10)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.0...v3.13.0-beta.1) (2026-02-09)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.13.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.13.0-beta.0) (2026-02-07)
# [3.12.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.12.0) (2026-02-06)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@externals/dicom-microscopy-viewer",
"description": "External reference to dicom-microscopy-viewer",
"version": "3.13.0-beta.66",
"version": "3.12.4",
"license": "MIT",
"dependencies": {
"dicom-microscopy-viewer": "0.48.17"
+1 -1
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"
},
+1001 -243
View File
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -1 +1 @@
468e5734a9ab02516430cc0dab5d7f2106dea950
62917c214246233b7b76aa8926fdfd645a2385a7
+4 -526
View File
@@ -3,7 +3,7 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.13.0-beta.66](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.65...v3.13.0-beta.66) (2026-04-29)
## [3.12.4](https://github.com/OHIF/Viewers/compare/v3.12.3...v3.12.4) (2026-06-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
@@ -11,7 +11,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
# [3.13.0-beta.65](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.64...v3.13.0-beta.65) (2026-04-29)
## [3.12.3](https://github.com/OHIF/Viewers/compare/v3.12.2...v3.12.3) (2026-05-27)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
@@ -19,7 +19,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
# [3.13.0-beta.64](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.63...v3.13.0-beta.64) (2026-04-27)
## [3.12.2](https://github.com/OHIF/Viewers/compare/v3.12.1...v3.12.2) (2026-05-18)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
@@ -27,529 +27,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
# [3.13.0-beta.63](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.62...v3.13.0-beta.63) (2026-04-27)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.62](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.61...v3.13.0-beta.62) (2026-04-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.60...v3.13.0-beta.61) (2026-04-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.59...v3.13.0-beta.60) (2026-04-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.58...v3.13.0-beta.59) (2026-04-16)
### Bug Fixes
* Use newer ONNX version and load without errors ([#5854](https://github.com/OHIF/Viewers/issues/5854)) ([cc5dc20](https://github.com/OHIF/Viewers/commit/cc5dc201649bcbfb4cfad21141dbd56000d30f53)), closes [#5875](https://github.com/OHIF/Viewers/issues/5875) [#5884](https://github.com/OHIF/Viewers/issues/5884) [#5886](https://github.com/OHIF/Viewers/issues/5886) [#5893](https://github.com/OHIF/Viewers/issues/5893) [#5874](https://github.com/OHIF/Viewers/issues/5874) [#5865](https://github.com/OHIF/Viewers/issues/5865)
# [3.13.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.57...v3.13.0-beta.58) (2026-04-14)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.56...v3.13.0-beta.57) (2026-04-13)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.56](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.55...v3.13.0-beta.56) (2026-04-10)
### Bug Fixes
* A couple of changes to enable cs3d integration build ([#5944](https://github.com/OHIF/Viewers/issues/5944)) ([f6bbd5c](https://github.com/OHIF/Viewers/commit/f6bbd5c779e4692dc47c93327a890661b8dcc174))
# [3.13.0-beta.55](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.54...v3.13.0-beta.55) (2026-04-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.54](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.53...v3.13.0-beta.54) (2026-04-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.53](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.52...v3.13.0-beta.53) (2026-04-06)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.52](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.51...v3.13.0-beta.52) (2026-04-06)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.51](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.50...v3.13.0-beta.51) (2026-04-03)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.50](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.49...v3.13.0-beta.50) (2026-04-02)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.49](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.48...v3.13.0-beta.49) (2026-04-02)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.48](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.47...v3.13.0-beta.48) (2026-04-01)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.47](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.46...v3.13.0-beta.47) (2026-03-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.46](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.45...v3.13.0-beta.46) (2026-03-27)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.45](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.44...v3.13.0-beta.45) (2026-03-27)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.44](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.43...v3.13.0-beta.44) (2026-03-27)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.43](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.42...v3.13.0-beta.43) (2026-03-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.42](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.41...v3.13.0-beta.42) (2026-03-17)
### Features
* Add combined build ([#5895](https://github.com/OHIF/Viewers/issues/5895)) ([1df671e](https://github.com/OHIF/Viewers/commit/1df671e9ab67d43f98bf09f6838ddc0a5f220277))
# [3.13.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.40...v3.13.0-beta.41) (2026-03-16)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.39...v3.13.0-beta.40) (2026-03-13)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.38...v3.13.0-beta.39) (2026-03-13)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.37...v3.13.0-beta.38) (2026-03-12)
### Bug Fixes
* **segmentation:** Display "No description S:{series number} {modality}" for segmentations with no label. ([#5874](https://github.com/OHIF/Viewers/issues/5874)) ([7b5d0ce](https://github.com/OHIF/Viewers/commit/7b5d0ce40e5422ccfce6091ac3d7559586cbe57e))
# [3.13.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.36...v3.13.0-beta.37) (2026-03-12)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.35...v3.13.0-beta.36) (2026-03-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.34...v3.13.0-beta.35) (2026-03-09)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.33...v3.13.0-beta.34) (2026-03-09)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.32...v3.13.0-beta.33) (2026-03-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.31...v3.13.0-beta.32) (2026-03-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.30...v3.13.0-beta.31) (2026-03-04)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.29...v3.13.0-beta.30) (2026-03-04)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.28...v3.13.0-beta.29) (2026-03-04)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.27...v3.13.0-beta.28) (2026-03-03)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.26...v3.13.0-beta.27) (2026-03-02)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.25...v3.13.0-beta.26) (2026-02-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.24...v3.13.0-beta.25) (2026-02-26)
### Bug Fixes
* Update CS3D 4.18.2 ([#5837](https://github.com/OHIF/Viewers/issues/5837)) ([5370b93](https://github.com/OHIF/Viewers/commit/5370b9382e7bfddeadd69bab9e653f5f997a6e19))
# [3.13.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.23...v3.13.0-beta.24) (2026-02-24)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.22...v3.13.0-beta.23) (2026-02-23)
### Bug Fixes
* palette color 8 encoded 16 ([#5823](https://github.com/OHIF/Viewers/issues/5823)) ([eeca1f7](https://github.com/OHIF/Viewers/commit/eeca1f7a7b529d1700f5d281a6fd98074547ffe9)), closes [#5813](https://github.com/OHIF/Viewers/issues/5813)
# [3.13.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.21...v3.13.0-beta.22) (2026-02-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.20...v3.13.0-beta.21) (2026-02-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.19...v3.13.0-beta.20) (2026-02-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.18...v3.13.0-beta.19) (2026-02-20)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.17...v3.13.0-beta.18) (2026-02-19)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.16...v3.13.0-beta.17) (2026-02-19)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.15...v3.13.0-beta.16) (2026-02-18)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.14...v3.13.0-beta.15) (2026-02-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.13...v3.13.0-beta.14) (2026-02-13)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.12...v3.13.0-beta.13) (2026-02-12)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.11...v3.13.0-beta.12) (2026-02-12)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.10...v3.13.0-beta.11) (2026-02-12)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.9...v3.13.0-beta.10) (2026-02-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.9) (2026-02-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.8) (2026-02-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.7) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.5...v3.13.0-beta.6) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.4...v3.13.0-beta.5) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.3...v3.13.0-beta.4) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.2...v3.13.0-beta.3) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.1...v3.13.0-beta.2) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.0...v3.13.0-beta.1) (2026-02-09)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.13.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.13.0-beta.0) (2026-02-07)
# [3.12.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.12.0) (2026-02-06)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-cornerstone-dicom-pmap",
"version": "3.13.0-beta.66",
"version": "3.12.4",
"description": "DICOM Parametric Map read workflow",
"author": "OHIF",
"license": "MIT",
@@ -33,10 +33,10 @@
"start": "yarn run dev"
},
"peerDependencies": {
"@ohif/core": "3.13.0-beta.66",
"@ohif/extension-cornerstone": "3.13.0-beta.66",
"@ohif/extension-default": "3.13.0-beta.66",
"@ohif/i18n": "3.13.0-beta.66",
"@ohif/core": "3.12.4",
"@ohif/extension-cornerstone": "3.12.4",
"@ohif/extension-default": "3.12.4",
"@ohif/i18n": "3.12.4",
"prop-types": "15.8.1",
"react": "18.3.1",
"react-dom": "18.3.1",
@@ -46,8 +46,8 @@
},
"dependencies": {
"@babel/runtime": "7.28.2",
"@cornerstonejs/adapters": "4.22.3",
"@cornerstonejs/core": "4.22.3",
"@cornerstonejs/adapters": "4.15.29",
"@cornerstonejs/core": "4.15.29",
"@kitware/vtk.js": "34.15.1"
}
}
+4 -517
View File
@@ -3,7 +3,7 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.13.0-beta.66](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.65...v3.13.0-beta.66) (2026-04-29)
## [3.12.4](https://github.com/OHIF/Viewers/compare/v3.12.3...v3.12.4) (2026-06-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
@@ -11,7 +11,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
# [3.13.0-beta.65](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.64...v3.13.0-beta.65) (2026-04-29)
## [3.12.3](https://github.com/OHIF/Viewers/compare/v3.12.2...v3.12.3) (2026-05-27)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
@@ -19,7 +19,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
# [3.13.0-beta.64](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.63...v3.13.0-beta.64) (2026-04-27)
## [3.12.2](https://github.com/OHIF/Viewers/compare/v3.12.1...v3.12.2) (2026-05-18)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
@@ -27,520 +27,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
# [3.13.0-beta.63](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.62...v3.13.0-beta.63) (2026-04-27)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.62](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.61...v3.13.0-beta.62) (2026-04-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.60...v3.13.0-beta.61) (2026-04-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.59...v3.13.0-beta.60) (2026-04-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.58...v3.13.0-beta.59) (2026-04-16)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.57...v3.13.0-beta.58) (2026-04-14)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.56...v3.13.0-beta.57) (2026-04-13)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.56](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.55...v3.13.0-beta.56) (2026-04-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.55](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.54...v3.13.0-beta.55) (2026-04-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.54](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.53...v3.13.0-beta.54) (2026-04-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.53](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.52...v3.13.0-beta.53) (2026-04-06)
### Reverts
* rename DisplaySet.frameOfReferenceUID back to FrameOfReferenceUID ([#5943](https://github.com/OHIF/Viewers/issues/5943)) ([0e933c2](https://github.com/OHIF/Viewers/commit/0e933c256e07b7cda35ed2ba3cfb1ab35d895d57))
# [3.13.0-beta.52](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.51...v3.13.0-beta.52) (2026-04-06)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.51](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.50...v3.13.0-beta.51) (2026-04-03)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.50](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.49...v3.13.0-beta.50) (2026-04-02)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.49](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.48...v3.13.0-beta.49) (2026-04-02)
### Bug Fixes
* **segmentation:** restrict overlay segmentation menu to same frame of reference as viewport background display set ([#5900](https://github.com/OHIF/Viewers/issues/5900)) ([b9029ef](https://github.com/OHIF/Viewers/commit/b9029ef6f8d63a0e36ec929310c1c5ad3f563ef8))
# [3.13.0-beta.48](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.47...v3.13.0-beta.48) (2026-04-01)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.47](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.46...v3.13.0-beta.47) (2026-03-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.46](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.45...v3.13.0-beta.46) (2026-03-27)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.45](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.44...v3.13.0-beta.45) (2026-03-27)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.44](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.43...v3.13.0-beta.44) (2026-03-27)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.43](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.42...v3.13.0-beta.43) (2026-03-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.42](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.41...v3.13.0-beta.42) (2026-03-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.40...v3.13.0-beta.41) (2026-03-16)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.39...v3.13.0-beta.40) (2026-03-13)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.38...v3.13.0-beta.39) (2026-03-13)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.37...v3.13.0-beta.38) (2026-03-12)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.36...v3.13.0-beta.37) (2026-03-12)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.35...v3.13.0-beta.36) (2026-03-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.34...v3.13.0-beta.35) (2026-03-09)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.33...v3.13.0-beta.34) (2026-03-09)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.32...v3.13.0-beta.33) (2026-03-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.31...v3.13.0-beta.32) (2026-03-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.30...v3.13.0-beta.31) (2026-03-04)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.29...v3.13.0-beta.30) (2026-03-04)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.28...v3.13.0-beta.29) (2026-03-04)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.27...v3.13.0-beta.28) (2026-03-03)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.26...v3.13.0-beta.27) (2026-03-02)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.25...v3.13.0-beta.26) (2026-02-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.24...v3.13.0-beta.25) (2026-02-26)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.23...v3.13.0-beta.24) (2026-02-24)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.22...v3.13.0-beta.23) (2026-02-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.21...v3.13.0-beta.22) (2026-02-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.20...v3.13.0-beta.21) (2026-02-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.19...v3.13.0-beta.20) (2026-02-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.18...v3.13.0-beta.19) (2026-02-20)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.17...v3.13.0-beta.18) (2026-02-19)
### Bug Fixes
* **segmentation overlay:** update viewport ds list upon seg delete - OHIF-2425 ([#5729](https://github.com/OHIF/Viewers/issues/5729)) ([b353541](https://github.com/OHIF/Viewers/commit/b35354120a01d89b27844f967c32c052bba8b096))
# [3.13.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.16...v3.13.0-beta.17) (2026-02-19)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.15...v3.13.0-beta.16) (2026-02-18)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.14...v3.13.0-beta.15) (2026-02-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.13...v3.13.0-beta.14) (2026-02-13)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.12...v3.13.0-beta.13) (2026-02-12)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.11...v3.13.0-beta.12) (2026-02-12)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.10...v3.13.0-beta.11) (2026-02-12)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.9...v3.13.0-beta.10) (2026-02-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.9) (2026-02-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.8) (2026-02-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.7) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.5...v3.13.0-beta.6) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.4...v3.13.0-beta.5) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.3...v3.13.0-beta.4) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.2...v3.13.0-beta.3) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.1...v3.13.0-beta.2) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.0...v3.13.0-beta.1) (2026-02-09)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.13.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.13.0-beta.0) (2026-02-07)
# [3.12.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.12.0) (2026-02-06)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-cornerstone-dicom-rt",
"version": "3.13.0-beta.66",
"version": "3.12.4",
"description": "DICOM RT read workflow",
"author": "OHIF",
"license": "MIT",
@@ -33,10 +33,10 @@
"start": "yarn run dev"
},
"peerDependencies": {
"@ohif/core": "3.13.0-beta.66",
"@ohif/extension-cornerstone": "3.13.0-beta.66",
"@ohif/extension-default": "3.13.0-beta.66",
"@ohif/i18n": "3.13.0-beta.66",
"@ohif/core": "3.12.4",
"@ohif/extension-cornerstone": "3.12.4",
"@ohif/extension-default": "3.12.4",
"@ohif/i18n": "3.12.4",
"prop-types": "15.8.1",
"react": "18.3.1",
"react-dom": "18.3.1",
@@ -1,6 +1,5 @@
import { utils, Types as OhifTypes } from '@ohif/core';
import i18n from '@ohif/i18n';
import { segmentation as cstSegmentation } from '@cornerstonejs/tools';
import { SOPClassHandlerId } from './id';
import loadRTStruct from './loadRTStruct';
@@ -9,6 +8,8 @@ const { sopClassDictionary } = utils;
const sopClassUids = [sopClassDictionary.RTStructureSetStorage];
const cachedRTStructsSEG = new Set<string>();
const loadPromises = {};
function _getDisplaySetsFromSeries(
@@ -56,7 +57,6 @@ function _getDisplaySetsFromSeries(
StudyInstanceUID,
SOPClassHandlerId,
SOPClassUID,
FrameOfReferenceUID: null,
referencedImages: null,
referencedSeriesInstanceUID: null,
referencedDisplaySetInstanceUID: null,
@@ -96,9 +96,6 @@ function _getDisplaySetsFromSeries(
displaySet.referencedImages = instance.ReferencedSeriesSequence.ReferencedInstanceSequence;
displaySet.referencedSeriesInstanceUID = referencedSeries.SeriesInstanceUID;
displaySet.FrameOfReferenceUID =
instance.ReferencedFrameOfReferenceSequence?.[0]?.FrameOfReferenceUID;
const { displaySetService } = servicesManager.services;
const referencedDisplaySets =
displaySetService.getDisplaySetsForReferences(referencedSeriesSequence);
@@ -117,7 +114,6 @@ function _getDisplaySetsFromSeries(
if (addedDisplaySet.SeriesInstanceUID === displaySet.referencedSeriesInstanceUID) {
displaySet.referencedDisplaySetInstanceUID = addedDisplaySet.displaySetInstanceUID;
displaySet.isReconstructable = addedDisplaySet.isReconstructable;
displaySet.FrameOfReferenceUID = addedDisplaySet.FrameOfReferenceUID;
unsubscribe();
}
}
@@ -126,7 +122,6 @@ function _getDisplaySetsFromSeries(
const [referencedDisplaySet] = referencedDisplaySets;
displaySet.referencedDisplaySetInstanceUID = referencedDisplaySet.displaySetInstanceUID;
displaySet.isReconstructable = referencedDisplaySet.isReconstructable;
displaySet.FrameOfReferenceUID = referencedDisplaySet.FrameOfReferenceUID;
}
displaySet.load = ({ headers, createSegmentation = true }) =>
@@ -148,13 +143,23 @@ function _load(
if (
(rtDisplaySet.loading || rtDisplaySet.isLoaded) &&
loadPromises[SOPInstanceUID] &&
_segmentationExists(rtDisplaySet)
cachedRTStructsSEG.has(rtDisplaySet.displaySetInstanceUID)
) {
return loadPromises[SOPInstanceUID];
}
rtDisplaySet.loading = true;
const { unsubscribe } = segmentationService.subscribe(
segmentationService.EVENTS.SEGMENTATION_LOADING_COMPLETE,
(evt: { rtDisplaySet: { displaySetInstanceUID: string } }) => {
if (evt.rtDisplaySet?.displaySetInstanceUID === rtDisplaySet.displaySetInstanceUID) {
cachedRTStructsSEG.add(rtDisplaySet.displaySetInstanceUID);
unsubscribe();
}
}
);
// We don't want to fire multiple loads, so we'll wait for the first to finish
// and also return the same promise to any other callers.
loadPromises[SOPInstanceUID] = new Promise<void>(async (resolve, reject) => {
@@ -214,10 +219,6 @@ function _deriveReferencedSeriesSequenceFromFrameOfReferenceSequence(
return ReferencedSeriesSequence;
}
function _segmentationExists(segDisplaySet) {
return !!cstSegmentation.state.getSegmentation(segDisplaySet.displaySetInstanceUID);
}
function getSopClassHandlerModule(params: OhifTypes.Extensions.ExtensionParams) {
const { servicesManager, extensionManager } = params;
@@ -168,7 +168,7 @@ function OHIFCornerstoneRTViewport(props: withAppTypes) {
return () => {
// remove the segmentation representations if seg displayset changed
segmentationService.removeRepresentationsFromViewport(viewportId);
segmentationService.removeSegmentationRepresentations(viewportId);
referencedDisplaySetRef.current = null;
toolGroupService.destroyToolGroup(toolGroupId);
};
+4 -538
View File
@@ -3,7 +3,7 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.13.0-beta.66](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.65...v3.13.0-beta.66) (2026-04-29)
## [3.12.4](https://github.com/OHIF/Viewers/compare/v3.12.3...v3.12.4) (2026-06-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
@@ -11,7 +11,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
# [3.13.0-beta.65](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.64...v3.13.0-beta.65) (2026-04-29)
## [3.12.3](https://github.com/OHIF/Viewers/compare/v3.12.2...v3.12.3) (2026-05-27)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
@@ -19,7 +19,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
# [3.13.0-beta.64](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.63...v3.13.0-beta.64) (2026-04-27)
## [3.12.2](https://github.com/OHIF/Viewers/compare/v3.12.1...v3.12.2) (2026-05-18)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
@@ -27,541 +27,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
# [3.13.0-beta.63](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.62...v3.13.0-beta.63) (2026-04-27)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.62](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.61...v3.13.0-beta.62) (2026-04-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.60...v3.13.0-beta.61) (2026-04-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.59...v3.13.0-beta.60) (2026-04-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.58...v3.13.0-beta.59) (2026-04-16)
### Bug Fixes
* Use newer ONNX version and load without errors ([#5854](https://github.com/OHIF/Viewers/issues/5854)) ([cc5dc20](https://github.com/OHIF/Viewers/commit/cc5dc201649bcbfb4cfad21141dbd56000d30f53)), closes [#5875](https://github.com/OHIF/Viewers/issues/5875) [#5884](https://github.com/OHIF/Viewers/issues/5884) [#5886](https://github.com/OHIF/Viewers/issues/5886) [#5893](https://github.com/OHIF/Viewers/issues/5893) [#5874](https://github.com/OHIF/Viewers/issues/5874) [#5865](https://github.com/OHIF/Viewers/issues/5865)
# [3.13.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.57...v3.13.0-beta.58) (2026-04-14)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.56...v3.13.0-beta.57) (2026-04-13)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.56](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.55...v3.13.0-beta.56) (2026-04-10)
### Bug Fixes
* A couple of changes to enable cs3d integration build ([#5944](https://github.com/OHIF/Viewers/issues/5944)) ([f6bbd5c](https://github.com/OHIF/Viewers/commit/f6bbd5c779e4692dc47c93327a890661b8dcc174))
# [3.13.0-beta.55](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.54...v3.13.0-beta.55) (2026-04-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.54](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.53...v3.13.0-beta.54) (2026-04-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.53](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.52...v3.13.0-beta.53) (2026-04-06)
### Reverts
* rename DisplaySet.frameOfReferenceUID back to FrameOfReferenceUID ([#5943](https://github.com/OHIF/Viewers/issues/5943)) ([0e933c2](https://github.com/OHIF/Viewers/commit/0e933c256e07b7cda35ed2ba3cfb1ab35d895d57))
# [3.13.0-beta.52](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.51...v3.13.0-beta.52) (2026-04-06)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.51](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.50...v3.13.0-beta.51) (2026-04-03)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.50](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.49...v3.13.0-beta.50) (2026-04-02)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.49](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.48...v3.13.0-beta.49) (2026-04-02)
### Bug Fixes
* **segmentation:** restrict overlay segmentation menu to same frame of reference as viewport background display set ([#5900](https://github.com/OHIF/Viewers/issues/5900)) ([b9029ef](https://github.com/OHIF/Viewers/commit/b9029ef6f8d63a0e36ec929310c1c5ad3f563ef8))
# [3.13.0-beta.48](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.47...v3.13.0-beta.48) (2026-04-01)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.47](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.46...v3.13.0-beta.47) (2026-03-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.46](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.45...v3.13.0-beta.46) (2026-03-27)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.45](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.44...v3.13.0-beta.45) (2026-03-27)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.44](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.43...v3.13.0-beta.44) (2026-03-27)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.43](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.42...v3.13.0-beta.43) (2026-03-17)
### Bug Fixes
* **SR:** Added support for spline and live wire SR items. ([#5870](https://github.com/OHIF/Viewers/issues/5870)) ([1d4802c](https://github.com/OHIF/Viewers/commit/1d4802c2a38dd75dca7afca87913e100453c9135))
# [3.13.0-beta.42](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.41...v3.13.0-beta.42) (2026-03-17)
### Features
* Add combined build ([#5895](https://github.com/OHIF/Viewers/issues/5895)) ([1df671e](https://github.com/OHIF/Viewers/commit/1df671e9ab67d43f98bf09f6838ddc0a5f220277))
# [3.13.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.40...v3.13.0-beta.41) (2026-03-16)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.39...v3.13.0-beta.40) (2026-03-13)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.38...v3.13.0-beta.39) (2026-03-13)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.37...v3.13.0-beta.38) (2026-03-12)
### Bug Fixes
* **segmentation:** Display "No description S:{series number} {modality}" for segmentations with no label. ([#5874](https://github.com/OHIF/Viewers/issues/5874)) ([7b5d0ce](https://github.com/OHIF/Viewers/commit/7b5d0ce40e5422ccfce6091ac3d7559586cbe57e))
# [3.13.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.36...v3.13.0-beta.37) (2026-03-12)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.35...v3.13.0-beta.36) (2026-03-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.34...v3.13.0-beta.35) (2026-03-09)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.33...v3.13.0-beta.34) (2026-03-09)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.32...v3.13.0-beta.33) (2026-03-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.31...v3.13.0-beta.32) (2026-03-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.30...v3.13.0-beta.31) (2026-03-04)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.29...v3.13.0-beta.30) (2026-03-04)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.28...v3.13.0-beta.29) (2026-03-04)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.27...v3.13.0-beta.28) (2026-03-03)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.26...v3.13.0-beta.27) (2026-03-02)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.25...v3.13.0-beta.26) (2026-02-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.24...v3.13.0-beta.25) (2026-02-26)
### Bug Fixes
* Update CS3D 4.18.2 ([#5837](https://github.com/OHIF/Viewers/issues/5837)) ([5370b93](https://github.com/OHIF/Viewers/commit/5370b9382e7bfddeadd69bab9e653f5f997a6e19))
# [3.13.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.23...v3.13.0-beta.24) (2026-02-24)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.22...v3.13.0-beta.23) (2026-02-23)
### Bug Fixes
* palette color 8 encoded 16 ([#5823](https://github.com/OHIF/Viewers/issues/5823)) ([eeca1f7](https://github.com/OHIF/Viewers/commit/eeca1f7a7b529d1700f5d281a6fd98074547ffe9)), closes [#5813](https://github.com/OHIF/Viewers/issues/5813)
# [3.13.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.21...v3.13.0-beta.22) (2026-02-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.20...v3.13.0-beta.21) (2026-02-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.19...v3.13.0-beta.20) (2026-02-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.18...v3.13.0-beta.19) (2026-02-20)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.17...v3.13.0-beta.18) (2026-02-19)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.16...v3.13.0-beta.17) (2026-02-19)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.15...v3.13.0-beta.16) (2026-02-18)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.14...v3.13.0-beta.15) (2026-02-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.13...v3.13.0-beta.14) (2026-02-13)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.12...v3.13.0-beta.13) (2026-02-12)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.11...v3.13.0-beta.12) (2026-02-12)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.10...v3.13.0-beta.11) (2026-02-12)
### Bug Fixes
* **colors:** Replaces legacy colors with ui-next colors ([#5351](https://github.com/OHIF/Viewers/issues/5351)) ([9a2691a](https://github.com/OHIF/Viewers/commit/9a2691a71fe3723bb05cbd148968b64e5d0fa951))
# [3.13.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.9...v3.13.0-beta.10) (2026-02-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.9) (2026-02-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.8) (2026-02-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.7) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.5...v3.13.0-beta.6) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.4...v3.13.0-beta.5) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.3...v3.13.0-beta.4) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.2...v3.13.0-beta.3) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.1...v3.13.0-beta.2) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.0...v3.13.0-beta.1) (2026-02-09)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.13.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.13.0-beta.0) (2026-02-07)
# [3.12.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.12.0) (2026-02-06)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-cornerstone-dicom-seg",
"version": "3.13.0-beta.66",
"version": "3.12.4",
"description": "DICOM SEG read workflow",
"author": "OHIF",
"license": "MIT",
@@ -33,10 +33,10 @@
"start": "yarn run dev"
},
"peerDependencies": {
"@ohif/core": "3.13.0-beta.66",
"@ohif/extension-cornerstone": "3.13.0-beta.66",
"@ohif/extension-default": "3.13.0-beta.66",
"@ohif/i18n": "3.13.0-beta.66",
"@ohif/core": "3.12.4",
"@ohif/extension-cornerstone": "3.12.4",
"@ohif/extension-default": "3.12.4",
"@ohif/i18n": "3.12.4",
"prop-types": "15.8.1",
"react": "18.3.1",
"react-dom": "18.3.1",
@@ -46,8 +46,8 @@
},
"dependencies": {
"@babel/runtime": "7.28.2",
"@cornerstonejs/adapters": "4.22.3",
"@cornerstonejs/core": "4.22.3",
"@cornerstonejs/adapters": "4.15.29",
"@cornerstonejs/core": "4.15.29",
"@kitware/vtk.js": "34.15.1"
}
}
@@ -2,8 +2,9 @@ import dcmjs from 'dcmjs';
import { classes, Types, utils } from '@ohif/core';
import { cache, metaData } from '@cornerstonejs/core';
import { segmentation as cornerstoneToolsSegmentation } from '@cornerstonejs/tools';
import { adaptersRT, adaptersSEG } from '@cornerstonejs/adapters';
import { adaptersRT, helpers, adaptersSEG } from '@cornerstonejs/adapters';
import { createReportDialogPrompt, useUIStateStore } from '@ohif/extension-default';
import { DicomMetadataStore } from '@ohif/core';
import PROMPT_RESPONSES from '../../default/src/utils/_shared/PROMPT_RESPONSES';
@@ -28,11 +29,11 @@ const {
},
} = adaptersRT;
const { downloadDICOMData } = helpers;
const commandsModule = ({
servicesManager,
extensionManager,
commandsManager,
}: Types.Extensions.ExtensionParams): Types.Extensions.CommandsModule => {
const { segmentationService, displaySetService, viewportGridService } =
servicesManager.services as AppTypes.Services;
@@ -193,11 +194,8 @@ const commandsModule = ({
const generatedSegmentation = actions.generateSegmentation({
segmentationId,
});
const storeFn = commandsManager.runCommand('createStoreFunction', {
dataSource: 'download',
defaultFileName: `${segmentationInOHIF.label}.dcm`,
});
storeFn(generatedSegmentation.dataset);
downloadDICOMData(generatedSegmentation.dataset, `${segmentationInOHIF.label}`);
},
/**
* Stores a segmentation based on the provided segmentationId into a specified data source.
@@ -219,10 +217,11 @@ const commandsModule = ({
}
const { label, predecessorImageId } = segmentation;
const defaultDataSource = dataSource ?? extensionManager.getActiveDataSource()[0];
const {
value: reportName,
dataSourceName,
dataSourceName: selectedDataSource,
series,
priorSeriesNumber,
action,
@@ -232,58 +231,50 @@ const commandsModule = ({
predecessorImageId,
title: 'Store Segmentation',
modality,
enableDownload: true,
});
if (action !== PROMPT_RESPONSES.CREATE_REPORT) {
return;
}
if (action === PROMPT_RESPONSES.CREATE_REPORT) {
try {
const selectedDataSourceConfig = selectedDataSource
? extensionManager.getDataSources(selectedDataSource)[0]
: defaultDataSource;
const defaultFileName =
modality === 'RTSTRUCT'
? `rtss-${segmentationId}.dcm`
: `${label || 'segmentation'}.dcm`;
const args = {
segmentationId,
options: {
SeriesDescription: series ? undefined : reportName || label || 'Contour Series',
SeriesNumber: series ? undefined : 1 + priorSeriesNumber,
predecessorImageId: series,
},
};
const generatedDataAsync =
(modality === 'SEG' && actions.generateSegmentation(args)) ||
(modality === 'RTSTRUCT' && actions.generateContour(args));
const generatedData = await generatedDataAsync;
const storeFn = commandsManager.runCommand('createStoreFunction', {
dataSource: dataSourceName,
defaultFileName,
});
if (!generatedData || !generatedData.dataset) {
throw new Error('Error during segmentation generation');
}
if (!storeFn) {
throw new Error(`No valid store for dataSource: ${dataSourceName}`);
}
const { dataset: naturalizedReport } = generatedData;
try {
const args = {
segmentationId,
options: {
SeriesDescription: series ? undefined : reportName || label || 'Contour Series',
SeriesNumber: series ? undefined : 1 + priorSeriesNumber,
predecessorImageId: series,
},
};
const generatedDataAsync =
(modality === 'SEG' && actions.generateSegmentation(args)) ||
(modality === 'RTSTRUCT' && actions.generateContour(args));
const generatedData = await generatedDataAsync;
// DCMJS assigns a dummy study id during creation, and this can cause problems, so clearing it out
if (naturalizedReport.StudyID === 'No Study ID') {
naturalizedReport.StudyID = '';
}
if (!generatedData?.dataset) {
throw new Error('Error during segmentation generation');
await selectedDataSourceConfig.store.dicom(naturalizedReport);
// add the information for where we stored it to the instance as well
naturalizedReport.wadoRoot = selectedDataSourceConfig.getConfig().wadoRoot;
DicomMetadataStore.addInstances([naturalizedReport], true);
return naturalizedReport;
} catch (error) {
console.debug('Error storing segmentation:', error);
throw error;
}
const { dataset: naturalizedReport } = generatedData;
// DCMJS assigns a dummy study id during creation, and this can cause problems, so clearing it out
if (naturalizedReport.StudyID === 'No Study ID') {
naturalizedReport.StudyID = '';
}
await storeFn(naturalizedReport, {});
return naturalizedReport;
} catch (error) {
console.debug('Error storing segmentation:', error);
throw error;
}
},
@@ -316,11 +307,14 @@ const commandsModule = ({
downloadRTSS: async args => {
const { dataset } = await actions.generateContour(args);
const { InstanceNumber: instanceNumber = 1, SeriesInstanceUID: seriesUID } = dataset;
const storeFn = commandsManager.runCommand('createStoreFunction', {
dataSource: 'download',
defaultFileName: `rtss-${seriesUID}-${instanceNumber}.dcm`,
});
await storeFn(dataset);
try {
//Create a URL for the binary.
const filename = `rtss-${seriesUID}-${instanceNumber}.dcm`;
downloadDICOMData(dataset, filename);
} catch (e) {
console.warn(e);
}
},
toggleActiveSegmentationUtility: ({ itemId: buttonId }) => {
@@ -189,7 +189,7 @@ function LogicalContourOperationOptions() {
</Tabs>
<div>{t(operation.label)}</div>
</div>
<div className="bg-muted flex h-[62px] w-[88px] items-center justify-center rounded-lg">
<div className="bg-primary-dark flex h-[62px] w-[88px] items-center justify-center rounded-lg">
<Icons.ByName name={operation.helperIcon}></Icons.ByName>
</div>
</div>
@@ -30,7 +30,6 @@ function _getDisplaySetsFromSeries(
SeriesDate,
StructureSetDate,
SOPClassUID,
FrameOfReferenceUID,
wadoRoot,
wadoUri,
wadoUriRoot,
@@ -50,7 +49,6 @@ function _getDisplaySetsFromSeries(
StudyInstanceUID,
SOPClassHandlerId,
SOPClassUID,
FrameOfReferenceUID,
referencedImages: null,
referencedSeriesInstanceUID: null,
referencedDisplaySetInstanceUID: null,
@@ -106,7 +104,6 @@ function _getDisplaySetsFromSeries(
if (addedDisplaySet.SeriesInstanceUID === displaySet.referencedSeriesInstanceUID) {
displaySet.referencedDisplaySetInstanceUID = addedDisplaySet.displaySetInstanceUID;
displaySet.isReconstructable = addedDisplaySet.isReconstructable;
displaySet.FrameOfReferenceUID = addedDisplaySet.FrameOfReferenceUID;
unsubscribe();
}
}
@@ -114,7 +111,6 @@ function _getDisplaySetsFromSeries(
} else {
displaySet.referencedDisplaySetInstanceUID = referencedDisplaySet.displaySetInstanceUID;
displaySet.isReconstructable = referencedDisplaySet.isReconstructable;
displaySet.FrameOfReferenceUID = referencedDisplaySet.FrameOfReferenceUID;
}
displaySet.load = async ({ headers }) =>
+4 -541
View File
@@ -3,7 +3,7 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.13.0-beta.66](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.65...v3.13.0-beta.66) (2026-04-29)
## [3.12.4](https://github.com/OHIF/Viewers/compare/v3.12.3...v3.12.4) (2026-06-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
@@ -11,7 +11,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
# [3.13.0-beta.65](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.64...v3.13.0-beta.65) (2026-04-29)
## [3.12.3](https://github.com/OHIF/Viewers/compare/v3.12.2...v3.12.3) (2026-05-27)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
@@ -19,7 +19,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
# [3.13.0-beta.64](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.63...v3.13.0-beta.64) (2026-04-27)
## [3.12.2](https://github.com/OHIF/Viewers/compare/v3.12.1...v3.12.2) (2026-05-18)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
@@ -27,544 +27,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
# [3.13.0-beta.63](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.62...v3.13.0-beta.63) (2026-04-27)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.62](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.61...v3.13.0-beta.62) (2026-04-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.60...v3.13.0-beta.61) (2026-04-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.59...v3.13.0-beta.60) (2026-04-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.58...v3.13.0-beta.59) (2026-04-16)
### Bug Fixes
* Use newer ONNX version and load without errors ([#5854](https://github.com/OHIF/Viewers/issues/5854)) ([cc5dc20](https://github.com/OHIF/Viewers/commit/cc5dc201649bcbfb4cfad21141dbd56000d30f53)), closes [#5875](https://github.com/OHIF/Viewers/issues/5875) [#5884](https://github.com/OHIF/Viewers/issues/5884) [#5886](https://github.com/OHIF/Viewers/issues/5886) [#5893](https://github.com/OHIF/Viewers/issues/5893) [#5874](https://github.com/OHIF/Viewers/issues/5874) [#5865](https://github.com/OHIF/Viewers/issues/5865)
# [3.13.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.57...v3.13.0-beta.58) (2026-04-14)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.56...v3.13.0-beta.57) (2026-04-13)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.56](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.55...v3.13.0-beta.56) (2026-04-10)
### Bug Fixes
* A couple of changes to enable cs3d integration build ([#5944](https://github.com/OHIF/Viewers/issues/5944)) ([f6bbd5c](https://github.com/OHIF/Viewers/commit/f6bbd5c779e4692dc47c93327a890661b8dcc174))
# [3.13.0-beta.55](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.54...v3.13.0-beta.55) (2026-04-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.54](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.53...v3.13.0-beta.54) (2026-04-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.53](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.52...v3.13.0-beta.53) (2026-04-06)
### Reverts
* rename DisplaySet.frameOfReferenceUID back to FrameOfReferenceUID ([#5943](https://github.com/OHIF/Viewers/issues/5943)) ([0e933c2](https://github.com/OHIF/Viewers/commit/0e933c256e07b7cda35ed2ba3cfb1ab35d895d57))
# [3.13.0-beta.52](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.51...v3.13.0-beta.52) (2026-04-06)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.51](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.50...v3.13.0-beta.51) (2026-04-03)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.50](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.49...v3.13.0-beta.50) (2026-04-02)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.49](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.48...v3.13.0-beta.49) (2026-04-02)
### Bug Fixes
* **segmentation:** restrict overlay segmentation menu to same frame of reference as viewport background display set ([#5900](https://github.com/OHIF/Viewers/issues/5900)) ([b9029ef](https://github.com/OHIF/Viewers/commit/b9029ef6f8d63a0e36ec929310c1c5ad3f563ef8))
# [3.13.0-beta.48](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.47...v3.13.0-beta.48) (2026-04-01)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.47](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.46...v3.13.0-beta.47) (2026-03-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.46](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.45...v3.13.0-beta.46) (2026-03-27)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.45](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.44...v3.13.0-beta.45) (2026-03-27)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.44](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.43...v3.13.0-beta.44) (2026-03-27)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.43](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.42...v3.13.0-beta.43) (2026-03-17)
### Bug Fixes
* **SR:** Added support for spline and live wire SR items. ([#5870](https://github.com/OHIF/Viewers/issues/5870)) ([1d4802c](https://github.com/OHIF/Viewers/commit/1d4802c2a38dd75dca7afca87913e100453c9135))
# [3.13.0-beta.42](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.41...v3.13.0-beta.42) (2026-03-17)
### Features
* Add combined build ([#5895](https://github.com/OHIF/Viewers/issues/5895)) ([1df671e](https://github.com/OHIF/Viewers/commit/1df671e9ab67d43f98bf09f6838ddc0a5f220277))
# [3.13.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.40...v3.13.0-beta.41) (2026-03-16)
### Bug Fixes
* **sr-hydration:** enable hydration and arrow navigation for 3D SR measurements ([#5887](https://github.com/OHIF/Viewers/issues/5887)) ([7a38903](https://github.com/OHIF/Viewers/commit/7a38903b1977b1cf0f3a0ba8a4a823fac5e8fdeb))
# [3.13.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.39...v3.13.0-beta.40) (2026-03-13)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.38...v3.13.0-beta.39) (2026-03-13)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.37...v3.13.0-beta.38) (2026-03-12)
### Bug Fixes
* **segmentation:** Display "No description S:{series number} {modality}" for segmentations with no label. ([#5874](https://github.com/OHIF/Viewers/issues/5874)) ([7b5d0ce](https://github.com/OHIF/Viewers/commit/7b5d0ce40e5422ccfce6091ac3d7559586cbe57e))
# [3.13.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.36...v3.13.0-beta.37) (2026-03-12)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.35...v3.13.0-beta.36) (2026-03-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.34...v3.13.0-beta.35) (2026-03-09)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.33...v3.13.0-beta.34) (2026-03-09)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.32...v3.13.0-beta.33) (2026-03-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.31...v3.13.0-beta.32) (2026-03-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.30...v3.13.0-beta.31) (2026-03-04)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.29...v3.13.0-beta.30) (2026-03-04)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.28...v3.13.0-beta.29) (2026-03-04)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.27...v3.13.0-beta.28) (2026-03-03)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.26...v3.13.0-beta.27) (2026-03-02)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.25...v3.13.0-beta.26) (2026-02-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.24...v3.13.0-beta.25) (2026-02-26)
### Bug Fixes
* Update CS3D 4.18.2 ([#5837](https://github.com/OHIF/Viewers/issues/5837)) ([5370b93](https://github.com/OHIF/Viewers/commit/5370b9382e7bfddeadd69bab9e653f5f997a6e19))
# [3.13.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.23...v3.13.0-beta.24) (2026-02-24)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.22...v3.13.0-beta.23) (2026-02-23)
### Bug Fixes
* palette color 8 encoded 16 ([#5823](https://github.com/OHIF/Viewers/issues/5823)) ([eeca1f7](https://github.com/OHIF/Viewers/commit/eeca1f7a7b529d1700f5d281a6fd98074547ffe9)), closes [#5813](https://github.com/OHIF/Viewers/issues/5813)
# [3.13.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.21...v3.13.0-beta.22) (2026-02-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.20...v3.13.0-beta.21) (2026-02-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.19...v3.13.0-beta.20) (2026-02-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.18...v3.13.0-beta.19) (2026-02-20)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.17...v3.13.0-beta.18) (2026-02-19)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.16...v3.13.0-beta.17) (2026-02-19)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.15...v3.13.0-beta.16) (2026-02-18)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.14...v3.13.0-beta.15) (2026-02-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.13...v3.13.0-beta.14) (2026-02-13)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.12...v3.13.0-beta.13) (2026-02-12)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.11...v3.13.0-beta.12) (2026-02-12)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.10...v3.13.0-beta.11) (2026-02-12)
### Bug Fixes
* **colors:** Replaces legacy colors with ui-next colors ([#5351](https://github.com/OHIF/Viewers/issues/5351)) ([9a2691a](https://github.com/OHIF/Viewers/commit/9a2691a71fe3723bb05cbd148968b64e5d0fa951))
# [3.13.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.9...v3.13.0-beta.10) (2026-02-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.9) (2026-02-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.8) (2026-02-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.7) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.5...v3.13.0-beta.6) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.4...v3.13.0-beta.5) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.3...v3.13.0-beta.4) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.2...v3.13.0-beta.3) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.1...v3.13.0-beta.2) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.0...v3.13.0-beta.1) (2026-02-09)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.13.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.13.0-beta.0) (2026-02-07)
# [3.12.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.12.0) (2026-02-06)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
+8 -8
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-cornerstone-dicom-sr",
"version": "3.13.0-beta.66",
"version": "3.12.4",
"description": "OHIF extension for an SR Cornerstone Viewport",
"author": "OHIF",
"license": "MIT",
@@ -34,10 +34,10 @@
"test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests"
},
"peerDependencies": {
"@ohif/core": "3.13.0-beta.66",
"@ohif/extension-cornerstone": "3.13.0-beta.66",
"@ohif/extension-measurement-tracking": "3.13.0-beta.66",
"@ohif/ui": "3.13.0-beta.66",
"@ohif/core": "3.12.4",
"@ohif/extension-cornerstone": "3.12.4",
"@ohif/extension-measurement-tracking": "3.12.4",
"@ohif/ui": "3.12.4",
"dcmjs": "0.49.4",
"dicom-parser": "1.8.21",
"hammerjs": "2.0.8",
@@ -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.15.29",
"@cornerstonejs/core": "4.15.29",
"@cornerstonejs/tools": "4.15.29",
"classnames": "2.5.1"
}
}
@@ -1,11 +1,14 @@
import { metaData } from '@cornerstonejs/core';
import OHIF from '@ohif/core';
import OHIF, { DicomMetadataStore, utils } from '@ohif/core';
import dcmjs from 'dcmjs';
import { adaptersSR } from '@cornerstonejs/adapters';
import getFilteredCornerstoneToolState from './utils/getFilteredCornerstoneToolState';
import hydrateStructuredReport from './utils/hydrateStructuredReport';
const { downloadBlob } = utils;
const { MeasurementReport } = adaptersSR.Cornerstone3D;
const { log } = OHIF;
@@ -72,8 +75,24 @@ const commandsModule = (props: withAppTypes) => {
/**
*
* @param measurementData An array of measurements from the measurements service
* @param additionalFindingTypes toolTypes that should be stored with labels as Findings
* @param options Naturalized DICOM JSON headers to merge into the displaySet.
* as opposed to Finding Sites.
* that you wish to serialize.
* @param dataSource The data source name ('download', 'copyToClipboard', or a named data source).
*/
downloadReport: ({ measurementData, additionalFindingTypes, options = {} }) => {
const srDataset = _generateReport(measurementData, additionalFindingTypes, options);
const reportBlob = dcmjs.data.datasetToBlob(srDataset);
//Create a URL for the binary.
downloadBlob(reportBlob, { filename: 'dicom-sr.dcm' });
},
/**
*
* @param measurementData An array of measurements from the measurements service
* that you wish to serialize.
* @param dataSource The dataSource that you wish to use to persist the data.
* @param additionalFindingTypes toolTypes that should be stored with labels as Findings
* @param options Naturalized DICOM JSON headers to merge into the displaySet.
* @return The naturalized report
@@ -84,30 +103,23 @@ const commandsModule = (props: withAppTypes) => {
additionalFindingTypes,
options = {},
}) => {
// Use the @cornerstonejs adapter for converting to/from DICOM
// But it is good enough for now whilst we only have cornerstone as a datasource.
log.info('[DICOMSR] storeMeasurements');
const storeFn = commandsManager.runCommand('createStoreFunction', {
dataSource,
defaultFileName: 'dicom-sr.dcm',
});
if (!storeFn) {
log.error('[DICOMSR] No valid store for dataSource:', dataSource);
if (!dataSource || !dataSource.store || !dataSource.store.dicom) {
log.error('[DICOMSR] datasource has no dataSource.store.dicom endpoint!');
return Promise.reject({});
}
try {
const naturalizedReport = _generateReport(
measurementData,
additionalFindingTypes,
options
);
const naturalizedReport = _generateReport(measurementData, additionalFindingTypes, options);
const { ContentSequence } = naturalizedReport;
const { StudyInstanceUID, ContentSequence } = naturalizedReport;
// The content sequence has 5 or more elements, of which
// the `[4]` element contains the annotation data, so this is
// checking that there is some annotation data present.
if (!ContentSequence?.[4]?.ContentSequence?.length) {
if (!ContentSequence?.[4].ContentSequence?.length) {
console.log('naturalizedReport missing imaging content', naturalizedReport);
throw new Error('Invalid report, no content');
}
@@ -116,12 +128,22 @@ const commandsModule = (props: withAppTypes) => {
}
const onBeforeDicomStore = customizationService.getCustomization('onBeforeDicomStore');
let dicomDict;
if (typeof onBeforeDicomStore === 'function') {
dicomDict = onBeforeDicomStore({ dicomDict, measurementData, naturalizedReport });
}
await storeFn(naturalizedReport, { measurementData, dicomDict });
await dataSource.store.dicom(naturalizedReport, null, dicomDict);
if (StudyInstanceUID) {
dataSource.deleteStudyMetadataPromise(StudyInstanceUID);
}
// The "Mode" route listens for DicomMetadataStore changes
// When a new instance is added, it listens and
// automatically calls makeDisplaySets
DicomMetadataStore.addInstances([naturalizedReport], true);
return naturalizedReport;
} catch (error) {
@@ -144,6 +166,7 @@ const commandsModule = (props: withAppTypes) => {
};
const definitions = {
downloadReport: actions.downloadReport,
storeMeasurements: actions.storeMeasurements,
hydrateStructuredReport: actions.hydrateStructuredReport,
};
@@ -9,7 +9,7 @@ function OHIFCornerstoneSRTextViewport(props: withAppTypes) {
const instance = displaySet.instances[0];
return (
<div className="text-foreground relative flex h-full w-full flex-col overflow-auto p-4">
<div className="relative flex h-full w-full flex-col overflow-auto p-4 text-white">
<div>
{/* The root level is always a container */}
<OHIFCornerstoneSRContainer container={instance} />
@@ -200,13 +200,8 @@ async function _load(
srDisplaySet.isRehydratable = isRehydratable(srDisplaySet, mappings);
srDisplaySet.isLoaded = true;
/** Check currently added displaySets and add measurements if the sources exist.
* Walk the SR's study first in default series order (not load order) so SCOORD3D
* FrameOfReference matching picks a stable series when several share FOR. */
const displaySetsForSRPass = utils.sortDisplaySetsCopy(displaySetService.activeDisplaySets, {
studyInstanceUIDFirst: srDisplaySet.StudyInstanceUID,
});
displaySetsForSRPass.forEach(activeDisplaySet => {
/** Check currently added displaySets and add measurements if the sources exist */
displaySetService.activeDisplaySets.forEach(activeDisplaySet => {
_checkIfCanAddMeasurementsToDisplaySet(
srDisplaySet,
activeDisplaySet,
@@ -642,35 +637,16 @@ function _processNonGeometricallyDefinedMeasurement(mergedContentSequence) {
NUMContentItems.forEach(item => {
const { ConceptNameCodeSequence, ContentSequence, MeasuredValueSequence } = item;
// Handle spatial reference ONLY if ContentSequence exists.
// ContentSequence may be a scalar SCOORD or an array when additional named
// SCOORDs (e.g. control points) are nested alongside the primary geometry.
// Pick the primary geometry entry: prefer the SCOORD without a
// ConceptNameCodeSequence (plain polyline), falling back to the first SCOORD.
// Handle spatial reference ONLY if ContentSequence exists
if (ContentSequence) {
const scoordItem = Array.isArray(ContentSequence)
? (ContentSequence.find(
cs =>
(cs.ValueType === 'SCOORD' || cs.ValueType === 'SCOORD3D') &&
!cs.ConceptNameCodeSequence
) ?? ContentSequence.find(cs => cs.ValueType === 'SCOORD' || cs.ValueType === 'SCOORD3D'))
: ContentSequence;
if (!scoordItem) {
console.warn(
'ContentSequence array contains no SCOORD or SCOORD3D entry, skipping annotation.'
);
return;
}
const { ValueType } = scoordItem;
const { ValueType } = ContentSequence;
if (ValueType !== 'SCOORD' && ValueType !== 'SCOORD3D') {
console.warn(`Graphic ${ValueType} not currently supported, skipping annotation.`);
return;
}
const coords = _getCoordsFromSCOORDOrSCOORD3D(scoordItem);
const coords = _getCoordsFromSCOORDOrSCOORD3D(ContentSequence);
if (coords) {
measurement.coords.push(coords);
@@ -80,7 +80,7 @@ export default function hydrateStructuredReport(
const { ReferencedSOPInstanceUID, imageId, frameNumber = 1 } = measurement;
const key = `${ReferencedSOPInstanceUID}:${frameNumber}`;
if (imageId && !sopInstanceUIDToImageId[key]) {
if (!sopInstanceUIDToImageId[key]) {
sopInstanceUIDToImageId[key] = imageId;
}
});
@@ -118,17 +118,41 @@ export default function hydrateStructuredReport(
}
});
// Set the series touched as tracked.
const imageIds = [];
// TODO: notification if no hydratable?
Object.keys(hydratableMeasurementsInSR).forEach(annotationType => {
const toolDataForAnnotationType = hydratableMeasurementsInSR[annotationType];
toolDataForAnnotationType.forEach(toolData => {
// Add the measurement to toolState
// dcmjs and Cornerstone3D has structural defect in supporting multi-frame
// files, and looking up the imageId from sopInstanceUIDToImageId results
// in the wrong value.
const frameNumber = toolData.annotation.data?.frameNumber || 1;
const imageId = sopInstanceUIDToImageId[`${toolData.sopInstanceUid}:${frameNumber}`];
if (!imageIds.includes(imageId)) {
imageIds.push(imageId);
}
});
});
let targetStudyInstanceUID;
const SeriesInstanceUIDs = [];
// Set the series touched as tracked.
const imageIds = getImageIds(hydratableMeasurementsInSR, sopInstanceUIDToImageId);
for (const imageId of imageIds) {
for (let i = 0; i < imageIds.length; i++) {
const imageId = imageIds[i];
if (!imageId) {
continue;
}
const { SeriesInstanceUID, StudyInstanceUID } = metaData.get('instance', imageId);
if (!SeriesInstanceUIDs.includes(SeriesInstanceUID)) {
SeriesInstanceUIDs.push(SeriesInstanceUID);
}
if (!targetStudyInstanceUID) {
targetStudyInstanceUID = StudyInstanceUID;
} else if (targetStudyInstanceUID !== StudyInstanceUID) {
@@ -136,31 +160,6 @@ export default function hydrateStructuredReport(
}
}
// For 3d annotations there are no image IDs,
// so we need to find the display sets by frame of reference to get the SeriesInstanceUIDs
const frameOfReferenceUIDs = getFrameOfReferenceUIDs(
hydratableMeasurementsInSR,
sopInstanceUIDToImageId
);
for (const FrameOfReferenceUID of frameOfReferenceUIDs) {
const displaySetsFOR = displaySetService.getDisplaySetsBy(
ds => ds.FrameOfReferenceUID === FrameOfReferenceUID && !ds.isDerivedDisplaySet
);
const ds = chooseDisplaySet(displaySetsFOR, FrameOfReferenceUID);
if (!ds) {
continue;
}
if (!SeriesInstanceUIDs.includes(ds.SeriesInstanceUID)) {
SeriesInstanceUIDs.push(ds.SeriesInstanceUID);
}
if (!targetStudyInstanceUID) {
targetStudyInstanceUID = ds.StudyInstanceUID;
} else if (targetStudyInstanceUID !== ds.StudyInstanceUID) {
console.warn('NO SUPPORT FOR SRs THAT HAVE MEASUREMENTS FROM MULTIPLE STUDIES.');
}
}
/**
* Gets reference data for what frame of reference and the referenced
* image id, or for 3d measurements, the volumeId to apply this annotation to.
@@ -197,7 +196,7 @@ export default function hydrateStructuredReport(
toolDataForAnnotationType.forEach(toolData => {
toolData.uid = guid();
const referenceData = getReferenceData(toolData);
const { referencedImageId } = referenceData;
const { imageId } = referenceData;
const annotation = {
annotationUID: toolData.annotation.annotationUID,
@@ -242,8 +241,8 @@ export default function hydrateStructuredReport(
locking.setAnnotationLocked(newAnnotationUID, true);
}
if (referencedImageId && !imageIds.includes(referencedImageId)) {
imageIds.push(referencedImageId);
if (imageId && !imageIds.includes(imageId)) {
imageIds.push(imageId);
}
});
});
@@ -256,64 +255,15 @@ export default function hydrateStructuredReport(
};
}
/**
* Gets the unique imageIds from hydratable measurements that have an imageId reference
* (i.e., 2D/SCOORD annotations).
*/
function getImageIds(hydratableMeasurementsInSR, sopInstanceUIDToImageId): string[] {
const imageIds: string[] = [];
Object.keys(hydratableMeasurementsInSR).forEach(annotationType => {
const toolDataForAnnotationType = hydratableMeasurementsInSR[annotationType];
toolDataForAnnotationType.forEach(toolData => {
// Add the measurement to toolState
// dcmjs and Cornerstone3D has structural defect in supporting multi-frame
// files, and looking up the imageId from sopInstanceUIDToImageId results
// in the wrong value.
const frameNumber = toolData.annotation.data?.frameNumber || 1;
const imageId = sopInstanceUIDToImageId[`${toolData.sopInstanceUid}:${frameNumber}`];
if (imageId && !imageIds.includes(imageId)) {
imageIds.push(imageId);
}
});
});
return imageIds;
}
/**
* Gets the unique FrameOfReferenceUIDs from hydratable measurements that have no imageId reference
* (i.e., 3D/SCOORD3D annotations). This excludes annotations handled by the getImageIds function.
*/
function getFrameOfReferenceUIDs(hydratableMeasurementsInSR, sopInstanceUIDToImageId): string[] {
const frameOfReferenceUIDs: string[] = [];
Object.keys(hydratableMeasurementsInSR).forEach(annotationType => {
const toolDataForAnnotationType = hydratableMeasurementsInSR[annotationType];
toolDataForAnnotationType.forEach(toolData => {
const frameNumber = toolData.annotation.data?.frameNumber || 1;
const imageId = sopInstanceUIDToImageId[`${toolData.sopInstanceUid}:${frameNumber}`];
if (!imageId) {
const { FrameOfReferenceUID } = toolData.annotation.metadata;
if (FrameOfReferenceUID && !frameOfReferenceUIDs.includes(FrameOfReferenceUID)) {
frameOfReferenceUIDs.push(FrameOfReferenceUID);
}
}
});
});
return frameOfReferenceUIDs;
}
/**
* For 3d annotations, there are often several display sets which could
* be used to display the annotation. Choose the first annotation with the
* same frame of reference that is reconstructable, or the first display set
* otherwise.
*/
function chooseDisplaySet(displaySets, reference) {
function chooseDisplaySet(displaySets, annotation) {
if (!displaySets?.length) {
console.warn('No display set found for', reference);
console.warn('No display set found for', annotation);
return;
}
if (displaySets.length === 1) {
@@ -3,7 +3,7 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.13.0-beta.66](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.65...v3.13.0-beta.66) (2026-04-29)
## [3.12.4](https://github.com/OHIF/Viewers/compare/v3.12.3...v3.12.4) (2026-06-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
@@ -11,7 +11,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
# [3.13.0-beta.65](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.64...v3.13.0-beta.65) (2026-04-29)
## [3.12.3](https://github.com/OHIF/Viewers/compare/v3.12.2...v3.12.3) (2026-05-27)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
@@ -19,7 +19,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
# [3.13.0-beta.64](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.63...v3.13.0-beta.64) (2026-04-27)
## [3.12.2](https://github.com/OHIF/Viewers/compare/v3.12.1...v3.12.2) (2026-05-18)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
@@ -27,532 +27,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
# [3.13.0-beta.63](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.62...v3.13.0-beta.63) (2026-04-27)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.62](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.61...v3.13.0-beta.62) (2026-04-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.60...v3.13.0-beta.61) (2026-04-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.59...v3.13.0-beta.60) (2026-04-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.58...v3.13.0-beta.59) (2026-04-16)
### Bug Fixes
* Use newer ONNX version and load without errors ([#5854](https://github.com/OHIF/Viewers/issues/5854)) ([cc5dc20](https://github.com/OHIF/Viewers/commit/cc5dc201649bcbfb4cfad21141dbd56000d30f53)), closes [#5875](https://github.com/OHIF/Viewers/issues/5875) [#5884](https://github.com/OHIF/Viewers/issues/5884) [#5886](https://github.com/OHIF/Viewers/issues/5886) [#5893](https://github.com/OHIF/Viewers/issues/5893) [#5874](https://github.com/OHIF/Viewers/issues/5874) [#5865](https://github.com/OHIF/Viewers/issues/5865)
# [3.13.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.57...v3.13.0-beta.58) (2026-04-14)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.56...v3.13.0-beta.57) (2026-04-13)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.56](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.55...v3.13.0-beta.56) (2026-04-10)
### Bug Fixes
* A couple of changes to enable cs3d integration build ([#5944](https://github.com/OHIF/Viewers/issues/5944)) ([f6bbd5c](https://github.com/OHIF/Viewers/commit/f6bbd5c779e4692dc47c93327a890661b8dcc174))
# [3.13.0-beta.55](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.54...v3.13.0-beta.55) (2026-04-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.54](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.53...v3.13.0-beta.54) (2026-04-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.53](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.52...v3.13.0-beta.53) (2026-04-06)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.52](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.51...v3.13.0-beta.52) (2026-04-06)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.51](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.50...v3.13.0-beta.51) (2026-04-03)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.50](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.49...v3.13.0-beta.50) (2026-04-02)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.49](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.48...v3.13.0-beta.49) (2026-04-02)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.48](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.47...v3.13.0-beta.48) (2026-04-01)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.47](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.46...v3.13.0-beta.47) (2026-03-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.46](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.45...v3.13.0-beta.46) (2026-03-27)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.45](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.44...v3.13.0-beta.45) (2026-03-27)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.44](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.43...v3.13.0-beta.44) (2026-03-27)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.43](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.42...v3.13.0-beta.43) (2026-03-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.42](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.41...v3.13.0-beta.42) (2026-03-17)
### Features
* Add combined build ([#5895](https://github.com/OHIF/Viewers/issues/5895)) ([1df671e](https://github.com/OHIF/Viewers/commit/1df671e9ab67d43f98bf09f6838ddc0a5f220277))
# [3.13.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.40...v3.13.0-beta.41) (2026-03-16)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.39...v3.13.0-beta.40) (2026-03-13)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.38...v3.13.0-beta.39) (2026-03-13)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.37...v3.13.0-beta.38) (2026-03-12)
### Bug Fixes
* **segmentation:** Display "No description S:{series number} {modality}" for segmentations with no label. ([#5874](https://github.com/OHIF/Viewers/issues/5874)) ([7b5d0ce](https://github.com/OHIF/Viewers/commit/7b5d0ce40e5422ccfce6091ac3d7559586cbe57e))
# [3.13.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.36...v3.13.0-beta.37) (2026-03-12)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.35...v3.13.0-beta.36) (2026-03-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.34...v3.13.0-beta.35) (2026-03-09)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.33...v3.13.0-beta.34) (2026-03-09)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.32...v3.13.0-beta.33) (2026-03-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.31...v3.13.0-beta.32) (2026-03-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.30...v3.13.0-beta.31) (2026-03-04)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.29...v3.13.0-beta.30) (2026-03-04)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.28...v3.13.0-beta.29) (2026-03-04)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.27...v3.13.0-beta.28) (2026-03-03)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.26...v3.13.0-beta.27) (2026-03-02)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.25...v3.13.0-beta.26) (2026-02-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.24...v3.13.0-beta.25) (2026-02-26)
### Bug Fixes
* Update CS3D 4.18.2 ([#5837](https://github.com/OHIF/Viewers/issues/5837)) ([5370b93](https://github.com/OHIF/Viewers/commit/5370b9382e7bfddeadd69bab9e653f5f997a6e19))
# [3.13.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.23...v3.13.0-beta.24) (2026-02-24)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.22...v3.13.0-beta.23) (2026-02-23)
### Bug Fixes
* palette color 8 encoded 16 ([#5823](https://github.com/OHIF/Viewers/issues/5823)) ([eeca1f7](https://github.com/OHIF/Viewers/commit/eeca1f7a7b529d1700f5d281a6fd98074547ffe9)), closes [#5813](https://github.com/OHIF/Viewers/issues/5813)
# [3.13.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.21...v3.13.0-beta.22) (2026-02-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.20...v3.13.0-beta.21) (2026-02-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.19...v3.13.0-beta.20) (2026-02-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.18...v3.13.0-beta.19) (2026-02-20)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.17...v3.13.0-beta.18) (2026-02-19)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.16...v3.13.0-beta.17) (2026-02-19)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.15...v3.13.0-beta.16) (2026-02-18)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.14...v3.13.0-beta.15) (2026-02-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.13...v3.13.0-beta.14) (2026-02-13)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.12...v3.13.0-beta.13) (2026-02-12)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.11...v3.13.0-beta.12) (2026-02-12)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.10...v3.13.0-beta.11) (2026-02-12)
### Bug Fixes
* **colors:** Replaces legacy colors with ui-next colors ([#5351](https://github.com/OHIF/Viewers/issues/5351)) ([9a2691a](https://github.com/OHIF/Viewers/commit/9a2691a71fe3723bb05cbd148968b64e5d0fa951))
# [3.13.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.9...v3.13.0-beta.10) (2026-02-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.9) (2026-02-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.8) (2026-02-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.7) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.5...v3.13.0-beta.6) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.4...v3.13.0-beta.5) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.3...v3.13.0-beta.4) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.2...v3.13.0-beta.3) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.1...v3.13.0-beta.2) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.0...v3.13.0-beta.1) (2026-02-09)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.13.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.13.0-beta.0) (2026-02-07)
# [3.12.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.12.0) (2026-02-06)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-cornerstone-dynamic-volume",
"version": "3.13.0-beta.66",
"version": "3.12.4",
"description": "OHIF extension for 4D volumes data",
"author": "OHIF",
"license": "MIT",
@@ -29,11 +29,11 @@
"test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests"
},
"peerDependencies": {
"@ohif/core": "3.13.0-beta.66",
"@ohif/extension-cornerstone": "3.13.0-beta.66",
"@ohif/extension-default": "3.13.0-beta.66",
"@ohif/i18n": "3.13.0-beta.66",
"@ohif/ui": "3.13.0-beta.66",
"@ohif/core": "3.12.4",
"@ohif/extension-cornerstone": "3.12.4",
"@ohif/extension-default": "3.12.4",
"@ohif/i18n": "3.12.4",
"@ohif/ui": "3.12.4",
"dcmjs": "0.49.4",
"dicom-parser": "1.8.21",
"hammerjs": "2.0.8",
@@ -42,8 +42,8 @@
},
"dependencies": {
"@babel/runtime": "7.28.2",
"@cornerstonejs/core": "4.22.3",
"@cornerstonejs/tools": "4.22.3",
"@cornerstonejs/core": "4.15.29",
"@cornerstonejs/tools": "4.15.29",
"classnames": "2.5.1"
}
}
@@ -5,7 +5,7 @@ function DynamicDataPanel({ servicesManager, commandsManager, tab }: withAppType
return (
<>
<div
className="text-foreground flex flex-col"
className="flex flex-col text-white"
data-cy={'dynamic-volume-panel'}
>
<PanelGenerateImage
@@ -10,7 +10,7 @@ function WorkflowPanel({ servicesManager }: { servicesManager: ServicesManager }
return (
<div
data-cy={'workflow-panel'}
className="bg-popover mb-1 px-3 py-4"
className="bg-secondary-dark mb-1 px-3 py-4"
>
<div className="mb-1">Workflow</div>
<div>
+4 -577
View File
@@ -3,7 +3,7 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.13.0-beta.66](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.65...v3.13.0-beta.66) (2026-04-29)
## [3.12.4](https://github.com/OHIF/Viewers/compare/v3.12.3...v3.12.4) (2026-06-05)
**Note:** Version bump only for package @ohif/extension-cornerstone
@@ -11,7 +11,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
# [3.13.0-beta.65](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.64...v3.13.0-beta.65) (2026-04-29)
## [3.12.3](https://github.com/OHIF/Viewers/compare/v3.12.2...v3.12.3) (2026-05-27)
**Note:** Version bump only for package @ohif/extension-cornerstone
@@ -19,18 +19,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
# [3.13.0-beta.64](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.63...v3.13.0-beta.64) (2026-04-27)
### Bug Fixes
* **seg:** prevent segmentations from spreading to all viewports before hydration confirmation in 3D four-up ([#5967](https://github.com/OHIF/Viewers/issues/5967)) ([f8ccf9f](https://github.com/OHIF/Viewers/commit/f8ccf9ff2ea9ab7c38bd427514a8ae87902822a3))
# [3.13.0-beta.63](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.62...v3.13.0-beta.63) (2026-04-27)
## [3.12.2](https://github.com/OHIF/Viewers/compare/v3.12.1...v3.12.2) (2026-05-18)
**Note:** Version bump only for package @ohif/extension-cornerstone
@@ -38,569 +27,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
# [3.13.0-beta.62](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.61...v3.13.0-beta.62) (2026-04-23)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.60...v3.13.0-beta.61) (2026-04-23)
### Features
* **slice scrollbar:** Integrate ViewportSliceProgressScrollbar with customizations and docs ([#5960](https://github.com/OHIF/Viewers/issues/5960)) ([8fc0dc1](https://github.com/OHIF/Viewers/commit/8fc0dc16e97f3262fdac902ecf2d7c20cb8f78cc))
# [3.13.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.59...v3.13.0-beta.60) (2026-04-21)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.58...v3.13.0-beta.59) (2026-04-16)
### Bug Fixes
* Use newer ONNX version and load without errors ([#5854](https://github.com/OHIF/Viewers/issues/5854)) ([cc5dc20](https://github.com/OHIF/Viewers/commit/cc5dc201649bcbfb4cfad21141dbd56000d30f53)), closes [#5875](https://github.com/OHIF/Viewers/issues/5875) [#5884](https://github.com/OHIF/Viewers/issues/5884) [#5886](https://github.com/OHIF/Viewers/issues/5886) [#5893](https://github.com/OHIF/Viewers/issues/5893) [#5874](https://github.com/OHIF/Viewers/issues/5874) [#5865](https://github.com/OHIF/Viewers/issues/5865)
# [3.13.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.57...v3.13.0-beta.58) (2026-04-14)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.56...v3.13.0-beta.57) (2026-04-13)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.56](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.55...v3.13.0-beta.56) (2026-04-10)
### Bug Fixes
* A couple of changes to enable cs3d integration build ([#5944](https://github.com/OHIF/Viewers/issues/5944)) ([f6bbd5c](https://github.com/OHIF/Viewers/commit/f6bbd5c779e4692dc47c93327a890661b8dcc174))
# [3.13.0-beta.55](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.54...v3.13.0-beta.55) (2026-04-10)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.54](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.53...v3.13.0-beta.54) (2026-04-08)
### Bug Fixes
* **cornerstone:** read FrameOfReferenceUID from display set in viewport service ([#5950](https://github.com/OHIF/Viewers/issues/5950)) ([d219171](https://github.com/OHIF/Viewers/commit/d219171e25caf5a7c575080f63819d6f4fe45016))
# [3.13.0-beta.53](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.52...v3.13.0-beta.53) (2026-04-06)
### Reverts
* rename DisplaySet.frameOfReferenceUID back to FrameOfReferenceUID ([#5943](https://github.com/OHIF/Viewers/issues/5943)) ([0e933c2](https://github.com/OHIF/Viewers/commit/0e933c256e07b7cda35ed2ba3cfb1ab35d895d57))
# [3.13.0-beta.52](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.51...v3.13.0-beta.52) (2026-04-06)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.51](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.50...v3.13.0-beta.51) (2026-04-03)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.50](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.49...v3.13.0-beta.50) (2026-04-02)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.49](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.48...v3.13.0-beta.49) (2026-04-02)
### Bug Fixes
* **segmentation:** restrict overlay segmentation menu to same frame of reference as viewport background display set ([#5900](https://github.com/OHIF/Viewers/issues/5900)) ([b9029ef](https://github.com/OHIF/Viewers/commit/b9029ef6f8d63a0e36ec929310c1c5ad3f563ef8))
# [3.13.0-beta.48](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.47...v3.13.0-beta.48) (2026-04-01)
### Bug Fixes
* **measurement:** Restore viewport interactivity when deleting in-progress Spline or Livewire measurement ([#5905](https://github.com/OHIF/Viewers/issues/5905)) ([7929f08](https://github.com/OHIF/Viewers/commit/7929f0898f1bf882682a912b1c32d93d0944726f))
# [3.13.0-beta.47](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.46...v3.13.0-beta.47) (2026-03-28)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.46](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.45...v3.13.0-beta.46) (2026-03-27)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.45](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.44...v3.13.0-beta.45) (2026-03-27)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.44](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.43...v3.13.0-beta.44) (2026-03-27)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.43](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.42...v3.13.0-beta.43) (2026-03-17)
### Bug Fixes
* **SR:** Added support for spline and live wire SR items. ([#5870](https://github.com/OHIF/Viewers/issues/5870)) ([1d4802c](https://github.com/OHIF/Viewers/commit/1d4802c2a38dd75dca7afca87913e100453c9135))
# [3.13.0-beta.42](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.41...v3.13.0-beta.42) (2026-03-17)
### Features
* Add combined build ([#5895](https://github.com/OHIF/Viewers/issues/5895)) ([1df671e](https://github.com/OHIF/Viewers/commit/1df671e9ab67d43f98bf09f6838ddc0a5f220277))
# [3.13.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.40...v3.13.0-beta.41) (2026-03-16)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.39...v3.13.0-beta.40) (2026-03-13)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.38...v3.13.0-beta.39) (2026-03-13)
### Bug Fixes
* **window level:** The window level value is not displayed by default on all the viewports when selecting common/custom layout and TMTV. ([#5865](https://github.com/OHIF/Viewers/issues/5865)) ([fe1ecfe](https://github.com/OHIF/Viewers/commit/fe1ecfe0cc5d1bcf82686d821f356da8936a8c4b))
# [3.13.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.37...v3.13.0-beta.38) (2026-03-12)
### Bug Fixes
* **segmentation:** Display "No description S:{series number} {modality}" for segmentations with no label. ([#5874](https://github.com/OHIF/Viewers/issues/5874)) ([7b5d0ce](https://github.com/OHIF/Viewers/commit/7b5d0ce40e5422ccfce6091ac3d7559586cbe57e))
# [3.13.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.36...v3.13.0-beta.37) (2026-03-12)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.35...v3.13.0-beta.36) (2026-03-11)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.34...v3.13.0-beta.35) (2026-03-09)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.33...v3.13.0-beta.34) (2026-03-09)
### Bug Fixes
* **seg hydration:** auto-hydrate RT struct on second load with disableConfirmationPrompts ([#5875](https://github.com/OHIF/Viewers/issues/5875)) ([6f773f9](https://github.com/OHIF/Viewers/commit/6f773f997214c388409f3af3e9fc0e5b84debc10))
# [3.13.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.32...v3.13.0-beta.33) (2026-03-05)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.31...v3.13.0-beta.32) (2026-03-05)
### Features
* **ecg:** add DICOM ECG waveform extension ([#5856](https://github.com/OHIF/Viewers/issues/5856)) ([70f76ae](https://github.com/OHIF/Viewers/commit/70f76aeba1b27f8e4de5ec73a7b831428e38e3d2))
# [3.13.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.30...v3.13.0-beta.31) (2026-03-04)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.29...v3.13.0-beta.30) (2026-03-04)
### Bug Fixes
* **segmentation:** segment bidirectional tool error and show toast notification when no segment is drawn ([#5861](https://github.com/OHIF/Viewers/issues/5861)) ([7e10830](https://github.com/OHIF/Viewers/commit/7e10830d5802e22bda4df6a3f8008e9a414b4cd4))
# [3.13.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.28...v3.13.0-beta.29) (2026-03-04)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.27...v3.13.0-beta.28) (2026-03-03)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.26...v3.13.0-beta.27) (2026-03-02)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.25...v3.13.0-beta.26) (2026-02-28)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.24...v3.13.0-beta.25) (2026-02-26)
### Bug Fixes
* Update CS3D 4.18.2 ([#5837](https://github.com/OHIF/Viewers/issues/5837)) ([5370b93](https://github.com/OHIF/Viewers/commit/5370b9382e7bfddeadd69bab9e653f5f997a6e19))
# [3.13.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.23...v3.13.0-beta.24) (2026-02-24)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.22...v3.13.0-beta.23) (2026-02-23)
### Bug Fixes
* palette color 8 encoded 16 ([#5823](https://github.com/OHIF/Viewers/issues/5823)) ([eeca1f7](https://github.com/OHIF/Viewers/commit/eeca1f7a7b529d1700f5d281a6fd98074547ffe9)), closes [#5813](https://github.com/OHIF/Viewers/issues/5813)
# [3.13.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.21...v3.13.0-beta.22) (2026-02-23)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.20...v3.13.0-beta.21) (2026-02-23)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.19...v3.13.0-beta.20) (2026-02-21)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.18...v3.13.0-beta.19) (2026-02-20)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.17...v3.13.0-beta.18) (2026-02-19)
### Bug Fixes
* **segmentation overlay:** update viewport ds list upon seg delete - OHIF-2425 ([#5729](https://github.com/OHIF/Viewers/issues/5729)) ([b353541](https://github.com/OHIF/Viewers/commit/b35354120a01d89b27844f967c32c052bba8b096))
# [3.13.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.16...v3.13.0-beta.17) (2026-02-19)
### Bug Fixes
* Add copy to clipboard option for capture ([#5720](https://github.com/OHIF/Viewers/issues/5720)) ([53c67f3](https://github.com/OHIF/Viewers/commit/53c67f361234a0b4160c1b11fafcb143a0723336))
# [3.13.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.15...v3.13.0-beta.16) (2026-02-18)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.14...v3.13.0-beta.15) (2026-02-17)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.13...v3.13.0-beta.14) (2026-02-13)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.12...v3.13.0-beta.13) (2026-02-12)
### Bug Fixes
* **colors:** Replace hardcoded black with background color token ([#5815](https://github.com/OHIF/Viewers/issues/5815)) ([dbc31a5](https://github.com/OHIF/Viewers/commit/dbc31a5d4ec5b2238683a580af96aff23d9fafeb))
# [3.13.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.11...v3.13.0-beta.12) (2026-02-12)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.10...v3.13.0-beta.11) (2026-02-12)
### Bug Fixes
* **colors:** Replaces legacy colors with ui-next colors ([#5351](https://github.com/OHIF/Viewers/issues/5351)) ([9a2691a](https://github.com/OHIF/Viewers/commit/9a2691a71fe3723bb05cbd148968b64e5d0fa951))
# [3.13.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.9...v3.13.0-beta.10) (2026-02-11)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.9) (2026-02-11)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.8) (2026-02-11)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.7) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.5...v3.13.0-beta.6) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.4...v3.13.0-beta.5) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.3...v3.13.0-beta.4) (2026-02-10)
### Bug Fixes
* Better handle octet stream case ([#5789](https://github.com/OHIF/Viewers/issues/5789)) ([037402f](https://github.com/OHIF/Viewers/commit/037402f7f6a1fc07593be302e4f578f6c4870c6e))
# [3.13.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.2...v3.13.0-beta.3) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.1...v3.13.0-beta.2) (2026-02-10)
### Bug Fixes
* **cine:** prevent crash on second view/hydration of SR series ([#5724](https://github.com/OHIF/Viewers/issues/5724)) ([f70c9b9](https://github.com/OHIF/Viewers/commit/f70c9b932db2bb14173acae675d38ce250d244fa))
# [3.13.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.0...v3.13.0-beta.1) (2026-02-09)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.13.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.13.0-beta.0) (2026-02-07)
# [3.12.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.12.0) (2026-02-06)
**Note:** Version bump only for package @ohif/extension-cornerstone
+10 -10
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-cornerstone",
"version": "3.13.0-beta.66",
"version": "3.12.4",
"description": "OHIF extension for Cornerstone",
"author": "OHIF",
"license": "MIT",
@@ -40,9 +40,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.66",
"@ohif/ui": "3.13.0-beta.66",
"@cornerstonejs/dicom-image-loader": "4.15.29",
"@ohif/core": "3.12.4",
"@ohif/ui": "3.12.4",
"dcmjs": "0.49.4",
"dicom-parser": "1.8.21",
"hammerjs": "2.0.8",
@@ -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.15.29",
"@cornerstonejs/ai": "4.15.29",
"@cornerstonejs/core": "4.15.29",
"@cornerstonejs/labelmap-interpolation": "4.15.29",
"@cornerstonejs/polymorphic-segmentation": "4.15.29",
"@cornerstonejs/tools": "4.15.29",
"@icr/polyseg-wasm": "0.4.0",
"@itk-wasm/morphological-contour-interpolation": "1.1.0",
"@kitware/vtk.js": "34.15.1",
@@ -1,14 +1,13 @@
import React, { useEffect, useState } from 'react';
import ViewportImageScrollbar from './ViewportImageScrollbar';
import ViewportSliceProgressScrollbar from './ViewportSliceProgressScrollbar/ViewportSliceProgressScrollbar';
import CustomizableViewportOverlay from './CustomizableViewportOverlay';
import ViewportOrientationMarkers from './ViewportOrientationMarkers';
import ViewportImageSliceLoadingIndicator from './ViewportImageSliceLoadingIndicator';
function CornerstoneOverlays(props: withAppTypes) {
const { viewportId, element, scrollbarHeight, servicesManager } = props;
const { cornerstoneViewportService, customizationService } = servicesManager.services;
const { cornerstoneViewportService } = servicesManager.services;
const [imageSliceData, setImageSliceData] = useState({
imageIndex: 0,
numberOfSlices: 0,
@@ -44,31 +43,17 @@ function CornerstoneOverlays(props: withAppTypes) {
}
}
const viewportScrollbarVariant = customizationService.getCustomization('viewportScrollbar.variant');
const useProgressScrollbar = viewportScrollbarVariant !== 'legacy';
return (
<div className="noselect">
{useProgressScrollbar ? (
<ViewportSliceProgressScrollbar
viewportId={viewportId}
viewportData={viewportData}
element={element}
imageSliceData={imageSliceData}
setImageSliceData={setImageSliceData}
servicesManager={servicesManager}
/>
) : (
<ViewportImageScrollbar
viewportId={viewportId}
viewportData={viewportData}
element={element}
imageSliceData={imageSliceData}
setImageSliceData={setImageSliceData}
scrollbarHeight={scrollbarHeight}
servicesManager={servicesManager}
/>
)}
<ViewportImageScrollbar
viewportId={viewportId}
viewportData={viewportData}
element={element}
imageSliceData={imageSliceData}
setImageSliceData={setImageSliceData}
scrollbarHeight={scrollbarHeight}
servicesManager={servicesManager}
/>
<CustomizableViewportOverlay
imageSliceData={imageSliceData}
@@ -67,9 +67,10 @@ function CustomizableViewportOverlay({
}) {
const { cornerstoneViewportService, customizationService, toolGroupService, displaySetService } =
servicesManager.services;
const [voi, setVOI] = useState({ windowCenter: null, windowWidth: null });
const [scale, setScale] = useState(1);
const [annotationState, setAnnotationState] = useState(0);
const { isViewportBackgroundLight: isLight, windowLevel: voi } = useViewportRendering(viewportId);
const { isViewportBackgroundLight: isLight } = useViewportRendering(viewportId);
const { imageIndex } = imageSliceData;
// Historical usage defined the overlays as separate items due to lack of
@@ -109,6 +110,30 @@ function CustomizableViewportOverlay({
};
}, [viewportData, viewportId, instanceNumber, cornerstoneViewportService]);
/**
* Updating the VOI when the viewport changes its voi
*/
useEffect(() => {
const updateVOI = eventDetail => {
const { range } = eventDetail.detail;
if (!range) {
return;
}
const { lower, upper } = range;
const { windowWidth, windowCenter } = utilities.windowLevel.toWindowLevel(lower, upper);
setVOI({ windowCenter, windowWidth });
};
element.addEventListener(Enums.Events.VOI_MODIFIED, updateVOI);
return () => {
element.removeEventListener(Enums.Events.VOI_MODIFIED, updateVOI);
};
}, [viewportId, viewportData, voi, element]);
const annotationModified = useCallback(evt => {
if (evt.detail.annotation.metadata.toolName === UltrasoundPleuraBLineTool.toolName) {
// Update the annotation state to trigger a re-render
@@ -201,7 +226,6 @@ function CustomizableViewportOverlay({
scale,
instanceNumber,
annotationState,
isLight,
]
);
@@ -367,7 +391,7 @@ function OverlayItem(props) {
title={title}
>
{label ? <span className="mr-1 shrink-0">{label}</span> : null}
<span className="ml-0 shrink-0">{value}</span>
<span className="ml-0 mr-2 shrink-0">{value}</span>
</div>
);
}
@@ -378,7 +402,6 @@ function OverlayItem(props) {
*/
function VOIOverlayItem({ voi, customization }: OverlayItemProps) {
const { windowWidth, windowCenter } = voi;
const { title } = customization;
if (typeof windowCenter !== 'number' || typeof windowWidth !== 'number') {
return null;
}
@@ -387,7 +410,6 @@ function VOIOverlayItem({ voi, customization }: OverlayItemProps) {
<div
className="overlay-item flex flex-row"
style={{ color: customization?.color }}
title={title}
>
<span className="mr-0.5 shrink-0 opacity-[0.70]">W:</span>
<span className="mr-2.5 shrink-0">{windowWidth.toFixed(0)}</span>
@@ -421,13 +443,11 @@ function InstanceNumberOverlayItem({
customization,
}: OverlayItemProps) {
const { imageIndex, numberOfSlices } = imageSliceData;
const { title } = customization;
return (
<div
className="overlay-item flex flex-row"
style={{ color: (customization && customization.color) || undefined }}
title={title}
>
<span>
{instanceNumber !== undefined && instanceNumber !== null ? (
@@ -51,7 +51,7 @@ function ViewportImageSliceLoadingIndicator({ viewportData, element }) {
<>
<div className="absolute top-0 left-0 h-full w-full bg-black opacity-50">
<div className="transparent flex h-full w-full items-center justify-center">
<p className="text-highlight text-xl font-light">
<p className="text-primary-light text-xl font-light">
<h4>Error Loading Image</h4>
<p>An error has occurred.</p>
<p>{error}</p>
@@ -68,7 +68,7 @@ function ViewportImageSliceLoadingIndicator({ viewportData, element }) {
// interacting with the mouse, since scrolling should propagate to the viewport underneath
<div className="pointer-events-none absolute top-0 left-0 h-full w-full bg-black opacity-50">
<div className="transparent flex h-full w-full items-center justify-center">
<p className="text-highlight text-xl font-light">Loading...</p>
<p className="text-primary-light text-xl font-light">Loading...</p>
</div>
</div>
);
@@ -1,200 +0,0 @@
import React, { useMemo } from 'react';
import PropTypes from 'prop-types';
import { VolumeViewport3D, utilities as csUtils } from '@cornerstonejs/core';
import {
SmartScrollbar,
SmartScrollbarTrack,
SmartScrollbarFill,
SmartScrollbarIndicator,
SmartScrollbarEndpoints,
} from '@ohif/ui-next';
import { getViewportImageIds } from './helpers';
import {
useLoadedSliceBytes,
useProgressScrollbarMode,
useViewedSliceBytes,
useViewportSliceSync,
} from './hooks';
import { ViewportSliceProgressScrollbarProps } from './types';
function ViewportSliceProgressScrollbar({
viewportData,
viewportId,
element,
imageSliceData,
setImageSliceData,
servicesManager,
}: ViewportSliceProgressScrollbarProps) {
const { cineService, cornerstoneViewportService, customizationService, viewedDataService } =
servicesManager.services;
const showLoadedEndpoints =
customizationService.getCustomization('viewportScrollbar.showLoadedEndpoints') !== false;
const showLoadedFill =
customizationService.getCustomization('viewportScrollbar.showLoadedFill') !== false;
const showViewedFill =
customizationService.getCustomization('viewportScrollbar.showViewedFill') !== false;
const showLoadingPattern =
customizationService.getCustomization('viewportScrollbar.showLoadingPattern') !== false;
const viewedDwellMsRaw = customizationService.getCustomization('viewportScrollbar.viewedDwellMs');
const loadedBatchIntervalMsRaw = customizationService.getCustomization(
'viewportScrollbar.loadedBatchIntervalMs'
);
const viewedDwellMs =
typeof viewedDwellMsRaw === 'number' && viewedDwellMsRaw >= 0 ? viewedDwellMsRaw : 0;
const loadedBatchIntervalMs =
typeof loadedBatchIntervalMsRaw === 'number' && loadedBatchIntervalMsRaw >= 0
? loadedBatchIntervalMsRaw
: 200;
const { numberOfSlices, imageIndex } = imageSliceData;
const imageIds = useMemo(() => getViewportImageIds(viewportData), [viewportData]);
const imageIdToIndex = useMemo(() => {
const map = new Map<string, number>();
for (let i = 0; i < imageIds.length; i++) {
const imageId = imageIds[i];
if (imageId) {
map.set(imageId, i);
}
}
return map;
}, [imageIds]);
const isFullMode = useProgressScrollbarMode({
viewportData,
viewportId,
element,
cornerstoneViewportService,
});
useViewportSliceSync({
viewportData,
viewportId,
element,
cornerstoneViewportService,
setImageSliceData,
});
const {
bytes: loadedBytes,
version: loadedVersion,
isFull: isFullyLoaded,
} = useLoadedSliceBytes({
isFullMode,
numberOfSlices,
viewportData,
imageIds,
imageIdToIndex,
loadedBatchIntervalMs,
});
const { bytes: viewedBytes, version: viewedVersion } = useViewedSliceBytes({
isFullMode,
numberOfSlices,
imageIndex,
imageIds,
imageIdToIndex,
viewedDwellMs,
viewedDataService,
});
const onScrollbarValueChange = targetImageIndex => {
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
if (!viewport || viewport instanceof VolumeViewport3D) {
return;
}
const { isCineEnabled } = cineService.getState();
if (isCineEnabled) {
cineService.stopClip(element, { viewportId });
cineService.setCine({ id: viewportId, frameRate: undefined, isPlaying: false });
}
csUtils.jumpToSlice(viewport.element, {
imageIndex: targetImageIndex,
debounceLoading: true,
});
};
const isLoading = isFullMode && showLoadingPattern ? !isFullyLoaded : false;
if (!numberOfSlices || numberOfSlices <= 1) {
return null;
}
return (
<div
style={{
position: 'absolute',
right: 0,
top: 0,
height: '100%',
padding: '8px 5px',
zIndex: 10,
}}
>
<div
style={{
position: 'relative',
height: '100%',
width: '11px',
}}
>
<SmartScrollbar
className="absolute inset-0"
value={imageIndex || 0}
total={numberOfSlices}
onValueChange={onScrollbarValueChange}
isLoading={isLoading}
enableKeyboardNavigation={false}
aria-label="Image navigation scrollbar"
indicator={
customizationService.getCustomization('viewportScrollbar.indicator') as
| Record<string, unknown>
| undefined
}
>
<SmartScrollbarTrack>
{isFullMode && showLoadedFill && (
<SmartScrollbarFill
marked={loadedBytes}
version={loadedVersion}
className="bg-neutral/25"
loadingClassName="bg-neutral/50"
/>
)}
{isFullMode && showViewedFill && (
<SmartScrollbarFill
marked={viewedBytes}
version={viewedVersion}
className="bg-primary/35"
loadingClassName="bg-primary/35"
/>
)}
</SmartScrollbarTrack>
<SmartScrollbarIndicator />
{isFullMode && showLoadedEndpoints && (
<SmartScrollbarEndpoints
marked={loadedBytes}
version={loadedVersion}
/>
)}
</SmartScrollbar>
</div>
</div>
);
}
ViewportSliceProgressScrollbar.propTypes = {
viewportData: PropTypes.object,
viewportId: PropTypes.string.isRequired,
element: PropTypes.instanceOf(Element),
imageSliceData: PropTypes.object.isRequired,
setImageSliceData: PropTypes.func.isRequired,
servicesManager: PropTypes.object.isRequired,
};
export default ViewportSliceProgressScrollbar;
@@ -1,40 +0,0 @@
import { Enums, VolumeViewport3D } from '@cornerstonejs/core';
import { ViewportData } from './types';
export function getImageIndexFromEvent(event): number | undefined {
const { imageIndex, newImageIdIndex = imageIndex, imageIdIndex } = event.detail;
return newImageIdIndex ?? imageIdIndex;
}
export function getViewportImageIds(viewportData: ViewportData): string[] {
if (!viewportData?.data?.length) {
return [];
}
const firstData = viewportData.data[0];
const volumeImageIds = (firstData as any).volume?.imageIds as string[] | undefined;
const datumImageIds = (firstData as any).imageIds as string[] | undefined;
return volumeImageIds || datumImageIds || [];
}
export function isProgressFullMode(viewportData: ViewportData, viewport): boolean {
if (!viewportData || !viewport || viewport instanceof VolumeViewport3D) {
return false;
}
if (viewportData.viewportType === Enums.ViewportType.STACK) {
return true;
}
if (viewportData.viewportType === Enums.ViewportType.ORTHOGRAPHIC) {
return !!viewport.isInAcquisitionPlane?.();
}
return false;
}
export function getImageIdFromCacheEvent(event): string | undefined {
const detail = event?.detail;
return detail?.imageId || detail?.image?.imageId || detail?.cachedImage?.imageId;
}
@@ -1,353 +0,0 @@
import { useEffect, useRef, useState } from 'react';
import {
cache as cornerstoneCache,
Enums,
eventTarget,
utilities,
VolumeViewport3D,
} from '@cornerstonejs/core';
import { useByteArray } from '@ohif/ui-next';
import { getImageIdFromCacheEvent, getImageIndexFromEvent, isProgressFullMode } from './helpers';
import { ImageSliceData, ViewportData } from './types';
export function useProgressScrollbarMode({
viewportData,
viewportId,
element,
cornerstoneViewportService,
}: {
viewportData: ViewportData;
viewportId: string;
element: HTMLElement;
cornerstoneViewportService: AppTypes.CornerstoneViewportService;
}) {
const [isFullMode, setIsFullMode] = useState(false);
const lastViewPlaneNormalRef = useRef<number[] | null>(null);
/**
* Tracks whether this viewport should render full progress UI (stack or acquisition-plane
* orthographic volume) versus minimal UI. We compute once on setup and recompute on each
* CAMERA_MODIFIED event so stack->MPR transitions and acquisition-plane changes are reflected
* immediately.
*/
useEffect(() => {
if (!viewportData) {
return;
}
const updateMode = () => {
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
const viewportImageData = viewport?.getImageData?.();
const nextViewPlaneNormal = viewport?.getCamera?.()?.viewPlaneNormal as number[] | undefined;
// Do not update the lastViewPlaneNormalRef until we have a valid viewportImageData.
// Without viewportImageData, the viewport is not fully initialized and the isAcquisitionPlane
// check will not be accurate.
if (viewportImageData && nextViewPlaneNormal) {
lastViewPlaneNormalRef.current = [...nextViewPlaneNormal];
}
const nextMode = isProgressFullMode(viewportData, viewport);
setIsFullMode(prevMode => (prevMode === nextMode ? prevMode : nextMode));
};
updateMode();
const onCameraModified = () => {
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
const nextViewPlaneNormal = viewport?.getCamera?.()?.viewPlaneNormal as number[] | undefined;
const previousViewPlaneNormal = lastViewPlaneNormalRef.current;
// Ignore camera updates that keep the same orientation (pan/zoom/scroll).
if (nextViewPlaneNormal && previousViewPlaneNormal) {
if (utilities.isEqual(nextViewPlaneNormal, previousViewPlaneNormal)) {
return;
}
}
updateMode();
};
element.addEventListener(Enums.Events.CAMERA_MODIFIED, onCameraModified);
return () => {
element.removeEventListener(Enums.Events.CAMERA_MODIFIED, onCameraModified);
};
}, [viewportData, viewportId, cornerstoneViewportService, element]);
return isFullMode;
}
export function useViewportSliceSync({
viewportData,
viewportId,
element,
cornerstoneViewportService,
setImageSliceData,
}: {
viewportData: ViewportData;
viewportId: string;
element: HTMLElement;
cornerstoneViewportService: AppTypes.CornerstoneViewportService;
setImageSliceData: (data: ImageSliceData) => void;
}) {
/**
* Keeps shared slice state in sync: first initialize from the live viewport snapshot, then
* subscribe to navigation/render events for incremental updates while users scroll.
*/
useEffect(() => {
if (!viewportData) {
return;
}
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
if (viewport && !(viewport instanceof VolumeViewport3D)) {
try {
const currentImageIndex = viewport.getCurrentImageIdIndex();
const currentNumberOfSlices = viewport.getNumberOfSlices();
setImageSliceData({
imageIndex: currentImageIndex,
numberOfSlices: currentNumberOfSlices,
});
} catch (error) {
console.warn(error);
}
}
const { viewportType } = viewportData;
const eventId =
(viewportType === Enums.ViewportType.STACK && Enums.Events.STACK_NEW_IMAGE) ||
(viewportType === Enums.ViewportType.ORTHOGRAPHIC && Enums.Events.VOLUME_NEW_IMAGE) ||
Enums.Events.IMAGE_RENDERED;
const updateIndex = event => {
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
if (!viewport || viewport instanceof VolumeViewport3D) {
return;
}
const nextImageIndex = getImageIndexFromEvent(event);
if (nextImageIndex == null) {
return;
}
const nextNumberOfSlices = viewport.getNumberOfSlices();
setImageSliceData({
imageIndex: nextImageIndex,
numberOfSlices: nextNumberOfSlices,
});
};
element.addEventListener(eventId, updateIndex);
return () => {
element.removeEventListener(eventId, updateIndex);
};
}, [viewportData, element, viewportId, cornerstoneViewportService, setImageSliceData]);
}
export function useLoadedSliceBytes({
isFullMode,
numberOfSlices,
viewportData,
imageIds,
imageIdToIndex,
loadedBatchIntervalMs,
}: {
isFullMode: boolean;
numberOfSlices: number;
viewportData: ViewportData;
imageIds: string[];
imageIdToIndex: Map<string, number>;
loadedBatchIntervalMs: number;
}) {
const loadedState = useByteArray(numberOfSlices || 0, loadedBatchIntervalMs);
const {
resetWith: resetLoaded,
setByte: setLoadedByte,
clearByte: clearLoadedByte,
} = loadedState;
/**
* Keeps the loaded byte array in sync with Cornerstone cache: seed from cache whenever stack /
* mode / slice count changes, then subscribe so cache add/remove updates stay incremental.
* Seeding runs immediately before registering listeners in the same effect.
*/
useEffect(() => {
if (isFullMode && numberOfSlices) {
resetLoaded(bytes => {
for (let i = 0; i < bytes.length; i++) {
const imageId = imageIds[i];
if (imageId && cornerstoneCache.isLoaded(imageId)) {
bytes[i] = 1;
}
}
});
}
if (!isFullMode || !viewportData) {
return;
}
const markLoaded = event => {
const imageId = getImageIdFromCacheEvent(event);
if (!imageId) {
return;
}
const index = imageIdToIndex.get(imageId);
if (index !== undefined) {
setLoadedByte(index);
}
};
const markRemoved = event => {
const imageId = getImageIdFromCacheEvent(event);
if (!imageId) {
return;
}
const index = imageIdToIndex.get(imageId);
if (index !== undefined) {
clearLoadedByte(index);
}
};
eventTarget.addEventListener(Enums.Events.IMAGE_CACHE_IMAGE_ADDED, markLoaded);
eventTarget.addEventListener(Enums.Events.IMAGE_CACHE_IMAGE_REMOVED, markRemoved);
return () => {
eventTarget.removeEventListener(Enums.Events.IMAGE_CACHE_IMAGE_ADDED, markLoaded);
eventTarget.removeEventListener(Enums.Events.IMAGE_CACHE_IMAGE_REMOVED, markRemoved);
};
}, [
imageIds,
isFullMode,
numberOfSlices,
viewportData,
imageIdToIndex,
resetLoaded,
setLoadedByte,
clearLoadedByte,
]);
return loadedState;
}
export function useViewedSliceBytes({
isFullMode,
numberOfSlices,
imageIndex,
imageIds,
imageIdToIndex,
viewedDwellMs,
viewedDataService,
}: {
isFullMode: boolean;
numberOfSlices: number;
imageIndex: number;
imageIds: string[];
imageIdToIndex: Map<string, number>;
viewedDwellMs: number;
viewedDataService: AppTypes.ViewedDataService;
}) {
const viewedState = useByteArray(numberOfSlices || 0);
const { resetWith: resetViewed, setByte: setViewedByte } = viewedState;
/**
* Keeps the viewed byte array in sync with the global viewed-data store: seed from the store
* whenever stack / mode / slice count changes, then subscribe so `markDataViewed` updates stay
* incremental. Seeding runs immediately before registering the listener in the same effect.
*/
useEffect(() => {
if (isFullMode && numberOfSlices) {
resetViewed(bytes => {
for (let i = 0; i < bytes.length; i++) {
const imageId = imageIds[i];
if (imageId && viewedDataService?.isDataViewed(imageId)) {
bytes[i] = 1;
}
}
});
}
if (!viewedDataService) {
return;
}
const subscription = viewedDataService.subscribeViewedDataChanges(
({
viewedDataId,
viewedDataCleared,
}: {
viewedDataId?: string;
viewedDataCleared?: boolean;
}) => {
if (!isFullMode || !numberOfSlices) {
return;
}
if (viewedDataCleared) {
resetViewed(bytes => {
bytes.fill(0);
});
return;
}
const index = imageIdToIndex.get(viewedDataId);
if (index !== undefined) {
setViewedByte(index);
}
}
);
return () => {
subscription.unsubscribe();
};
}, [
imageIds,
isFullMode,
numberOfSlices,
imageIdToIndex,
resetViewed,
setViewedByte,
viewedDataService,
]);
/**
* Marks slices as viewed in full mode. With `viewedDwellMs === 0`, marking is immediate on
* index change; otherwise a dwell timer is used and cleaned up on subsequent changes/unmount.
*/
useEffect(() => {
if (!isFullMode || !numberOfSlices) {
return;
}
const markViewed = (targetIndex: number) => {
setViewedByte(targetIndex);
const imageId = imageIds[targetIndex];
if (imageId) {
viewedDataService?.markDataViewed(imageId);
}
};
if (viewedDwellMs === 0) {
markViewed(imageIndex || 0);
return;
}
const timerId = window.setTimeout(() => {
markViewed(imageIndex || 0);
}, viewedDwellMs);
return () => {
window.clearTimeout(timerId);
};
}, [
isFullMode,
numberOfSlices,
imageIndex,
imageIds,
setViewedByte,
viewedDwellMs,
viewedDataService,
]);
return viewedState;
}
@@ -1 +0,0 @@
export { default } from './ViewportSliceProgressScrollbar';
@@ -1,17 +0,0 @@
import { StackViewportData, VolumeViewportData } from '../../../types/CornerstoneCacheService';
export type ViewportData = StackViewportData | VolumeViewportData;
export type ImageSliceData = {
imageIndex: number;
numberOfSlices: number;
};
export type ViewportSliceProgressScrollbarProps = {
viewportData: ViewportData | null;
viewportId: string;
element: HTMLElement;
imageSliceData: ImageSliceData;
setImageSliceData: (data: ImageSliceData) => void;
servicesManager: AppTypes.ServicesManager;
};
+7 -40
View File
@@ -398,31 +398,12 @@ function commandsModule({
const { segmentationId: targetId, segmentIndex: targetIndex } = targetSegmentation;
// Check if the segment has voxels before computing bidirectional measurement
const uniqueSegmentIndices = cstUtils.segmentation.getUniqueSegmentIndices(targetId);
const hasVoxels = uniqueSegmentIndices.includes(targetIndex);
if (!hasVoxels) {
uiNotificationService.show({
title: i18n.t('SegmentationPanel:Segment Bidirectional'),
message: i18n.t(
'SegmentationPanel:Draw a segment before using bidirectional measurement'
),
type: 'warning',
});
return;
}
// Get bidirectional measurement data
const bidirectionalData = await cstUtils.segmentation.getSegmentLargestBidirectional({
segmentationId: targetId,
segmentIndices: [targetIndex],
});
if (!bidirectionalData.length) {
return;
}
const activeViewportId = viewportGridService.getActiveViewportId();
// Process each bidirectional measurement
@@ -464,7 +445,7 @@ function commandsModule({
measurement => measurement.segmentIndex === targetIndex
);
commandsManager.run('jumpToMeasurement', {
uid: activeBidirectional?.annotationUID,
uid: activeBidirectional.annotationUID,
});
},
interpolateLabelmap: () => {
@@ -756,9 +737,6 @@ function commandsModule({
* Also marks any provided display measurements isActive value
*/
jumpToMeasurement: ({ uid, displayMeasurements = [] }) => {
if (!uid) {
return;
}
measurementService.jumpToMeasurement(viewportGridService.getActiveViewportId(), uid);
for (const measurement of displayMeasurements) {
measurement.isActive = measurement.uid === uid;
@@ -1757,14 +1735,12 @@ function commandsModule({
* Removes a segmentation from the viewport
* @param props.segmentationId - The ID of the segmentation to remove
*/
removeSegmentationFromViewportCommand: ({ segmentationId: displaySetInstanceUID }) => {
const { viewportGridService } = servicesManager.services;
const viewportId = viewportGridService.getActiveViewportId();
commandsManager.runCommand('removeDisplaySetLayer', {
viewportId,
displaySetInstanceUID,
});
removeSegmentationFromViewportCommand: ({ segmentationId }) => {
const { segmentationService, viewportGridService } = servicesManager.services;
segmentationService.removeSegmentationRepresentations(
viewportGridService.getActiveViewportId(),
{ segmentationId }
);
},
/**
@@ -2096,15 +2072,6 @@ function commandsModule({
displaySetInstanceUIDs,
});
if (!updatedViewports?.length) {
return;
}
updatedViewports.forEach(({ viewportId: csViewportId }) => {
const csViewport = cornerstoneViewportService.getCornerstoneViewport(csViewportId);
csViewport?.setNeedsRender?.();
});
actions.setDisplaySetsForViewports({
viewportsToUpdate: updatedViewports.map(viewport => ({
viewportId: viewport.viewportId,
@@ -91,14 +91,14 @@ function DefaultAccordion(props) {
return null;
}
if (asChild) {
if (Boolean(asChild)) {
return React.cloneElement(props.children, props);
}
return (
<Accordion
type={grouping.type || 'multiple'}
className="text-foreground"
className="text-white"
defaultValue={defaultValue}
>
{[...groups.entries()].map(([key, group]) => {
@@ -16,7 +16,7 @@ type DicomUploadProps = {
function DicomUpload({ dataSource, onComplete, onStarted }: DicomUploadProps): ReactElement {
const baseClassNames =
'min-h-[375px] flex flex-col bg-background select-none rounded-lg overflow-hidden';
'min-h-[375px] flex flex-col bg-black select-none rounded-lg overflow-hidden';
const [dicomFileUploaderArr, setDicomFileUploaderArr] = useState([]);
const onDrop = useCallback(async acceptedFiles => {
@@ -276,7 +276,7 @@ function DicomUploadProgress({
const getNumCompletedAndTimeRemainingComponent = (): ReactElement => {
return (
<div className="bg-muted text-foreground flex h-14 items-center px-1 pb-4 text-lg">
<div className="bg-muted flex h-14 items-center px-1 pb-4 text-lg text-white">
{numFilesCompleted === dicomFileUploaderArr.length ? (
<>
<span className={NO_WRAP_ELLIPSIS_CLASS_NAMES}>{`${dicomFileUploaderArr.length} ${
@@ -372,7 +372,7 @@ function DicomUploadProgress({
return (
<div className="flex grow flex-col">
{getNumCompletedAndTimeRemainingComponent()}
<div className="flex grow flex-col overflow-hidden bg-background text-lg">
<div className="flex grow flex-col overflow-hidden bg-black text-lg">
{getPercentCompleteComponent()}
<div className="ohif-scrollbar h-1 grow overflow-y-scroll px-2">
{dicomFileUploaderArr
@@ -75,7 +75,7 @@ const DicomUploadProgressItem = memo(
<div className="self-top flex w-0 shrink grow flex-col gap-1">
<div className="flex gap-4">
<div className="flex w-6 shrink-0 items-center justify-center">{getStatusIcon()}</div>
<div className="text-foreground overflow-hidden text-ellipsis whitespace-nowrap">
<div className="overflow-hidden text-ellipsis whitespace-nowrap text-white">
{dicomFileUploader.getFileName()}
</div>
</div>
@@ -5,7 +5,9 @@ import {
DropdownMenuSubTrigger,
DropdownMenuPortal,
DropdownMenuSubContent,
DropdownMenuLabel,
DropdownMenuItem,
DropdownMenuSeparator,
Icons,
} from '@ohif/ui-next';
@@ -17,6 +19,8 @@ interface ExportSegmentationSubMenuItemProps {
allowExport: boolean;
actions: {
storeSegmentation: (segmentationId: string, modality?: string) => Promise<unknown>;
onSegmentationDownloadRTSS: (segmentationId: string) => void;
onSegmentationDownload: (segmentationId: string) => void;
downloadCSVSegmentationReport: (segmentationId: string) => void;
};
}
@@ -33,10 +37,14 @@ export const ExportSegmentationSubMenuItem: React.FC<ExportSegmentationSubMenuIt
<DropdownMenuSub>
<DropdownMenuSubTrigger className="pl-1">
<Icons.Export className="text-foreground" />
<span className="pl-2">{t('Export')}</span>
<span className="pl-2">{t('Download & Export')}</span>
</DropdownMenuSubTrigger>
<DropdownMenuPortal>
<DropdownMenuSubContent>
<DropdownMenuLabel className="flex items-center pl-0">
<Icons.Download className="h-5 w-5" />
<span className="pl-1">{t('Download')}</span>
</DropdownMenuLabel>
{segmentationRepresentationType === SegmentationRepresentations.Labelmap && (
<DropdownMenuItem
onClick={e => {
@@ -48,6 +56,31 @@ export const ExportSegmentationSubMenuItem: React.FC<ExportSegmentationSubMenuIt
{t('CSV Report')}
</DropdownMenuItem>
)}
{segmentationRepresentationType === SegmentationRepresentations.Labelmap && (
<DropdownMenuItem
onClick={e => {
e.preventDefault();
actions.onSegmentationDownload(segmentationId);
}}
disabled={!allowExport}
>
{t('DICOM SEG')}
</DropdownMenuItem>
)}
<DropdownMenuItem
onClick={e => {
e.preventDefault();
actions.onSegmentationDownloadRTSS(segmentationId);
}}
disabled={!allowExport}
>
{t('DICOM RTSS')}
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuLabel className="flex items-center pl-0">
<Icons.Export className="h-5 w-5" />
<span className="pl-1 pt-1">{t('Export')}</span>
</DropdownMenuLabel>
{segmentationRepresentationType === SegmentationRepresentations.Labelmap && (
<DropdownMenuItem
onClick={e => {
@@ -122,9 +122,9 @@ function ModalityLoadBadge({ viewportId }: { viewportId: string }) {
return (
<div
data-cy={`ModalityLoadBadge-${viewportId}`}
className="text-foreground flex h-6 cursor-default text-sm leading-6"
className="flex h-6 cursor-default text-sm leading-6 text-white"
>
<div className="bg-popover flex min-w-[45px] items-center rounded-l-xl rounded-r p-1">
<div className="bg-customgray-100 flex min-w-[45px] items-center rounded-l-xl rounded-r p-1">
<StatusIcon />
<span className="ml-1">{statusInfo.type}</span>
</div>
@@ -28,7 +28,7 @@ export default function PanelAccordionTrigger(props) {
<div className={`inline-flex text-base ${isActive ? 'bg-popover' : 'bg-muted'} flex-grow`}>
<button onClick={onClickDefault.bind(props)}>
<span
className={`inline-flex rounded-l border-r border-background ${isActive ? 'bg-highlight' : 'bg-muted'}`}
className={`inline-flex rounded-l border-r border-black ${isActive ? 'bg-highlight' : 'bg-muted'}`}
>
{count !== undefined ? <span className="px-2">{count}</span> : null}
{colorHex && <ColorCircle colorHex={colorHex} />}
@@ -34,7 +34,7 @@ export default function SegmentationToolConfig() {
};
return (
<div className="bg-muted flex flex-col gap-2 border-b border-b-[2px] border-background px-2 py-3">
<div className="bg-muted flex flex-col gap-2 border-b border-b-[2px] border-black px-2 py-3">
<div className="flex items-center gap-2">
<Switch
checked={previewEdits}
@@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react';
import React, { useState } from 'react';
import {
Button,
Icons,
@@ -43,10 +43,6 @@ function ViewportDataOverlayMenu({ viewportId }: withAppTypes<{ viewportId: stri
const [thresholdOpacityEnabled, setThresholdOpacityEnabled] = useState(false);
useEffect(() => {
setOptimisticOverlayDisplaySets(overlayDisplaySets);
}, [backgroundDisplaySet?.displaySetInstanceUID, overlayDisplaySets]);
/**
* Change the background display set
*/
@@ -486,10 +482,7 @@ function ViewportDataOverlayMenu({ viewportId }: withAppTypes<{ viewportId: stri
}
}}
>
<SelectTrigger
className="flex-1"
data-cy={`overlay-background-ds-select-${viewportId}`}
>
<SelectTrigger className="flex-1">
<SelectValue>
{(
backgroundDisplaySet?.SeriesDescription ||
@@ -203,7 +203,7 @@ function ViewportOrientationMenu({
<div className="flex-1 text-left">Acquisition</div>
</Button>
{/* Divider */}
<div className="border-input mx-1 my-2 border-t" />
<div className="mx-1 my-2 border-t border-white/20" />
<Button
variant="ghost"
className="flex h-7 w-full flex-shrink-0 items-center justify-start self-stretch px-1 py-0"
@@ -61,7 +61,7 @@ export function VolumeRenderingPresetsContent({ presets, viewportId, hide }: Pro
className={
selectedPreset?.name === preset.name
? 'border-highlight h-[75px] w-[95px] max-w-none rounded border-2'
: 'hover:border-highlight h-[75px] w-[95px] max-w-none rounded border-2 border-background'
: 'hover:border-highlight h-[75px] w-[95px] max-w-none rounded border-2 border-black'
}
/>
<label className="text-muted-foreground mt-1 text-left text-xs">
@@ -64,6 +64,12 @@ export const CustomDropdownMenuContent = () => {
context: 'CORNERSTONE',
});
},
onSegmentationDownloadRTSS: segmentationId => {
commandsManager.run('downloadRTSS', { segmentationId });
},
onSegmentationDownload: segmentationId => {
commandsManager.run('downloadSegmentation', { segmentationId });
},
downloadCSVSegmentationReport: segmentationId => {
commandsManager.run('downloadCSVSegmentationReport', { segmentationId });
},
@@ -1,5 +1,5 @@
import React, { useState, useEffect } from 'react';
import { ImageModal, FooterAction, toast } from '@ohif/ui-next';
import { ImageModal, FooterAction } from '@ohif/ui-next';
import { useTranslation } from 'react-i18next';
const MAX_TEXTURE_SIZE = 10000;
const DEFAULT_FILENAME = 'image';
@@ -16,7 +16,6 @@ interface ViewportDownloadFormNewProps {
onEnableViewport: (element: HTMLElement) => void;
onDisableViewport: () => void;
onDownload: (filename: string, fileType: string) => void;
onCopyToClipboard: () => void;
warningState: { enabled: boolean; value: string };
}
@@ -33,7 +32,6 @@ function ViewportDownloadFormNew({
onEnableViewport,
onDisableViewport,
onDownload,
onCopyToClipboard,
}: ViewportDownloadFormNewProps) {
const [viewportElement, setViewportElement] = useState<HTMLElement | null>(null);
const [showWarningMessage, setShowWarningMessage] = useState(true);
@@ -68,7 +66,7 @@ function ViewportDownloadFormNew({
>
{warningState.enabled && showWarningMessage && (
<div
className="text-foreground absolute left-1/2 bottom-[5px] z-[1000] -translate-x-1/2 whitespace-nowrap rounded bg-background p-3 text-xs font-bold"
className="text-foreground absolute left-1/2 bottom-[5px] z-[1000] -translate-x-1/2 whitespace-nowrap rounded bg-black p-3 text-xs font-bold"
style={{
fontSize: '12px',
}}
@@ -140,27 +138,13 @@ function ViewportDownloadFormNew({
<FooterAction.Secondary onClick={onClose}>
{t('Common:Cancel')}
</FooterAction.Secondary>
<FooterAction.Secondary
onClick={async () => {
try {
await onCopyToClipboard();
toast.success(t('Image copied to clipboard'));
onClose();
} catch (error) {
toast.error(t('Failed to copy image to clipboard'));
console.error('Failed to copy to clipboard:', error);
}
}}
>
{t('Copy to Clipboard')}
</FooterAction.Secondary>
<FooterAction.Primary
onClick={() => {
onDownload(filename || DEFAULT_FILENAME, fileType);
onClose();
}}
>
{t('Save Image')}
{t('Common:Save')}
</FooterAction.Primary>
</FooterAction.Right>
</FooterAction>
@@ -25,7 +25,6 @@ export default {
{
id: 'WindowLevel',
inheritsFrom: 'ohif.overlayItem.windowLevel',
title: 'Window Level',
},
{
id: 'ZoomLevel',
@@ -40,7 +39,6 @@ export default {
{
id: 'InstanceNumber',
inheritsFrom: 'ohif.overlayItem.instanceNumber',
title: 'Instance Number',
},
],
};
@@ -1,27 +0,0 @@
/**
* Default customization values for viewport scrollbar behavior.
* The `progress` scrollbar variant is in full mode for stack viewports and
* acquisition-plane orthographic viewports.
* Otherwise, viewports using the `progress` scrollbar show only the indicator.
*
* - `viewportScrollbar.variant`: `'progress' | 'legacy'` (default: `'progress'`)
* - `viewportScrollbar.showLoadedEndpoints`: show loaded-range endpoint caps in full mode
* - `viewportScrollbar.showLoadedFill`: show loaded/cached fill in full mode
* - `viewportScrollbar.showViewedFill`: show viewed fill in full mode
* - `viewportScrollbar.showLoadingPattern`: show loading pattern in full mode while not fully loaded
* - `viewportScrollbar.viewedDwellMs`: delay before marking current image viewed in full mode (ms)
* - `viewportScrollbar.loadedBatchIntervalMs`: loaded-state version batch interval in full mode (ms)
* - `viewportScrollbar.indicator`: optional custom indicator config
*/
export default function getViewportScrollbarCustomization() {
return {
'viewportScrollbar.variant': 'progress',
'viewportScrollbar.showLoadedEndpoints': true,
'viewportScrollbar.showLoadedFill': true,
'viewportScrollbar.showViewedFill': true,
'viewportScrollbar.showLoadingPattern': true,
'viewportScrollbar.viewedDwellMs': 0,
'viewportScrollbar.loadedBatchIntervalMs': 200,
'viewportScrollbar.indicator': {},
};
}
@@ -11,7 +11,6 @@ import windowLevelPresetsCustomization from './customizations/windowLevelPresets
import miscCustomization from './customizations/miscCustomization';
import captureViewportModalCustomization from './customizations/captureViewportModalCustomization';
import viewportDownloadWarningCustomization from './customizations/viewportDownloadWarningCustomization';
import getViewportScrollbarCustomization from './customizations/viewportScrollbarCustomization';
function getCustomizationModule({ commandsManager, servicesManager, extensionManager }) {
return [
@@ -35,7 +34,6 @@ function getCustomizationModule({ commandsManager, servicesManager, extensionMan
...miscCustomization,
...captureViewportModalCustomization,
...viewportDownloadWarningCustomization,
...getViewportScrollbarCustomization(),
},
},
];
@@ -3,7 +3,6 @@ import i18n from '@ohif/i18n';
import { utilities as csUtils, Enums as csEnums } from '@cornerstonejs/core';
import dcmjs from 'dcmjs';
import { dicomWebUtils } from '@ohif/extension-default';
import { buildEcgModule } from './utils/ecgMetadata';
const { MetadataModules } = csEnums;
const { utils } = OHIF;
@@ -156,84 +155,6 @@ export function getDicomMicroscopySopClassHandler({ servicesManager, extensionMa
};
}
/**
* DICOM Waveform SOP Class UIDs for ECG / cardiac electrophysiology.
* Reference: https://dicom.nema.org/medical/dicom/current/output/chtml/part04/sect_B.5.html
*/
const ECG_SOP_CLASS_UIDS = {
TWELVE_LEAD_ECG_WAVEFORM_STORAGE: '1.2.840.10008.5.1.4.1.1.9.1.1',
GENERAL_ECG_WAVEFORM_STORAGE: '1.2.840.10008.5.1.4.1.1.9.1.2',
AMBULATORY_ECG_WAVEFORM_STORAGE: '1.2.840.10008.5.1.4.1.1.9.1.3',
HEMODYNAMIC_WAVEFORM_STORAGE: '1.2.840.10008.5.1.4.1.1.9.2.1',
CARDIAC_ELECTROPHYSIOLOGY_WAVEFORM_STORAGE: '1.2.840.10008.5.1.4.1.1.9.3.1',
};
const ecgSopClassUids = Object.values(ECG_SOP_CLASS_UIDS);
const DicomEcgSOPClassHandlerId =
'@ohif/extension-cornerstone.sopClassHandlerModule.DicomEcgSopClassHandler';
function _getEcgDisplaySetsFromSeries(instances, servicesManager) {
const { userAuthenticationService } = servicesManager.services;
return instances.map(instance => {
const { Modality, SOPInstanceUID } = instance;
const { SeriesDescription, SeriesNumber, SeriesDate } = instance;
const { SeriesInstanceUID, StudyInstanceUID, SOPClassUID } = instance;
const imageId = instance.imageId;
// Register ECG metadata in the OHIF metadata provider so that
// Cornerstone's ECGViewport can retrieve it via metaData.get('ecgModule', imageId).
if (imageId) {
const ecgModule = buildEcgModule(instance, userAuthenticationService);
if (ecgModule) {
csUtils.genericMetadataProvider.addRaw(imageId, {
type: MetadataModules.ECG,
metadata: ecgModule,
});
}
}
return {
Modality,
displaySetInstanceUID: utils.guid(),
SeriesDescription,
SeriesNumber,
SeriesDate,
SOPInstanceUID,
SeriesInstanceUID,
StudyInstanceUID,
SOPClassHandlerId: DicomEcgSOPClassHandlerId,
SOPClassUID,
referencedImages: null,
measurements: null,
viewportType: csEnums.ViewportType.ECG,
instances: [instance],
instance,
thumbnailSrc: null,
isDerivedDisplaySet: false,
isLoaded: false,
sopClassUids: ecgSopClassUids,
numImageFrames: 0,
numInstances: 1,
imageIds: imageId ? [imageId] : [],
supportsWindowLevel: false,
label: SeriesDescription || 'ECG',
};
});
}
export function getDicomEcgSopClassHandler({ servicesManager }) {
const getDisplaySetsFromSeries = instances =>
_getEcgDisplaySetsFromSeries(instances, servicesManager);
return {
name: 'DicomEcgSopClassHandler',
sopClassUids: ecgSopClassUids,
getDisplaySetsFromSeries,
};
}
export function getSopClassHandlerModule(params) {
return [getDicomMicroscopySopClassHandler(params), getDicomEcgSopClassHandler(params)];
return [getDicomMicroscopySopClassHandler(params)];
}
@@ -10,7 +10,6 @@ import {
BaseVolumeViewport,
cache,
} from '@cornerstonejs/core';
import { getDataIdForViewport } from '../utils/getDataIdForViewport';
import { WindowLevelPreset } from '../types/WindowLevel';
import { ColorbarPositionType, ColorbarOptions, ColorbarProperties } from '../types/Colorbar';
import { VolumeRenderingConfig } from '../types/VolumeRenderingConfig';
@@ -105,6 +104,11 @@ const opacityToLinear = (opacityValue: number): number => {
return Math.pow(opacityValue, 1.0 / GAMMA);
};
const is3DViewport = ({ viewportId, cornerstoneViewportService }) => {
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
return viewport instanceof VolumeViewport3D;
};
/**
* Hook to access window level functionality for a specific viewport
*
@@ -120,17 +124,15 @@ export function useViewportRendering(
const { cornerstoneViewportService, colorbarService, customizationService } =
servicesManager.services;
const [is3DVolume, setIs3DVolume] = useState(
is3DViewport({ viewportId, cornerstoneViewportService })
);
const [hasColorbar, setHasColorbar] = useState(colorbarService.hasColorbar(viewportId));
const [colorbarPosition, setColorbarPosition] = useState<ColorbarPositionType>(
options?.location ? getPosition(options.location) : 'bottom'
);
const [voiRange, setVoiRange] = useState<{ lower: number; upper: number } | undefined>();
const voiRangeRef = React.useRef<{ lower: number; upper: number } | undefined>();
// Viewport from service; kept in state so we can subscribe to VIEWPORT_DATA_CHANGED when null and re-run effects when it becomes available
const [viewport, setViewport] = useState<Types.IViewport | null>(() =>
viewportId ? (cornerstoneViewportService.getCornerstoneViewport(viewportId) ?? null) : null
);
const [is3DVolume, setIs3DVolume] = useState(viewport instanceof VolumeViewport3D);
const [opacity, setOpacityState] = useState<number | undefined>();
const [opacityLinear, setOpacityLinearState] = useState<number | undefined>();
const [threshold, setThresholdState] = useState<number | undefined>();
@@ -176,34 +178,6 @@ export function useViewportRendering(
);
}, [viewportDisplaySets, presets]);
// Keep viewport in state; when not available, subscribe to VIEWPORT_DATA_CHANGED so we set it when the viewport is ready
useEffect(() => {
if (!viewportId) {
setViewport(null);
return;
}
const vp = cornerstoneViewportService.getCornerstoneViewport(viewportId);
setViewport(vp ?? null);
if (vp) {
return;
}
const { unsubscribe } = cornerstoneViewportService.subscribe(
cornerstoneViewportService.EVENTS.VIEWPORT_DATA_CHANGED,
({ viewportId: eventViewportId }) => {
if (eventViewportId !== viewportId) {
return;
}
const next = cornerstoneViewportService.getCornerstoneViewport(viewportId);
if (next) {
setViewport(next);
}
}
);
return () => {
unsubscribe();
};
}, [viewportId, cornerstoneViewportService]);
// Calculate pixel value range for the active display set
useEffect(() => {
if (!activeDisplaySetInstanceUID) {
@@ -215,15 +189,17 @@ export function useViewportRendering(
return;
}
if (!viewport) {
const csViewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
if (!csViewport) {
return;
}
if (!(viewport instanceof BaseVolumeViewport)) {
if (!(csViewport instanceof BaseVolumeViewport)) {
return;
}
const volumeIds = viewport.getAllVolumeIds();
const volumeIds = csViewport.getAllVolumeIds();
const volumeId = volumeIds.find(id => id.includes(activeDisplaySetInstanceUID));
if (!volumeId) {
@@ -231,7 +207,7 @@ export function useViewportRendering(
}
// only handle volume viewports for now
const imageData = viewport.getImageData(volumeId);
const imageData = csViewport.getImageData(volumeId);
if (!imageData) {
return;
@@ -244,7 +220,7 @@ export function useViewportRendering(
const range = voxelManager.getRange();
setPixelValueRange({ min: range[0], max: range[1] });
}, [activeDisplaySetInstanceUID, displaySetService, viewport]);
}, [activeDisplaySetInstanceUID, displaySetService, cornerstoneViewportService, viewportId]);
// Get the presets specifically for the active display set
const activeDisplaySetPresets = useMemo(() => {
@@ -264,47 +240,55 @@ export function useViewportRendering(
}, [allWindowLevelPresets, activeDisplaySetInstanceUID]);
useEffect(() => {
setIs3DVolume(viewport instanceof VolumeViewport3D);
setIs3DVolume(is3DViewport({ viewportId, cornerstoneViewportService }));
if (!viewport || !activeDisplaySetInstanceUID) {
return;
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
// Initialize the VOI range from the viewport
if (viewport && activeDisplaySetInstanceUID) {
try {
let properties;
if (viewport instanceof StackViewport) {
properties = viewport.getProperties();
if (properties.voiRange) {
setVoiRange(properties.voiRange);
voiRangeRef.current = properties.voiRange;
}
} else if (viewport instanceof BaseVolumeViewport) {
// For volume viewports, find the actor for the active display set
const volumeIds = viewport.getAllVolumeIds();
const volumeId = volumeIds.find(id => id.includes(activeDisplaySetInstanceUID));
if (volumeId) {
properties = viewport.getProperties(volumeId);
if (properties?.voiRange) {
setVoiRange(properties.voiRange);
voiRangeRef.current = properties.voiRange;
}
// Get opacity from colormap if available
if (properties?.colormap?.opacity !== undefined) {
const isArray = Array.isArray(properties.colormap.opacity);
const opacity = isArray
? properties.colormap.opacity.reduce((max, current) => Math.max(max, current), 0)
: properties.colormap.opacity;
setOpacityState(opacity);
setOpacityLinearState(opacityToLinear(opacity));
}
// Get threshold from colormap if available
if (properties?.colormap && properties.colormap.threshold !== undefined) {
setThresholdState(properties.colormap.threshold);
}
}
}
} catch (error) {
console.error('Error initializing VOI range:', error);
}
}
try {
const dataId = getDataIdForViewport(viewport as unknown, activeDisplaySetInstanceUID);
const properties =
dataId != null
? (viewport as Types.IBaseVolumeViewport).getProperties(dataId)
: viewport.getProperties();
if (!properties) {
return;
}
if (properties.voiRange) {
setVoiRange(properties.voiRange);
voiRangeRef.current = properties.voiRange;
}
if (properties.colormap?.opacity !== undefined) {
const opacityVal = properties.colormap.opacity;
const opacity = Array.isArray(opacityVal)
? (opacityVal as unknown as number[]).reduce(
(max, current) => Math.max(max, current),
0
)
: opacityVal;
setOpacityState(opacity);
setOpacityLinearState(opacityToLinear(opacity));
}
if (properties.colormap?.threshold !== undefined) {
setThresholdState(properties.colormap.threshold);
}
} catch (error) {
console.error('Error initializing VOI range:', error);
}
}, [activeDisplaySetInstanceUID, viewport]);
}, [cornerstoneViewportService, viewportId, activeDisplaySetInstanceUID]);
useEffect(() => {
if (!viewportId) {
@@ -329,11 +313,19 @@ export function useViewportRendering(
}, [colorbarService, viewportId]);
useEffect(() => {
if (!activeDisplaySetInstanceUID || !viewport?.element) {
if (!viewportId || !activeDisplaySetInstanceUID) {
return;
}
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
if (!viewport) {
return;
}
const element = viewport.element;
if (!element) {
return;
}
const updateVOI = eventDetail => {
const { range } = eventDetail.detail;
@@ -377,7 +369,7 @@ export function useViewportRendering(
element.removeEventListener(Enums.Events.VOI_MODIFIED, updateVOI);
element.removeEventListener(Enums.Events.COLORMAP_MODIFIED, updateColormap);
};
}, [activeDisplaySetInstanceUID, viewport, opacityToLinear]);
}, [viewportId, activeDisplaySetInstanceUID, cornerstoneViewportService, opacityToLinear]);
const validateActiveDisplaySet = useCallback(() => {
if (!activeDisplaySetInstanceUID) {
@@ -568,11 +560,16 @@ export function useViewportRendering(
context: 'CORNERSTONE',
});
},
[commandsManager, validateActiveDisplaySet, viewport, viewportId]
[commandsManager, viewportId, validateActiveDisplaySet]
);
const setOpacity = useCallback(
(opacityValue: number) => {
if (!viewportId) {
return;
}
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
if (!viewport || !(viewport instanceof BaseVolumeViewport)) {
return;
}
@@ -610,7 +607,7 @@ export function useViewportRendering(
viewport.render();
},
[validateActiveDisplaySet, opacityToLinear, viewport]
[cornerstoneViewportService, viewportId, validateActiveDisplaySet, opacityToLinear]
);
const setOpacityLinear = useCallback(
@@ -624,6 +621,11 @@ export function useViewportRendering(
const setThreshold = useCallback(
(thresholdValue: number) => {
if (!viewportId) {
return;
}
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
if (!viewport || !(viewport instanceof BaseVolumeViewport)) {
return;
}
@@ -651,16 +653,18 @@ export function useViewportRendering(
viewport.render();
},
[validateActiveDisplaySet, viewport]
[cornerstoneViewportService, viewportId, validateActiveDisplaySet]
);
// Get the current colormap for the active display set
const colormap = useMemo(() => {
if (!activeDisplaySetInstanceUID || !viewportDisplaySets?.length) {
if (!viewportId || !activeDisplaySetInstanceUID || !viewportDisplaySets?.length) {
return null;
}
try {
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
if (!viewport) {
return null;
}
@@ -707,7 +711,13 @@ export function useViewportRendering(
colorbarProperties?.colormaps?.[0]
);
}
}, [activeDisplaySetInstanceUID, viewportDisplaySets, colorbarProperties?.colormaps, viewport]);
}, [
cornerstoneViewportService,
viewportId,
activeDisplaySetInstanceUID,
viewportDisplaySets,
colorbarProperties?.colormaps,
]);
// 3D volume rendering functions
const setVolumeRenderingPreset = useCallback(
@@ -791,9 +801,7 @@ export function useViewportRendering(
setWindowLevel,
setVOIRange,
voiRange,
windowLevel: voiRange
? utilities.windowLevel.toWindowLevel(voiRange?.lower, voiRange?.upper)
: { windowCenter: null, windowWidth: null },
windowLevel: utilities.windowLevel.toWindowLevel(voiRange?.lower, voiRange?.upper),
// Colorbar functions
hasColorbar,
@@ -9,7 +9,7 @@ import { useSystem } from '@ohif/core';
const excludedModalities = ['SM', 'OT', 'DOC', 'ECG'];
function mapSegmentationToDisplay(segmentation, customizationService) {
const { label, segments, fallbackLabel } = segmentation;
const { label, segments } = segmentation;
// Get the readable text mapping once
const readableTextMap = customizationService.getCustomization('panelSegmentation.readableText');
@@ -76,7 +76,6 @@ function mapSegmentationToDisplay(segmentation, customizationService) {
return {
...segmentation,
label,
fallbackLabel,
segments: updatedSegments,
};
}
+27 -87
View File
@@ -20,34 +20,6 @@ export const HYDRATE_SEG_SYNC_GROUP = {
},
};
const viewportStructure = {
layoutType: 'grid',
properties: {
rows: 1,
columns: 3,
layoutOptions: [
{
x: 0,
y: 0,
width: 1 / 3,
height: 1,
},
{
x: 1 / 3,
y: 0,
width: 1 / 3,
height: 1,
},
{
x: 2 / 3,
y: 0,
width: 1 / 3,
height: 1,
},
],
},
};
export const mpr: Types.HangingProtocol.Protocol = {
id: 'mpr',
name: i18n.t('Hps:MPR'),
@@ -81,7 +53,33 @@ export const mpr: Types.HangingProtocol.Protocol = {
stages: [
{
name: 'MPR 1x3',
viewportStructure,
viewportStructure: {
layoutType: 'grid',
properties: {
rows: 1,
columns: 3,
layoutOptions: [
{
x: 0,
y: 0,
width: 1 / 3,
height: 1,
},
{
x: 1 / 3,
y: 0,
width: 1 / 3,
height: 1,
},
{
x: 2 / 3,
y: 0,
width: 1 / 3,
height: 1,
},
],
},
},
viewports: [
{
viewportOptions: {
@@ -136,63 +134,5 @@ export const mpr: Types.HangingProtocol.Protocol = {
},
],
},
{
name: 'MPR Reformat 1x3',
viewportStructure,
viewports: [
{
viewportOptions: {
viewportId: 'mpr-axial',
toolGroupId: 'mpr',
viewportType: 'volume',
orientation: 'axial_reformat',
initialImageOptions: {
preset: 'middle',
},
syncGroups: [VOI_SYNC_GROUP, HYDRATE_SEG_SYNC_GROUP],
},
displaySets: [
{
id: 'activeDisplaySet',
},
],
},
{
viewportOptions: {
viewportId: 'mpr-sagittal',
toolGroupId: 'mpr',
viewportType: 'volume',
orientation: 'sagittal_reformat',
initialImageOptions: {
preset: 'middle',
},
syncGroups: [VOI_SYNC_GROUP, HYDRATE_SEG_SYNC_GROUP],
},
displaySets: [
{
id: 'activeDisplaySet',
},
],
},
{
viewportOptions: {
viewportId: 'mpr-coronal',
toolGroupId: 'mpr',
viewportType: 'volume',
orientation: 'coronal_reformat',
initialImageOptions: {
preset: 'middle',
},
syncGroups: [VOI_SYNC_GROUP, HYDRATE_SEG_SYNC_GROUP],
},
displaySets: [
{
id: 'activeDisplaySet',
},
],
},
],
},
],
};
-3
View File
@@ -21,7 +21,6 @@ import SegmentationService from './services/SegmentationService';
import CornerstoneCacheService from './services/CornerstoneCacheService';
import CornerstoneViewportService from './services/ViewportService/CornerstoneViewportService';
import ColorbarService from './services/ColorbarService';
import ViewedDataService from './services/ViewedDataService';
import * as CornerstoneExtensionTypes from './types';
import { toolNames } from './initCornerstoneTools';
@@ -181,7 +180,6 @@ const cornerstoneExtension: Types.Extensions.Extension = {
useSelectedSegmentationsForViewportStore
.getState()
.clearSelectedSegmentationsForViewportStore();
servicesManager.services.viewedDataService?.clearViewedData();
segmentationService.removeAllSegmentations();
},
@@ -198,7 +196,6 @@ const cornerstoneExtension: Types.Extensions.Extension = {
servicesManager.registerService(SegmentationService.REGISTRATION);
servicesManager.registerService(CornerstoneCacheService.REGISTRATION);
servicesManager.registerService(ColorbarService.REGISTRATION);
servicesManager.registerService(ViewedDataService.REGISTRATION);
const { syncGroupService } = servicesManager.services;
syncGroupService.registerCustomSynchronizer('frameview', createFrameViewSynchronizer);
@@ -2,11 +2,6 @@ import { cache, Types } from '@cornerstonejs/core';
import { utilities } from '@cornerstonejs/tools';
function _getVolumeFromViewport(viewport: Types.IBaseVolumeViewport) {
// Handle non-volume viewports that don't have getAllVolumeIds
if (!viewport?.getAllVolumeIds) {
return null;
}
const volumeIds = viewport.getAllVolumeIds();
const volumes = volumeIds.map(id => cache.getVolume(id));
const dynamicVolume = volumes.find(volume => volume.isDynamicVolume());
@@ -1,5 +1,5 @@
import { eventTarget, Types } from '@cornerstonejs/core';
import { Enums, annotation, cancelActiveManipulations } from '@cornerstonejs/tools';
import { Enums, annotation } from '@cornerstonejs/tools';
import { DicomMetadataStore } from '@ohif/core';
import * as CSExtensionEnums from './enums';
@@ -504,12 +504,6 @@ const connectMeasurementServiceToTools = ({
if (source?.name && source.name !== CORNERSTONE_3D_TOOLS_SOURCE_NAME) {
return;
}
// Cancel any active tool manipulation (e.g., Spline/Livewire) to avoid leaving the tool
// in a drawing state after deleting a not completed measurement, which can block viewport interactivity.
const element = getActiveViewportEnabledElement(viewportGridService)?.viewport?.element;
if (element) {
cancelActiveManipulations(element);
}
const removedAnnotation = annotation.state.getAnnotation(removedMeasurementId);
removeAnnotation(removedMeasurementId);
// Ensure `removedAnnotation` is available before triggering the memo,
@@ -65,7 +65,7 @@ export default function PanelMeasurement(props): React.ReactNode {
return EmptyComponent ? (
<EmptyComponent items={displayMeasurements} />
) : (
<span className="text-foreground">No Measurements</span>
<span className="text-white">No Measurements</span>
);
}
@@ -1,7 +1,6 @@
import { PubSubService, Types as OhifTypes } from '@ohif/core';
import { RENDERING_ENGINE_ID } from '../ViewportService/constants';
import { getRenderingEngine } from '@cornerstonejs/core';
import { getDataIdForViewport } from '../../utils/getDataIdForViewport';
import { ColorbarOptions, ChangeTypes } from '../../types/Colorbar';
export default class ColorbarService extends PubSubService {
@@ -39,6 +38,25 @@ export default class ColorbarService extends PubSubService {
this.servicesManager = servicesManager;
}
/**
* Gets the appropriate data ID for a viewport and display set
* @param viewport - The viewport instance
* @param displaySetInstanceUID - The display set instance UID to identify data
* @returns The appropriate data ID for the viewport type (volumeId for volume viewports, undefined for stack)
*/
private getDataIdForViewport(viewport, displaySetInstanceUID: string): string | undefined {
// For volume viewports, find the matching volumeId
if (viewport.getAllVolumeIds) {
const volumeIds = viewport.getAllVolumeIds() || [];
return volumeIds.length > 0
? volumeIds.find(id => id.includes(displaySetInstanceUID)) || undefined
: undefined;
}
// For other viewports, no specific dataId is needed for now
return undefined;
}
/**
* Adds a colorbar to a specific viewport identified by `viewportId`, using the provided `displaySetInstanceUIDs` and `options`.
* This method prepares the colorbar state that will be used by the ViewportColorbarsContainer component.
@@ -74,7 +92,7 @@ export default class ColorbarService extends PubSubService {
return;
}
const dataId = getDataIdForViewport(viewport, displaySetInstanceUID);
const dataId = this.getDataIdForViewport(viewport, displaySetInstanceUID);
const properties = dataId ? viewport.getProperties(dataId) : viewport.getProperties();
const colormap = properties?.colormap;
@@ -228,7 +246,7 @@ export default class ColorbarService extends PubSubService {
}
// Get the appropriate dataId for this viewport/displaySet combination
const dataId = getDataIdForViewport(viewport, displaySetInstanceUID);
const dataId = this.getDataIdForViewport(viewport, displaySetInstanceUID);
// Set properties with or without dataId based on what the viewport supports
viewport.setProperties({ colormap }, dataId);
@@ -1120,7 +1120,6 @@ describe('SegmentationService', () => {
isDynamicVolume: false,
SeriesNumber: 1,
SeriesDescription: 'Series Description',
Modality: 'SEG',
} as unknown as AppTypes.DisplaySet;
jest
@@ -1146,7 +1145,6 @@ describe('SegmentationService', () => {
info: 'S1: Series Description',
},
label: 'Segmentation 2',
fallbackLabel: 'S:1 SEG',
segments: {
'1': {
active: true,
@@ -1177,7 +1175,6 @@ describe('SegmentationService', () => {
dynamicVolumeInfo: {
timePoints: ['timePoint1', 'timePoint2', 'timePoint3'],
},
Modality: 'SEG',
} as unknown as AppTypes.DisplaySet;
jest
@@ -1215,7 +1212,6 @@ describe('SegmentationService', () => {
info: 'S1: Series Description',
},
label: 'Segmentation 2',
fallbackLabel: 'S:1 SEG',
segments: {
'1': {
active: true,
@@ -1324,8 +1320,6 @@ describe('SegmentationService', () => {
},
SeriesDate: '2025-01-01',
SeriesDescription: 'Series Description',
Modality: 'SEG',
SeriesNumber: 1,
};
const referencedDisplaySet = {
@@ -1385,7 +1379,6 @@ describe('SegmentationService', () => {
const expectedSegmentation = {
config: {
label: segDisplaySet.SeriesDescription,
fallbackLabel: 'S:1 SEG',
segments: {
'1': {
active: false,
@@ -1541,7 +1534,7 @@ describe('SegmentationService', () => {
it('should create a segmentation for a RTSTRUCT display set', async () => {
const segmentationId = 'segmentationId';
const rtStructDisplaySet = {
Modality: 'RTSTRUCT',
modality: 'RTSTRUCT',
displaySetInstanceUID: 'display-set-uid',
referencedDisplaySetInstanceUID: 'existent-display-set-uid',
SeriesDate: '2025-01-01',
@@ -1551,7 +1544,6 @@ describe('SegmentationService', () => {
ROIContours: [{}, {}, {}],
frameOfReferenceUID: 'frameOfReferenceUID',
},
SeriesNumber: 1,
};
const referencedDisplaySet = {
@@ -1658,7 +1650,6 @@ describe('SegmentationService', () => {
const expectedSegmentation = {
config: {
label: rtStructDisplaySet.SeriesDescription,
fallbackLabel: 'S:1 RTSTRUCT',
segments: {
'1': {
active: false,
@@ -2576,12 +2567,12 @@ describe('SegmentationService', () => {
describe('clearSegmentationRepresentations', () => {
it('should clear the segmentation representations', () => {
const viewportId = 'viewportId';
jest.spyOn(service, 'removeRepresentationsFromViewport').mockReturnValue(undefined);
jest.spyOn(service, 'removeSegmentationRepresentations').mockReturnValue(undefined);
service.clearSegmentationRepresentations(viewportId);
expect(service.removeRepresentationsFromViewport).toHaveBeenCalledTimes(1);
expect(service.removeRepresentationsFromViewport).toHaveBeenCalledWith(viewportId);
expect(service.removeSegmentationRepresentations).toHaveBeenCalledTimes(1);
expect(service.removeSegmentationRepresentations).toHaveBeenCalledWith(viewportId);
});
});
@@ -2609,7 +2600,7 @@ describe('SegmentationService', () => {
});
});
describe('removeRepresentationsFromViewport', () => {
describe('removeSegmentationRepresentations', () => {
it('should remove the segmentation representations', () => {
const viewportId = 'viewportId';
const specifier = {
@@ -2618,7 +2609,7 @@ describe('SegmentationService', () => {
};
jest.spyOn(cstSegmentation, 'removeSegmentationRepresentations').mockReturnValue(undefined);
service.removeRepresentationsFromViewport(viewportId, specifier);
service.removeSegmentationRepresentations(viewportId, specifier);
expect(cstSegmentation.removeSegmentationRepresentations).toHaveBeenCalledTimes(1);
expect(cstSegmentation.removeSegmentationRepresentations).toHaveBeenCalledWith(
@@ -55,7 +55,6 @@ export type SegmentationRepresentation = cstTypes.SegmentationRepresentation & {
viewportId: string;
id: string;
label: string;
fallbackLabel?: string;
styles: cstTypes.RepresentationStyle;
segments: {
[key: number]: SegmentRepresentation;
@@ -248,7 +247,7 @@ class SegmentationService extends PubSubService {
eventTarget.removeEventListener(
csToolsEnums.Events.SEGMENTATION_REMOVED,
this._onSegmentationRemovedFromSource
this._onSegmentationModifiedFromSource
);
eventTarget.removeEventListener(
@@ -268,7 +267,7 @@ class SegmentationService extends PubSubService {
eventTarget.removeEventListener(
csToolsEnums.Events.SEGMENTATION_REPRESENTATION_REMOVED,
this._onSegmentationRepresentationRemovedFromSource
this._onSegmentationRepresentationModifiedFromSource
);
eventTarget.removeEventListener(
@@ -431,7 +430,6 @@ class SegmentationService extends PubSubService {
},
config: {
label,
fallbackLabel: `S:${displaySet.SeriesNumber} ${displaySet.Modality}`,
segments:
options?.segments && Object.keys(options.segments).length > 0
? options.segments
@@ -585,7 +583,6 @@ class SegmentationService extends PubSubService {
},
config: {
label: segDisplaySet.SeriesDescription,
fallbackLabel: `S:${segDisplaySet.SeriesNumber} ${segDisplaySet.Modality}`,
segments,
},
};
@@ -667,7 +664,6 @@ class SegmentationService extends PubSubService {
},
config: {
label: rtDisplaySet.SeriesDescription,
fallbackLabel: `S:${rtDisplaySet.SeriesNumber} ${rtDisplaySet.Modality}`,
},
};
@@ -1288,14 +1284,14 @@ class SegmentationService extends PubSubService {
/**
* Clears segmentation representations from the viewport.
* Unlike removeRepresentationsFromViewport, this doesn't update
* Unlike removeSegmentationRepresentations, this doesn't update
* removed display set and representation maps.
* We track removed segmentations manually to avoid re-adding them
* when the display set is added again.
* @param viewportId - The viewport ID to clear segmentation representations from.
*/
public clearSegmentationRepresentations(viewportId: string): void {
this.removeRepresentationsFromViewport(viewportId);
this.removeSegmentationRepresentations(viewportId);
}
/**
@@ -1311,7 +1307,7 @@ class SegmentationService extends PubSubService {
}
/**
* Removes segmentation representations from the viewport.
* It removes the segmentation representations from the viewport.
* @param viewportId - The viewport id to remove the segmentation representations from.
* @param specifier - The specifier to remove the segmentation representations.
*
@@ -1321,7 +1317,7 @@ class SegmentationService extends PubSubService {
* If a type specifier is provided, only the segmentation representation with the specified type are removed.
* If both a segmentationId and type specifier are provided, only the segmentation representation with the specified segmentationId and type are removed.
*/
public removeRepresentationsFromViewport(
public removeSegmentationRepresentations(
viewportId: string,
specifier: {
segmentationId?: string;
@@ -1846,7 +1842,6 @@ class SegmentationService extends PubSubService {
id: id,
segmentationId,
label: segmentation.label,
fallbackLabel: segmentation.fallbackLabel,
active,
type,
visible,
@@ -1866,7 +1861,7 @@ class SegmentationService extends PubSubService {
eventTarget.addEventListener(
csToolsEnums.Events.SEGMENTATION_REMOVED,
this._onSegmentationRemovedFromSource
this._onSegmentationModifiedFromSource
);
eventTarget.addEventListener(
@@ -1886,7 +1881,7 @@ class SegmentationService extends PubSubService {
eventTarget.addEventListener(
csToolsEnums.Events.SEGMENTATION_REPRESENTATION_REMOVED,
this._onSegmentationRepresentationRemovedFromSource
this._onSegmentationRepresentationModifiedFromSource
);
eventTarget.addEventListener(
@@ -2125,14 +2120,6 @@ class SegmentationService extends PubSubService {
});
};
private _onSegmentationRepresentationRemovedFromSource = evt => {
const { segmentationId, viewportId } = evt.detail;
this._broadcastEvent(this.EVENTS.SEGMENTATION_REPRESENTATION_REMOVED, {
segmentationId,
viewportId,
});
};
private _onSegmentationModifiedFromSource = (
evt: cstTypes.EventTypes.SegmentationModifiedEventType
) => {
@@ -2153,16 +2140,6 @@ class SegmentationService extends PubSubService {
});
};
private _onSegmentationRemovedFromSource = (
evt: cstTypes.EventTypes.SegmentationRemovedEventType
) => {
const { segmentationId } = evt.detail;
this._broadcastEvent(this.EVENTS.SEGMENTATION_REMOVED, {
segmentationId,
});
};
private _onAnnotationCutMergeProcessCompletedFromSource = evt => {
const { segmentationId } = evt.detail;
this._broadcastEvent(this.EVENTS.SEGMENTATION_ANNOTATION_CUT_MERGE_PROCESS_COMPLETED, {
@@ -66,15 +66,7 @@ const segmentationRepresentationModifiedCallback = async (
const sharedDisplaySetExists = isAnyDisplaySetCommon(sourceDisplaySetUIDs, targetDisplaySetUIDs);
const targetFrameOfReferenceUID = viewport.getFrameOfReferenceUID();
const sourceFrameOfReferenceUID =
getEnabledElementByViewportId(sourceViewportId)?.viewport?.getFrameOfReferenceUID();
if (!sharedDisplaySetExists && !targetFrameOfReferenceUID) {
return;
}
if (!sharedDisplaySetExists && targetFrameOfReferenceUID !== sourceFrameOfReferenceUID) {
if (!sharedDisplaySetExists && !viewport.getFrameOfReferenceUID()) {
return;
}
@@ -1,58 +0,0 @@
import { PubSubService } from '@ohif/core';
export type ViewedDataPayload = {
viewedDataId?: string;
viewedDataCleared?: boolean;
};
class ViewedDataService extends PubSubService {
public static readonly EVENTS = {
VIEWED_DATA_CHANGED: 'event::viewedDataChanged',
};
public static REGISTRATION = {
name: 'viewedDataService',
altName: 'ViewedDataService',
create: () => {
return new ViewedDataService();
},
};
private viewedDataIds = new Set<string>();
constructor() {
super(ViewedDataService.EVENTS);
}
public markDataViewed(dataId: string): void {
if (!dataId || this.viewedDataIds.has(dataId)) {
return;
}
this.viewedDataIds.add(dataId);
this._broadcastEvent(this.EVENTS.VIEWED_DATA_CHANGED, {
viewedDataId: dataId,
});
}
public isDataViewed(dataId: string): boolean {
if (!dataId) {
return false;
}
return this.viewedDataIds.has(dataId);
}
public clearViewedData(): void {
this.viewedDataIds.clear();
this._broadcastEvent(this.EVENTS.VIEWED_DATA_CHANGED, {
viewedDataCleared: true,
});
}
public subscribeViewedDataChanges(listener: (payload: ViewedDataPayload) => void) {
return this.subscribe(this.EVENTS.VIEWED_DATA_CHANGED, listener);
}
}
export default ViewedDataService;
@@ -1,3 +0,0 @@
import ViewedDataService from './ViewedDataService';
export default ViewedDataService;
@@ -9,7 +9,6 @@ import {
utilities as csUtils,
VolumeViewport,
VolumeViewport3D,
ECGViewport,
cache,
Enums as csEnums,
BaseVolumeViewport,
@@ -49,47 +48,6 @@ const EVENTS = {
const MIN_STACK_VIEWPORTS_TO_ENQUEUE_RESIZE = 12;
const MIN_VOLUME_VIEWPORTS_TO_ENQUEUE_RESIZE = 6;
function getVolumeActorReferencedIds(viewport: Types.IVolumeViewport): string[] {
const actors = viewport.getActors?.() ?? [];
return actors
.filter(ac => ac.actor?.getClassName?.() === 'vtkVolume')
.map(ac => ac.referencedId)
.filter(Boolean) as string[];
}
function volumeIdPrefixesMatch(
existingIds: string[],
prefixLen: number,
targetIds: string[]
): boolean {
if (prefixLen > targetIds.length) {
return false;
}
for (let i = 0; i < prefixLen; i++) {
if (existingIds[i] !== targetIds[i]) {
return false;
}
}
return true;
}
/**
* Returns true when the viewport type matches a volume-based presentation (ORTHOGRAPHIC or VOLUME_3D).
*/
function viewportMatchesDesiredVolumePresentation(
viewport: Types.IViewport,
desiredViewportInfo: ViewportInfo
): boolean {
const desiredType = desiredViewportInfo.getViewportType();
if (viewport.type !== desiredType) {
return false;
}
return (
desiredType === csEnums.ViewportType.ORTHOGRAPHIC ||
desiredType === csEnums.ViewportType.VOLUME_3D
);
}
export const WITH_NAVIGATION = { withNavigation: true, withOrientation: false };
export const WITH_ORIENTATION = { withNavigation: true, withOrientation: true };
@@ -820,19 +778,6 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
/**
* Sets the image data for the given viewport.
*/
private async _setEcgViewport(
viewport: Types.IECGViewport,
viewportData: StackViewportData
): Promise<void> {
const [displaySet] = viewportData.data;
const imageId = displaySet.imageIds?.[0];
if (!imageId) {
console.error('[CornerstoneViewportService] ECG display set has no imageId');
return;
}
return viewport.setEcg(imageId);
}
private async _setOtherViewport(
viewport: Types.IStackViewport,
viewportData: StackViewportData,
@@ -911,21 +856,28 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
initialImageIndexToUse = this._getInitialImageIndexForViewport(viewportInfo, imageIds) || 0;
}
await viewport.setStack(imageIds, initialImageIndexToUse);
viewport.setProperties({ ...properties });
this.setPresentations(viewport.id, presentations, viewportInfo);
return viewport.setStack(imageIds, initialImageIndexToUse).then(() => {
viewport.setProperties({ ...properties });
this.setPresentations(viewport.id, presentations, viewportInfo);
await this._addOverlayRepresentations(overlayProcessingResults);
if (overlayProcessingResults?.length) {
overlayProcessingResults.forEach(overlayProcessingResult => {
if (overlayProcessingResult?.addOverlayFn) {
overlayProcessingResult.addOverlayFn();
}
});
}
if (displayArea) {
viewport.setDisplayArea(displayArea);
}
if (rotation) {
viewport.setProperties({ rotation });
}
if (flipHorizontal) {
viewport.setCamera({ flipHorizontal: true });
}
if (displayArea) {
viewport.setDisplayArea(displayArea);
}
if (rotation) {
viewport.setProperties({ rotation });
}
if (flipHorizontal) {
viewport.setCamera({ flipHorizontal: true });
}
});
}
private _getInitialImageIndexForViewport(
@@ -1153,45 +1105,15 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
});
}
const baseVolumeInputs = filteredVolumeInputArray.map(({ volumeInput }) => volumeInput);
const nextBaseVolumeIds = baseVolumeInputs.map(v => v.volumeId);
const existingVolumeIds = getVolumeActorReferencedIds(viewport);
await viewport.setVolumes(volumeInputArray);
let skippedIdenticalBaseVolumes = false;
if (baseVolumeInputs.length) {
const singleBaseViewport = nextBaseVolumeIds.length === 1;
// Only skip setVolumes() when the viewport type already matches the desired OHIF type
// (ORTHOGRAPHIC / VOLUME_3D); otherwise a stack → MPR switch with the same volumeId
// would incorrectly skip rebuilding the viewport.
if (
singleBaseViewport &&
existingVolumeIds.length >= nextBaseVolumeIds.length &&
volumeIdPrefixesMatch(existingVolumeIds, nextBaseVolumeIds.length, nextBaseVolumeIds) &&
viewportMatchesDesiredVolumePresentation(viewport, viewportInfo)
) {
// Same primary volume already loaded (e.g. labelmap / extra actors after it) — avoid
// setVolumes(), which tears down all actors and blanks MPR during SEG hydrate.
skippedIdenticalBaseVolumes = true;
} else if (
existingVolumeIds.length &&
nextBaseVolumeIds.length > existingVolumeIds.length &&
volumeIdPrefixesMatch(existingVolumeIds, existingVolumeIds.length, nextBaseVolumeIds) &&
typeof viewport.addVolumes === 'function'
) {
const toAdd = baseVolumeInputs.slice(existingVolumeIds.length);
if (toAdd.length) {
await viewport.addVolumes(toAdd);
if (overlayProcessingResults?.length) {
overlayProcessingResults.forEach(({ addOverlayFn }) => {
if (addOverlayFn) {
addOverlayFn();
}
} else {
await viewport.setVolumes(baseVolumeInputs);
}
} else if (volumeInputArray.length) {
await viewport.setVolumes(volumeInputArray);
});
}
await this._addOverlayRepresentations(overlayProcessingResults);
viewport.render();
volumesProperties.forEach(({ properties, volumeId }) => {
@@ -1202,11 +1124,8 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
});
this.setPresentations(viewport.id, presentations);
// Presentations apply segmentation (hydrated labelmap etc.) after the render above — redraw so
// every orthographic/3D tile shows the updated scene (fixes MPR siblings blank after SEG hydrate).
viewport.render();
if (!presentations.positionPresentation && !skippedIdenticalBaseVolumes) {
if (!presentations.positionPresentation) {
const imageIndex = this._getInitialImageIndexForViewport(viewportInfo);
if (imageIndex !== undefined) {
@@ -1260,7 +1179,7 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
private addOverlayRepresentationForDisplaySet(
displaySet: OhifTypes.DisplaySet,
viewport: Types.IViewport
): Promise<void> {
) {
const { segmentationService } = this.servicesManager.services;
const segmentationId = displaySet.displaySetInstanceUID;
@@ -1270,36 +1189,18 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
: csToolsEnums.SegmentationRepresentations.Contour;
const { predecessorImageId } = displaySet;
const segmentationRepresentationPromise = segmentationService.addSegmentationRepresentation(
viewport.id,
{
segmentationId,
predecessorImageId,
type: representationType,
config: {
blendMode:
viewport?.getBlendMode?.() === 1
? BlendModes.LABELMAP_EDGE_PROJECTION_BLEND
: undefined,
},
}
);
segmentationService.addSegmentationRepresentation(viewport.id, {
segmentationId,
predecessorImageId,
type: representationType,
config: {
blendMode:
viewport?.getBlendMode?.() === 1 ? BlendModes.LABELMAP_EDGE_PROJECTION_BLEND : undefined,
},
});
// store the segmentation presentation id in the viewport info
this.storePresentation({ viewportId: viewport.id });
return segmentationRepresentationPromise;
}
private async _addOverlayRepresentations(
overlayProcessingResults?: Array<{ addOverlayFn?: () => Promise<void> }>
): Promise<void> {
if (!overlayProcessingResults?.length) {
return;
}
for (const overlayProcessingResult of overlayProcessingResults) {
if (overlayProcessingResult?.addOverlayFn) {
await overlayProcessingResult.addOverlayFn();
}
}
}
// Todo: keepCamera is an interim solution until we have a better solution for
@@ -1356,13 +1257,6 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
);
}
if (viewport instanceof ECGViewport) {
return this._setEcgViewport(
viewport as unknown as Types.IECGViewport,
viewportData as StackViewportData
);
}
return this._setOtherViewport(
viewport,
viewportData as StackViewportData,
@@ -1414,8 +1308,8 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
return;
}
if (displaySet.FrameOfReferenceUID) {
return displaySet.FrameOfReferenceUID;
if (displaySet.frameOfReferenceUID) {
return displaySet.frameOfReferenceUID;
}
if (displaySet.Modality === 'SEG') {
@@ -135,27 +135,16 @@ const _getSegmentationPresentationId = ({
return;
}
const { displaySetService } = servicesManager.services;
const { displaySetInstanceUIDs, viewportOptions } = viewport;
// Match keys used by updateStoredSegmentationPresentation (referenced volume only).
// Including overlay UIDs (e.g. SEG) produced ids like "MR&SEG" while the store
// entry is under "MR", so hydrated segmentations never applied and viewports could mis-render.
const nonOverlayUIDs = displaySetInstanceUIDs.filter(uid => {
const ds = displaySetService.getDisplaySetByUID(uid);
return ds && !ds.isOverlayDisplaySet;
});
if (!nonOverlayUIDs.length) {
return;
}
let orientation = viewportOptions.orientation;
if (!orientation) {
// Calculate orientation from the viewport sample image
const displaySet = displaySetService.getDisplaySetByUID(nonOverlayUIDs[0]);
const sampleImage = displaySet?.images?.[0];
const displaySet = servicesManager.services.displaySetService.getDisplaySetByUID(
displaySetInstanceUIDs[0]
);
const sampleImage = displaySet.images?.[0];
const imageOrientationPatient = sampleImage?.ImageOrientationPatient;
orientation = getViewportOrientationFromImageOrientationPatient(imageOrientationPatient);
@@ -163,7 +152,7 @@ const _getSegmentationPresentationId = ({
const segmentationPresentationArr = [];
segmentationPresentationArr.push(...nonOverlayUIDs);
segmentationPresentationArr.push(...displaySetInstanceUIDs);
// Uncomment if unique indexing is needed
// addUniqueIndex(
@@ -5,7 +5,6 @@ import SegmentationServiceType from '../services/SegmentationService';
import SyncGroupServiceType from '../services/SyncGroupService';
import ToolGroupServiceType from '../services/ToolGroupService';
import ColorbarServiceType from '../services/ColorbarService';
import ViewedDataServiceType from '../services/ViewedDataService';
import * as cornerstone from '@cornerstonejs/core';
import * as cornerstoneTools from '@cornerstonejs/tools';
@@ -24,7 +23,6 @@ declare global {
export type SyncGroupService = SyncGroupServiceType;
export type ToolGroupService = ToolGroupServiceType;
export type ColorbarService = ColorbarServiceType;
export type ViewedDataService = ViewedDataServiceType;
export interface Services {
cornerstoneViewportService?: CornerstoneViewportServiceType;
@@ -33,7 +31,6 @@ declare global {
segmentationService?: SegmentationServiceType;
cornerstoneCacheService?: CornerstoneCacheServiceType;
colorbarService?: ColorbarServiceType;
viewedDataService?: ViewedDataServiceType;
}
export namespace Segmentation {
@@ -118,50 +118,29 @@ const CornerstoneViewportDownloadForm = ({
const downloadViewport = renderingEngine.getViewport(VIEWPORT_ID);
try {
// Capture current viewport state
// - properties: VOI, colormap, interpolation, etc.
// - viewPresentation: flip/rotate/zoom presentation state added for
// saving flip and rotation for capture
// - viewReference: image/volume reference
const properties = viewport.getProperties();
const viewPresentation = viewport.getViewPresentation?.();
const viewRef = viewport.getViewReference?.();
if (downloadViewport instanceof StackViewport) {
const imageId = viewport.getCurrentImageId();
const properties = viewport.getProperties();
await downloadViewport.setStack([imageId]);
downloadViewport.setProperties(properties);
} else if (downloadViewport instanceof BaseVolumeViewport) {
const volumeIds = viewport.getAllVolumeIds();
await downloadViewport.setVolumes([{ volumeId: volumeIds[0] }]);
downloadViewport.setVolumes([{ volumeId: volumeIds[0] }]);
}
// Apply presentation state so captured image preserves flip/rotate
if (viewPresentation && downloadViewport.setViewPresentation) {
downloadViewport.setViewPresentation(viewPresentation);
}
// Apply viewport display properties
downloadViewport.setProperties(properties);
// Ensure correct image/volume reference
if (viewRef && downloadViewport.setViewReference) {
downloadViewport.setViewReference(viewRef);
}
downloadViewport.render();
// Re-apply segmentation overlays to the download viewport
if (segmentationRepresentations?.length) {
segmentationRepresentations.forEach(segRepresentation => {
const { segmentationId, colorLUTIndex, type } = segRepresentation;
if (type === Enums.SegmentationRepresentations.Labelmap) {
segmentation.addLabelmapRepresentationToViewportMap({
[downloadViewport.id]: [
{
segmentationId,
type: Enums.SegmentationRepresentations.Labelmap,
config: { colorLUTOrIndex: colorLUTIndex },
config: {
colorLUTOrIndex: colorLUTIndex,
},
},
],
});
@@ -173,7 +152,9 @@ const CornerstoneViewportDownloadForm = ({
{
segmentationId,
type: Enums.SegmentationRepresentations.Contour,
config: { colorLUTOrIndex: colorLUTIndex },
config: {
colorLUTOrIndex: colorLUTIndex,
},
},
],
});
@@ -249,48 +230,6 @@ const CornerstoneViewportDownloadForm = ({
downloadUrl(canvas.toDataURL(`image/${fileType}`, 1.0), { filename });
};
const handleCopyToClipboard = async () => {
const divForDownloadViewport = document.querySelector(
`div[data-viewport-uid="${VIEWPORT_ID}"]`
);
if (!divForDownloadViewport) {
console.debug('No viewport found for copy');
return;
}
try {
const canvas = await html2canvas(divForDownloadViewport as HTMLElement);
// Clipboard API only supports PNG format in most browsers
const blob = await new Promise<Blob>((resolve, reject) => {
canvas.toBlob(
blob => {
if (blob) {
resolve(blob);
} else {
reject(new Error('Failed to create blob from canvas'));
}
},
'image/png',
1.0
);
});
// Copy to clipboard using the Clipboard API
await navigator.clipboard.write([
new ClipboardItem({
'image/png': blob,
}),
]);
console.log('Image copied to clipboard successfully');
} catch (error) {
console.error('Failed to copy image to clipboard:', error);
throw error;
}
};
const ViewportDownloadFormNew = customizationService.getCustomization(
'ohif.captureViewportModal'
);
@@ -308,7 +247,6 @@ const CornerstoneViewportDownloadForm = ({
onEnableViewport={handleEnableViewport}
onDisableViewport={handleDisableViewport}
onDownload={handleDownload}
onCopyToClipboard={handleCopyToClipboard}
warningState={warningState}
/>
);
@@ -1,217 +0,0 @@
import { decodeInt16Multiplex, base64ToArrayBuffer, buildEcgModule } from './ecgMetadata';
// ---------------------------------------------------------------------------
// decodeInt16Multiplex
// ---------------------------------------------------------------------------
describe('decodeInt16Multiplex', () => {
it('demultiplexes 2 channels correctly', () => {
// Interleaved layout: [ch0_s0, ch1_s0, ch0_s1, ch1_s1, ch0_s2, ch1_s2]
const interleaved = new Int16Array([10, 20, 30, 40, 50, 60]);
const channels = decodeInt16Multiplex(interleaved.buffer, 2, 3);
expect(channels).toHaveLength(2);
expect(Array.from(channels[0])).toEqual([10, 30, 50]);
expect(Array.from(channels[1])).toEqual([20, 40, 60]);
});
it('handles a single channel', () => {
const data = new Int16Array([100, 200, 300]);
const channels = decodeInt16Multiplex(data.buffer, 1, 3);
expect(channels).toHaveLength(1);
expect(Array.from(channels[0])).toEqual([100, 200, 300]);
});
it('handles negative values (signed short)', () => {
const data = new Int16Array([-1000, -2000, -3000]);
const channels = decodeInt16Multiplex(data.buffer, 1, 3);
expect(Array.from(channels[0])).toEqual([-1000, -2000, -3000]);
});
it('returns empty arrays when numberOfChannels or numberOfSamples is 0', () => {
const emptyBuffer = new Int16Array([]).buffer;
expect(decodeInt16Multiplex(emptyBuffer, 0, 0)).toHaveLength(0);
expect(decodeInt16Multiplex(emptyBuffer, 0, 10)).toHaveLength(0);
});
it('produces Int16Array instances for each channel', () => {
const data = new Int16Array([1, 2]);
const channels = decodeInt16Multiplex(data.buffer, 2, 1);
expect(channels[0]).toBeInstanceOf(Int16Array);
expect(channels[1]).toBeInstanceOf(Int16Array);
});
});
// ---------------------------------------------------------------------------
// base64ToArrayBuffer
// ---------------------------------------------------------------------------
describe('base64ToArrayBuffer', () => {
it('decodes a simple base64 string to the correct bytes', () => {
// "ABC" in ASCII = [65, 66, 67]; base64 of that is 'QUJD'
const buffer = base64ToArrayBuffer('QUJD');
const bytes = new Uint8Array(buffer);
expect(bytes).toHaveLength(3);
expect(Array.from(bytes)).toEqual([65, 66, 67]);
});
it('round-trips an Int16Array through base64', () => {
const original = new Int16Array([500, -300, 0, 32767]);
const base64 = btoa(String.fromCharCode(...new Uint8Array(original.buffer)));
const recovered = new Int16Array(base64ToArrayBuffer(base64));
expect(Array.from(recovered)).toEqual(Array.from(original));
});
it('returns an ArrayBuffer', () => {
const result = base64ToArrayBuffer('AA=='); // single zero byte
expect(result).toBeInstanceOf(ArrayBuffer);
expect(result.byteLength).toBe(1);
});
});
// ---------------------------------------------------------------------------
// buildEcgModule
// ---------------------------------------------------------------------------
describe('buildEcgModule', () => {
const makeInstance = (overrides = {}) => ({
WaveformSequence: [
{
NumberOfWaveformChannels: 12,
NumberOfWaveformSamples: 5000,
SamplingFrequency: 500,
WaveformBitsAllocated: 16,
WaveformSampleInterpretation: 'SS',
MultiplexGroupLabel: '12 Lead ECG',
ChannelDefinitionSequence: [
{ ChannelSourceSequence: [{ CodeMeaning: 'Lead I' }] },
{ ChannelSourceSequence: [{ CodeMeaning: 'Lead II' }] },
],
WaveformData: { InlineBinary: btoa('\x00\x01') },
},
],
...overrides,
});
it('returns null when WaveformSequence is absent', () => {
expect(buildEcgModule({})).toBeNull();
expect(buildEcgModule({ WaveformSequence: [] })).toBeNull();
});
it('returns a valid ecgModule for a complete instance', () => {
const module = buildEcgModule(makeInstance());
expect(module).not.toBeNull();
expect(module!.numberOfWaveformChannels).toBe(12);
expect(module!.numberOfWaveformSamples).toBe(5000);
expect(module!.samplingFrequency).toBe(500);
expect(module!.waveformBitsAllocated).toBe(16);
expect(module!.waveformSampleInterpretation).toBe('SS');
expect(module!.multiplexGroupLabel).toBe('12 Lead ECG');
expect(module!.channelDefinitionSequence).toHaveLength(2);
expect(module!.channelDefinitionSequence[0].channelSourceSequence.codeMeaning).toBe('Lead I');
expect(typeof module!.waveformData.retrieveBulkData).toBe('function');
});
it('applies defaults for missing optional fields', () => {
const instance = {
WaveformSequence: [
{
// No explicit values — all defaults
WaveformData: { InlineBinary: btoa('\x00\x00') },
},
],
};
const module = buildEcgModule(instance);
expect(module!.numberOfWaveformChannels).toBe(0);
expect(module!.numberOfWaveformSamples).toBe(0);
expect(module!.samplingFrequency).toBe(1);
expect(module!.waveformBitsAllocated).toBe(16);
expect(module!.waveformSampleInterpretation).toBe('SS');
expect(module!.multiplexGroupLabel).toBe('');
expect(module!.channelDefinitionSequence).toHaveLength(0);
});
it('retrieveBulkData decodes InlineBinary data correctly', async () => {
const samples = new Int16Array([10, 20, 30]);
const base64 = btoa(String.fromCharCode(...new Uint8Array(samples.buffer)));
const instance = {
WaveformSequence: [
{
NumberOfWaveformChannels: 1,
NumberOfWaveformSamples: 3,
WaveformData: { InlineBinary: base64 },
},
],
};
const module = buildEcgModule(instance);
const channels = await module!.waveformData.retrieveBulkData();
expect(channels).toHaveLength(1);
expect(Array.from(channels[0])).toEqual([10, 20, 30]);
});
it('retrieveBulkData returns [] when WaveformData is absent', async () => {
const instance = {
WaveformSequence: [
{ NumberOfWaveformChannels: 1, NumberOfWaveformSamples: 1 },
],
};
const module = buildEcgModule(instance);
const channels = await module!.waveformData.retrieveBulkData();
expect(channels).toEqual([]);
});
it('retrieveBulkData fetches BulkDataURI with auth header when provided', async () => {
const samples = new Int16Array([1, 2]);
global.fetch = jest.fn().mockResolvedValue({
ok: true,
arrayBuffer: () => Promise.resolve(samples.buffer),
});
const userAuthenticationService = {
getAuthorizationHeader: () => ({ Authorization: 'Bearer token123' }),
};
const instance = {
WaveformSequence: [
{
NumberOfWaveformChannels: 1,
NumberOfWaveformSamples: 2,
WaveformData: { BulkDataURI: 'http://example.com/waveform' },
},
],
};
const module = buildEcgModule(instance, userAuthenticationService);
await module!.waveformData.retrieveBulkData();
expect(global.fetch).toHaveBeenCalledWith('http://example.com/waveform', {
headers: {
Accept: 'application/octet-stream',
Authorization: 'Bearer token123',
},
});
});
it('retrieveBulkData throws when BulkDataURI response is not ok', async () => {
global.fetch = jest.fn().mockResolvedValue({ ok: false, status: 403 });
const instance = {
WaveformSequence: [
{
WaveformData: { BulkDataURI: 'http://example.com/waveform' },
},
],
};
const module = buildEcgModule(instance);
await expect(module!.waveformData.retrieveBulkData()).rejects.toThrow('403');
});
});
@@ -1,129 +0,0 @@
/**
* Decode a multiplexed Int16 buffer into per-channel arrays.
* Layout: sample0ch0, sample0ch1 ... sample0chN, sample1ch0, …
* Note: DICOM ECG data is canonically SS (signed short). The sampleInterpretation
* field is forwarded to ECGViewport for its own use; the raw buffer is always
* treated as Int16 because Cornerstone ECGViewport expects Int16Array[].
*/
export function decodeInt16Multiplex(
buffer: ArrayBuffer,
numberOfChannels: number,
numberOfSamples: number
): Int16Array[] {
const src = new Int16Array(buffer);
const channels: Int16Array[] = [];
for (let ch = 0; ch < numberOfChannels; ch++) {
const out = new Int16Array(numberOfSamples);
for (let s = 0; s < numberOfSamples; s++) {
out[s] = src[s * numberOfChannels + ch];
}
channels.push(out);
}
return channels;
}
/**
* Decode a base64 InlineBinary string into a raw ArrayBuffer.
*/
export function base64ToArrayBuffer(base64: string): ArrayBuffer {
const binaryStr = atob(base64);
const bytes = new Uint8Array(binaryStr.length);
for (let i = 0; i < binaryStr.length; i++) {
bytes[i] = binaryStr.charCodeAt(i);
}
return bytes.buffer;
}
export type EcgModule = {
numberOfWaveformChannels: number;
numberOfWaveformSamples: number;
samplingFrequency: number;
waveformBitsAllocated: number;
waveformSampleInterpretation: string;
multiplexGroupLabel: string;
channelDefinitionSequence: Array<{ channelSourceSequence: { codeMeaning: string } }>;
waveformData: { retrieveBulkData: () => Promise<Int16Array[]> };
};
/**
* Parse the naturalized DICOM instance's WaveformSequence and build the ecgModule
* that Cornerstone's ECGViewport.setEcg() expects via
* metaData.get(MetadataModules.ECG, imageId).
*
* Returns null if the instance has no WaveformSequence.
*/
export function buildEcgModule(
instance: any,
userAuthenticationService?: any
): EcgModule | null {
const waveformGroups = instance?.WaveformSequence;
if (!waveformGroups?.length) {
return null;
}
// Use the first (and typically only) multiplex group
const group = waveformGroups[0];
const numberOfChannels = group.NumberOfWaveformChannels ?? 0;
const numberOfSamples = group.NumberOfWaveformSamples ?? 0;
const samplingFrequency = group.SamplingFrequency ?? 1;
const bitsAllocated = group.WaveformBitsAllocated ?? 16;
const sampleInterpretation = group.WaveformSampleInterpretation ?? 'SS';
const multiplexGroupLabel = group.MultiplexGroupLabel ?? '';
const channelDefinitionSequence = (group.ChannelDefinitionSequence ?? []).map(ch => ({
channelSourceSequence: {
codeMeaning:
ch?.ChannelSourceSequence?.[0]?.CodeMeaning ??
ch?.ChannelSourceSequence?.[0]?.codeMeaning ??
'',
},
}));
const retrieveBulkData = async (): Promise<Int16Array[]> => {
const waveformData = group.WaveformData;
if (!waveformData) {
console.warn('[ECGViewport] No WaveformData found on instance');
return [];
}
let buffer: ArrayBuffer;
if (waveformData.InlineBinary) {
buffer = base64ToArrayBuffer(waveformData.InlineBinary);
} else if (waveformData.BulkDataURI) {
const headers: Record<string, string> = {
Accept: 'application/octet-stream',
};
const authHeader = userAuthenticationService?.getAuthorizationHeader?.();
if (authHeader) {
Object.assign(headers, authHeader);
}
const response = await fetch(waveformData.BulkDataURI, { headers });
if (!response.ok) {
throw new Error(
`[ECGViewport] Failed to fetch waveform BulkDataURI: ${response.status}`
);
}
buffer = await response.arrayBuffer();
} else {
console.warn('[ECGViewport] WaveformData has no InlineBinary or BulkDataURI');
return [];
}
return decodeInt16Multiplex(buffer, numberOfChannels, numberOfSamples);
};
return {
numberOfWaveformChannels: numberOfChannels,
numberOfWaveformSamples: numberOfSamples,
samplingFrequency,
waveformBitsAllocated: bitsAllocated,
waveformSampleInterpretation: sampleInterpretation,
multiplexGroupLabel,
channelDefinitionSequence,
waveformData: { retrieveBulkData },
};
}
@@ -8,9 +8,6 @@ jest.mock('@cornerstonejs/core', () => ({
SAGITTAL: 'sagittal',
CORONAL: 'coronal',
ACQUISITION: 'acquisition',
AXIAL_REFORMAT: 'axial_reformat',
SAGITTAL_REFORMAT: 'sagittal_reformat',
CORONAL_REFORMAT: 'coronal_reformat',
},
},
}));
@@ -36,21 +33,6 @@ describe('getCornerstoneOrientation', () => {
expect(result).toBe(Enums.OrientationAxis.CORONAL);
});
it('should return AXIAL_REFORMAT when orientation is axial_reformat', () => {
const result = getCornerstoneOrientation('axial_reformat');
expect(result).toBe(Enums.OrientationAxis.AXIAL_REFORMAT);
});
it('should return SAGITTAL_REFORMAT when orientation is sagittal_reformat', () => {
const result = getCornerstoneOrientation('sagittal_reformat');
expect(result).toBe(Enums.OrientationAxis.SAGITTAL_REFORMAT);
});
it('should return CORONAL_REFORMAT when orientation is coronal_reformat', () => {
const result = getCornerstoneOrientation('coronal_reformat');
expect(result).toBe(Enums.OrientationAxis.CORONAL_REFORMAT);
});
it('should return ACQUISITION for unknown orientation', () => {
const result = getCornerstoneOrientation('unknown');
expect(result).toBe(Enums.OrientationAxis.ACQUISITION);
@@ -3,25 +3,16 @@ import { Enums } from '@cornerstonejs/core';
const AXIAL = 'axial';
const SAGITTAL = 'sagittal';
const CORONAL = 'coronal';
const AXIAL_REFORMAT = 'axial_reformat';
const SAGITTAL_REFORMAT = 'sagittal_reformat';
const CORONAL_REFORMAT = 'coronal_reformat';
export default function getCornerstoneOrientation(orientation: string): Enums.OrientationAxis {
if (orientation) {
switch (orientation.toLowerCase()) {
case AXIAL:
return Enums.OrientationAxis.AXIAL;
case AXIAL_REFORMAT:
return Enums.OrientationAxis.AXIAL_REFORMAT;
case SAGITTAL:
return Enums.OrientationAxis.SAGITTAL;
case SAGITTAL_REFORMAT:
return Enums.OrientationAxis.SAGITTAL_REFORMAT;
case CORONAL:
return Enums.OrientationAxis.CORONAL;
case CORONAL_REFORMAT:
return Enums.OrientationAxis.CORONAL_REFORMAT;
default:
return Enums.OrientationAxis.ACQUISITION;
}
@@ -10,7 +10,6 @@ jest.mock('@cornerstonejs/core', () => ({
WHOLE_SLIDE: 'wholeslide',
ORTHOGRAPHIC: 'orthographic',
VOLUME_3D: 'volume3d',
ECG: 'ecg',
},
},
}));
@@ -51,14 +50,9 @@ describe('getCornerstoneViewportType', () => {
expect(result).toBe(Enums.ViewportType.VOLUME_3D);
});
it('should return ECG when viewportType is ecg', () => {
const result = getCornerstoneViewportType('ecg');
expect(result).toBe(Enums.ViewportType.ECG);
});
it('should throw error for invalid viewport type', () => {
expect(() => getCornerstoneViewportType('invalid')).toThrow(
'Invalid viewport type: invalid. Valid types are: stack, volume, video, wholeslide, ecg'
'Invalid viewport type: invalid. Valid types are: stack, volume, video, wholeslide'
);
});
@@ -7,7 +7,6 @@ const ORTHOGRAPHIC = 'orthographic';
const VOLUME_3D = 'volume3d';
const VIDEO = 'video';
const WHOLESLIDE = 'wholeslide';
const ECG = 'ecg';
export default function getCornerstoneViewportType(
viewportType: string,
@@ -26,10 +25,6 @@ export default function getCornerstoneViewportType(
return Enums.ViewportType.WHOLE_SLIDE;
}
if (lowerViewportType === ECG) {
return Enums.ViewportType.ECG;
}
if (lowerViewportType === VOLUME || lowerViewportType === ORTHOGRAPHIC) {
return Enums.ViewportType.ORTHOGRAPHIC;
}
@@ -39,6 +34,6 @@ export default function getCornerstoneViewportType(
}
throw new Error(
`Invalid viewport type: ${viewportType}. Valid types are: stack, volume, video, wholeslide, ecg`
`Invalid viewport type: ${viewportType}. Valid types are: stack, volume, video, wholeslide`
);
}
@@ -1,22 +0,0 @@
/**
* Resolves the data ID (e.g. volumeId) for a viewport and display set.
* For viewports with multiple volumes/actors, returns the id that matches the display set; otherwise undefined.
* Use this to call viewport.getProperties(dataId) in a viewport-type-agnostic way.
*
* @param viewport - Viewport instance (stack, volume, or future types with optional getAllVolumeIds)
* @param displaySetInstanceUID - Display set instance UID to match
* @returns volumeId (or equivalent) for multi-actor viewports, undefined for single-actor
*/
export function getDataIdForViewport(
viewport: unknown,
displaySetInstanceUID: string
): string | undefined {
const vp = viewport as { getAllVolumeIds?: () => string[] };
if (typeof vp.getAllVolumeIds !== 'function') {
return undefined;
}
const volumeIds = vp.getAllVolumeIds() || [];
return volumeIds.length > 0
? volumeIds.find(id => id.includes(displaySetInstanceUID)) ?? undefined
: undefined;
}
@@ -262,57 +262,6 @@ describe('getUpdatedViewportsForSegmentation', () => {
expect(result).toEqual(mockUpdatedViewports);
});
it('should merge all grid viewports that reference the volume after hydration (e.g. 3D four-up)', () => {
const volumeUid = 'volume-1';
const viewports = new Map([
[
'vp-axial',
{
viewportId: 'vp-axial',
viewportOptions: { viewportId: 'vp-axial' },
displaySetInstanceUIDs: [volumeUid],
},
],
[
'vp-sagittal',
{
viewportId: 'vp-sagittal',
viewportOptions: { viewportId: 'vp-sagittal' },
displaySetInstanceUIDs: [volumeUid],
},
],
[
'vp-other-study',
{
viewportId: 'vp-other-study',
viewportOptions: { viewportId: 'vp-other-study' },
displaySetInstanceUIDs: ['other-volume'],
},
],
]);
mockViewportGridService.getState.mockReturnValue({
isHangingProtocolLayout: true,
viewports,
activeViewportId: 'vp-axial',
});
mockHangingProtocolService.getViewportsRequireUpdate.mockReturnValue([
{ viewportId: 'vp-axial', displaySetInstanceUIDs: [volumeUid] },
]);
const result = getUpdatedViewportsForSegmentation({
viewportId: 'vp-axial',
servicesManager: mockServicesManager as unknown as AppTypes.ServicesManager,
displaySetInstanceUIDs: [volumeUid],
});
expect(result).toEqual([
{ viewportId: 'vp-axial', displaySetInstanceUIDs: [volumeUid] },
{ viewportId: 'vp-sagittal', displaySetInstanceUIDs: [volumeUid] },
]);
});
it('should handle complex viewport structure', () => {
const complexViewport = {
viewportOptions: {
@@ -1,63 +1,3 @@
import type { Types } from '@ohif/core';
/**
* After SEG hydration we must refresh every viewport that shows the referenced volume so
* presentations (including segmentation) apply to all MPR/3D tiles. Hanging-protocol matching
* can return only the active viewport when protocol definitions omit viewportId (e.g. 3D four-up)
* or when layout state diverges from the protocol; this merges in all grid panes that already
* list that volume in `displaySetInstanceUIDs`.
*
* Only exact displaySetInstanceUID matches are used (no Frame-of-Reference inference): sibling
* MPR planes must already share the same referenced volume UID in grid state, or HP matching
* must list them; otherwise forcing a different UID onto a volume viewport can leave it blank.
*/
function mergeVolumeSharingViewports(
hangingProtocolUpdates: Types.HangingProtocol.ViewportUpdate[] | null | undefined,
volumeUid: string | undefined,
viewports: AppTypes.ViewportGrid.GridViewports
): Types.HangingProtocol.ViewportUpdate[] {
if (!volumeUid) {
return (hangingProtocolUpdates ?? []) as Types.HangingProtocol.ViewportUpdate[];
}
const byId = new Map<string, Types.HangingProtocol.ViewportUpdate>();
const add = (viewportId: string, uids: string[]) => {
if (!viewportId) {
return;
}
byId.set(viewportId, { viewportId, displaySetInstanceUIDs: uids });
};
if (Array.isArray(hangingProtocolUpdates)) {
for (const entry of hangingProtocolUpdates) {
const vid = entry.viewportId ?? entry.viewportOptions?.viewportId;
if (vid) {
add(vid, entry.displaySetInstanceUIDs?.length ? entry.displaySetInstanceUIDs : [volumeUid]);
}
}
}
viewports.forEach(vp => {
const uids = vp.displaySetInstanceUIDs || [];
if (uids.includes(volumeUid)) {
add(vp.viewportId, [volumeUid]);
}
});
const merged = Array.from(byId.values());
if (
merged.length === 0 &&
Array.isArray(hangingProtocolUpdates) &&
hangingProtocolUpdates.length > 0
) {
return hangingProtocolUpdates;
}
return merged;
}
function getUpdatedViewportsForSegmentation({
viewportId,
servicesManager,
@@ -65,7 +5,7 @@ function getUpdatedViewportsForSegmentation({
}: withAppTypes) {
const { hangingProtocolService, viewportGridService } = servicesManager.services;
const { isHangingProtocolLayout, viewports } = viewportGridService.getState();
const { isHangingProtocolLayout } = viewportGridService.getState();
const viewport = getTargetViewport({ viewportId, viewportGridService });
const targetViewportId = viewport.viewportOptions.viewportId;
@@ -76,11 +16,7 @@ function getUpdatedViewportsForSegmentation({
isHangingProtocolLayout
);
if (updatedViewports == null) {
return updatedViewports;
}
return mergeVolumeSharingViewports(updatedViewports, displaySetInstanceUIDs[0], viewports);
return updatedViewports;
}
const getTargetViewport = ({ viewportId, viewportGridService }) => {
@@ -11,7 +11,7 @@ describe('promptHydrationDialog', () => {
};
const mockExtensionManager = {
appConfig: {
_appConfig: {
measurementTrackingMode: 'standard',
disableConfirmationPrompts: false,
},
@@ -57,7 +57,7 @@ describe('promptHydrationDialog', () => {
});
it('should return HYDRATE response when disableConfirmationPrompts is true for non-SR types', async () => {
mockExtensionManager.appConfig.disableConfirmationPrompts = true;
mockExtensionManager._appConfig.disableConfirmationPrompts = true;
const result = await promptHydrationDialog(defaultParameters);
@@ -71,7 +71,7 @@ describe('promptHydrationDialog', () => {
});
it('should show dialog when disableConfirmationPrompts is false for non-SR types', async () => {
mockExtensionManager.appConfig.disableConfirmationPrompts = false;
mockExtensionManager._appConfig.disableConfirmationPrompts = false;
const promise = promptHydrationDialog(defaultParameters);
@@ -107,7 +107,7 @@ describe('promptHydrationDialog', () => {
});
it('should handle CANCEL response', async () => {
mockExtensionManager.appConfig.disableConfirmationPrompts = false;
mockExtensionManager._appConfig.disableConfirmationPrompts = false;
const promise = promptHydrationDialog(defaultParameters);
@@ -120,7 +120,7 @@ describe('promptHydrationDialog', () => {
});
it('should handle onOutsideClick', async () => {
mockExtensionManager.appConfig.disableConfirmationPrompts = false;
mockExtensionManager._appConfig.disableConfirmationPrompts = false;
const promise = promptHydrationDialog(defaultParameters);
@@ -133,7 +133,7 @@ describe('promptHydrationDialog', () => {
});
it('should handle onKeyPress Enter', async () => {
mockExtensionManager.appConfig.disableConfirmationPrompts = false;
mockExtensionManager._appConfig.disableConfirmationPrompts = false;
const promise = promptHydrationDialog(defaultParameters);
@@ -146,7 +146,7 @@ describe('promptHydrationDialog', () => {
});
it('should handle onKeyPress non-Enter key', async () => {
mockExtensionManager.appConfig.disableConfirmationPrompts = false;
mockExtensionManager._appConfig.disableConfirmationPrompts = false;
const promise = promptHydrationDialog(defaultParameters);
@@ -163,7 +163,7 @@ describe('promptHydrationDialog', () => {
});
it('should handle SEG type hydration with setTimeout', async () => {
mockExtensionManager.appConfig.disableConfirmationPrompts = true;
mockExtensionManager._appConfig.disableConfirmationPrompts = true;
await promptHydrationDialog({
...defaultParameters,
@@ -178,7 +178,7 @@ describe('promptHydrationDialog', () => {
});
it('should handle RTSTRUCT type hydration', async () => {
mockExtensionManager.appConfig.disableConfirmationPrompts = true;
mockExtensionManager._appConfig.disableConfirmationPrompts = true;
const result = await promptHydrationDialog({
...defaultParameters,
@@ -194,7 +194,7 @@ describe('promptHydrationDialog', () => {
});
it('should handle SR type hydration when standardMode is true', async () => {
mockExtensionManager.appConfig.measurementTrackingMode = 'standard';
mockExtensionManager._appConfig.measurementTrackingMode = 'standard';
const mockHydrationResult = {
StudyInstanceUID: 'test-study-uid',
SeriesInstanceUIDs: ['series-1', 'series-2'],
@@ -222,7 +222,7 @@ describe('promptHydrationDialog', () => {
});
it('should handle SR type hydration when standardMode is false', async () => {
mockExtensionManager.appConfig.measurementTrackingMode = 'other';
mockExtensionManager._appConfig.measurementTrackingMode = 'other';
const result = await promptHydrationDialog({
...defaultParameters,
@@ -241,7 +241,7 @@ describe('promptHydrationDialog', () => {
});
it('should handle SR type with CANCEL response', async () => {
mockExtensionManager.appConfig.measurementTrackingMode = 'standard';
mockExtensionManager._appConfig.measurementTrackingMode = 'standard';
const promise = promptHydrationDialog({
...defaultParameters,
@@ -262,7 +262,7 @@ describe('promptHydrationDialog', () => {
});
it('should handle undefined preHydrateCallbacks', async () => {
mockExtensionManager.appConfig.disableConfirmationPrompts = true;
mockExtensionManager._appConfig.disableConfirmationPrompts = true;
await promptHydrationDialog({
...defaultParameters,
@@ -273,7 +273,7 @@ describe('promptHydrationDialog', () => {
});
it('should handle empty preHydrateCallbacks array', async () => {
mockExtensionManager.appConfig.disableConfirmationPrompts = true;
mockExtensionManager._appConfig.disableConfirmationPrompts = true;
await promptHydrationDialog({
...defaultParameters,
@@ -285,7 +285,7 @@ describe('promptHydrationDialog', () => {
it('should execute multiple preHydrateCallbacks', async () => {
const mockPreHydrateCallback2 = jest.fn();
mockExtensionManager.appConfig.disableConfirmationPrompts = true;
mockExtensionManager._appConfig.disableConfirmationPrompts = true;
await promptHydrationDialog({
...defaultParameters,
@@ -297,7 +297,7 @@ describe('promptHydrationDialog', () => {
});
it('should get correct customization message key for SEG type', async () => {
mockExtensionManager.appConfig.disableConfirmationPrompts = false;
mockExtensionManager._appConfig.disableConfirmationPrompts = false;
const promise = promptHydrationDialog({
...defaultParameters,
@@ -314,7 +314,7 @@ describe('promptHydrationDialog', () => {
});
it('should get correct customization message key for RTSTRUCT type', async () => {
mockExtensionManager.appConfig.disableConfirmationPrompts = false;
mockExtensionManager._appConfig.disableConfirmationPrompts = false;
const promise = promptHydrationDialog({
...defaultParameters,
@@ -331,7 +331,7 @@ describe('promptHydrationDialog', () => {
});
it('should get correct customization message key for SR type', async () => {
mockExtensionManager.appConfig.measurementTrackingMode = 'standard';
mockExtensionManager._appConfig.measurementTrackingMode = 'standard';
const promise = promptHydrationDialog({
...defaultParameters,
@@ -348,7 +348,7 @@ describe('promptHydrationDialog', () => {
});
it('should get default customization message key for unknown type', async () => {
mockExtensionManager.appConfig.disableConfirmationPrompts = false;
mockExtensionManager._appConfig.disableConfirmationPrompts = false;
const promise = promptHydrationDialog({
...defaultParameters,
@@ -365,7 +365,7 @@ describe('promptHydrationDialog', () => {
});
it('should get correct dialog id for SEG type', async () => {
mockExtensionManager.appConfig.disableConfirmationPrompts = false;
mockExtensionManager._appConfig.disableConfirmationPrompts = false;
const promise = promptHydrationDialog({
...defaultParameters,
@@ -384,7 +384,7 @@ describe('promptHydrationDialog', () => {
});
it('should get correct dialog id for SR type', async () => {
mockExtensionManager.appConfig.measurementTrackingMode = 'standard';
mockExtensionManager._appConfig.measurementTrackingMode = 'standard';
const promise = promptHydrationDialog({
...defaultParameters,
@@ -403,7 +403,7 @@ describe('promptHydrationDialog', () => {
});
it('should get default dialog id for unknown type', async () => {
mockExtensionManager.appConfig.disableConfirmationPrompts = false;
mockExtensionManager._appConfig.disableConfirmationPrompts = false;
const promise = promptHydrationDialog({
...defaultParameters,
@@ -422,7 +422,7 @@ describe('promptHydrationDialog', () => {
});
it('should handle hydrateCallback returning false for SEG', async () => {
mockExtensionManager.appConfig.disableConfirmationPrompts = true;
mockExtensionManager._appConfig.disableConfirmationPrompts = true;
mockHydrateCallback.mockResolvedValue(false);
const result = await promptHydrationDialog({
@@ -434,7 +434,7 @@ describe('promptHydrationDialog', () => {
});
it('should handle hydrateCallback returning false for RTSTRUCT', async () => {
mockExtensionManager.appConfig.disableConfirmationPrompts = true;
mockExtensionManager._appConfig.disableConfirmationPrompts = true;
mockHydrateCallback.mockResolvedValue(false);
const result = await promptHydrationDialog({
@@ -446,7 +446,7 @@ describe('promptHydrationDialog', () => {
});
it('should handle SR hydration with null result', async () => {
mockExtensionManager.appConfig.measurementTrackingMode = 'standard';
mockExtensionManager._appConfig.measurementTrackingMode = 'standard';
mockHydrateCallback.mockResolvedValue(null);
const promise = promptHydrationDialog({
@@ -470,7 +470,7 @@ describe('promptHydrationDialog', () => {
});
it('should handle RTSTRUCT type in getDialogId', async () => {
mockExtensionManager.appConfig.disableConfirmationPrompts = false;
mockExtensionManager._appConfig.disableConfirmationPrompts = false;
const promise = promptHydrationDialog({
...defaultParameters,
@@ -70,7 +70,7 @@ function promptHydrationDialog({
}: HydrationDialogProps): Promise<boolean | HydrationSRResult> {
const { uiViewportDialogService, customizationService } = servicesManager.services;
const extensionManager = servicesManager._extensionManager;
const appConfig = extensionManager.appConfig;
const appConfig = extensionManager._appConfig;
// Todo: make this use enum from the extension, we should move the enum
const standardMode = appConfig?.measurementTrackingMode === 'standard';
@@ -94,30 +94,22 @@ function promptHydrationDialog({
if (type === HydrationType.SEG) {
// SEG needs setTimeout
window.setTimeout(async () => {
try {
const isHydrated = await hydrateCallback({
segDisplaySet: displaySet,
viewportId,
});
resolve(isHydrated);
} catch (error) {
reject(error);
}
const isHydrated = await hydrateCallback({
segDisplaySet: displaySet,
viewportId,
});
resolve(isHydrated);
}, 0);
} else if (type === HydrationType.RTSTRUCT) {
// RT hydration
window.setTimeout(async () => {
try {
const isHydrated = await hydrateCallback({
rtDisplaySet: displaySet,
viewportId,
servicesManager,
});
resolve(isHydrated);
} catch (error) {
reject(error);
}
}, 0);
const isHydrated = await hydrateCallback({
rtDisplaySet: displaySet,
viewportId,
servicesManager,
});
resolve(isHydrated);
} else if (type === HydrationType.SR) {
// SR has a different result structure
const hydrationResult = await hydrateCallback(displaySet);
@@ -15,7 +15,6 @@ describe('setUpSegmentationEventHandlers', () => {
const mockSegmentationService = {
EVENTS: {
SEGMENTATION_ADDED: 'SEGMENTATION_ADDED',
SEGMENTATION_REMOVED: 'SEGMENTATION_REMOVED',
},
subscribe: jest.fn(),
getSegmentation: jest.fn(),
@@ -41,7 +40,6 @@ describe('setUpSegmentationEventHandlers', () => {
const mockUnsubscribeDataModified = jest.fn();
const mockUnsubscribeModified = jest.fn();
const mockUnsubscribeCreated = jest.fn();
const mockUnsubscribeRemoved = jest.fn();
const mockUnsubscribeSelectedSegmentationsForViewportEvents = [jest.fn(), jest.fn()];
const defaultParameters = {
@@ -61,14 +59,8 @@ describe('setUpSegmentationEventHandlers', () => {
unsubscribeSelectedSegmentationsForViewportEvents:
mockUnsubscribeSelectedSegmentationsForViewportEvents,
});
mockSegmentationService.subscribe.mockImplementation((eventName: string) => {
if (eventName === mockSegmentationService.EVENTS.SEGMENTATION_ADDED) {
return { unsubscribe: mockUnsubscribeCreated };
}
if (eventName === mockSegmentationService.EVENTS.SEGMENTATION_REMOVED) {
return { unsubscribe: mockUnsubscribeRemoved };
}
return { unsubscribe: jest.fn() };
mockSegmentationService.subscribe.mockReturnValue({
unsubscribe: mockUnsubscribeCreated,
});
});
@@ -107,7 +99,6 @@ describe('setUpSegmentationEventHandlers', () => {
mockUnsubscribeDataModified,
mockUnsubscribeModified,
mockUnsubscribeCreated,
mockUnsubscribeRemoved,
...mockUnsubscribeSelectedSegmentationsForViewportEvents,
],
});
@@ -367,6 +358,5 @@ describe('setUpSegmentationEventHandlers', () => {
expect(mockUnsubscribeDataModified).toHaveBeenCalled();
expect(mockUnsubscribeModified).toHaveBeenCalled();
expect(mockUnsubscribeCreated).toHaveBeenCalled();
expect(mockUnsubscribeRemoved).toHaveBeenCalled();
});
});
@@ -7,8 +7,7 @@ import {
} from './segmentationHandlers';
export const setUpSegmentationEventHandlers = ({ servicesManager, commandsManager }) => {
const { segmentationService, customizationService, displaySetService, viewportGridService } =
servicesManager.services;
const { segmentationService, customizationService, displaySetService } = servicesManager.services;
const { unsubscribe: unsubscribeSegmentationDataModifiedHandler } =
setupSegmentationDataModifiedHandler({
@@ -58,36 +57,6 @@ export const setUpSegmentationEventHandlers = ({ servicesManager, commandsManage
}
);
const { unsubscribe: unsubscribeSegmentationRemoved } = segmentationService.subscribe(
segmentationService.EVENTS.SEGMENTATION_REMOVED,
({ segmentationId }) => {
const displaySet = displaySetService.getDisplaySetByUID(segmentationId);
// Remove the display set layer from all viewports that have it
if (displaySet) {
const state = viewportGridService.getState();
const viewports = state.viewports;
// Find all viewports that contain this segmentation's display set as a layer
for (const [viewportId, viewport] of viewports.entries()) {
const displaySetInstanceUIDs = viewport.displaySetInstanceUIDs || [];
if (displaySetInstanceUIDs.includes(segmentationId)) {
// Remove the display set layer from this viewport
commandsManager.runCommand('removeDisplaySetLayer', {
viewportId,
displaySetInstanceUID: segmentationId,
});
}
}
// Delete the display set from the service if it was made in client
if (displaySet.madeInClient) {
displaySetService.deleteDisplaySet(segmentationId);
}
}
}
);
const { unsubscribeSelectedSegmentationsForViewportEvents } =
setUpSelectedSegmentationsForViewportHandler({
segmentationService,
@@ -97,7 +66,6 @@ export const setUpSegmentationEventHandlers = ({ servicesManager, commandsManage
unsubscribeSegmentationDataModifiedHandler,
unsubscribeSegmentationModifiedHandler,
unsubscribeSegmentationCreated,
unsubscribeSegmentationRemoved,
...unsubscribeSelectedSegmentationsForViewportEvents,
];
+4 -559
View File
@@ -3,18 +3,7 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.13.0-beta.66](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.65...v3.13.0-beta.66) (2026-04-29)
### Bug Fixes
* **config url:** Hardening fetch options. ([#5985](https://github.com/OHIF/Viewers/issues/5985)) ([468e573](https://github.com/OHIF/Viewers/commit/468e5734a9ab02516430cc0dab5d7f2106dea950))
# [3.13.0-beta.65](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.64...v3.13.0-beta.65) (2026-04-29)
## [3.12.4](https://github.com/OHIF/Viewers/compare/v3.12.3...v3.12.4) (2026-06-05)
**Note:** Version bump only for package @ohif/extension-default
@@ -22,29 +11,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
# [3.13.0-beta.64](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.63...v3.13.0-beta.64) (2026-04-27)
### Bug Fixes
* **seg:** prevent segmentations from spreading to all viewports before hydration confirmation in 3D four-up ([#5967](https://github.com/OHIF/Viewers/issues/5967)) ([f8ccf9f](https://github.com/OHIF/Viewers/commit/f8ccf9ff2ea9ab7c38bd427514a8ae87902822a3))
# [3.13.0-beta.63](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.62...v3.13.0-beta.63) (2026-04-27)
### Bug Fixes
* **security:** refine dynamic config URL trust policy and document trusted-origin behavior ([#5973](https://github.com/OHIF/Viewers/issues/5973)) ([f3cca21](https://github.com/OHIF/Viewers/commit/f3cca21e49729fbf4bab85aa1de64b9dcfebd0ce))
# [3.13.0-beta.62](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.61...v3.13.0-beta.62) (2026-04-23)
## [3.12.3](https://github.com/OHIF/Viewers/compare/v3.12.2...v3.12.3) (2026-05-27)
**Note:** Version bump only for package @ohif/extension-default
@@ -52,7 +19,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
# [3.13.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.60...v3.13.0-beta.61) (2026-04-23)
## [3.12.2](https://github.com/OHIF/Viewers/compare/v3.12.1...v3.12.2) (2026-05-18)
**Note:** Version bump only for package @ohif/extension-default
@@ -60,529 +27,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
# [3.13.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.59...v3.13.0-beta.60) (2026-04-21)
### Bug Fixes
* **configuration:** Harden dynamic datasource URL trust boundaries and credential handling. ([#5963](https://github.com/OHIF/Viewers/issues/5963)) ([eede569](https://github.com/OHIF/Viewers/commit/eede569a88ed6a3177bbdea8552dfb93ca13cac5))
# [3.13.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.58...v3.13.0-beta.59) (2026-04-16)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.57...v3.13.0-beta.58) (2026-04-14)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.56...v3.13.0-beta.57) (2026-04-13)
### Bug Fixes
* Enhance multiframe instance handling and improve instance valida… ([#5956](https://github.com/OHIF/Viewers/issues/5956)) ([f5a66b9](https://github.com/OHIF/Viewers/commit/f5a66b9eea236cd3291eac857208d7465516c89a))
# [3.13.0-beta.56](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.55...v3.13.0-beta.56) (2026-04-10)
### Bug Fixes
* A couple of changes to enable cs3d integration build ([#5944](https://github.com/OHIF/Viewers/issues/5944)) ([f6bbd5c](https://github.com/OHIF/Viewers/commit/f6bbd5c779e4692dc47c93327a890661b8dcc174))
# [3.13.0-beta.55](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.54...v3.13.0-beta.55) (2026-04-10)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.54](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.53...v3.13.0-beta.54) (2026-04-08)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.53](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.52...v3.13.0-beta.53) (2026-04-06)
### Reverts
* rename DisplaySet.frameOfReferenceUID back to FrameOfReferenceUID ([#5943](https://github.com/OHIF/Viewers/issues/5943)) ([0e933c2](https://github.com/OHIF/Viewers/commit/0e933c256e07b7cda35ed2ba3cfb1ab35d895d57))
# [3.13.0-beta.52](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.51...v3.13.0-beta.52) (2026-04-06)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.51](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.50...v3.13.0-beta.51) (2026-04-03)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.50](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.49...v3.13.0-beta.50) (2026-04-02)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.49](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.48...v3.13.0-beta.49) (2026-04-02)
### Bug Fixes
* **segmentation:** restrict overlay segmentation menu to same frame of reference as viewport background display set ([#5900](https://github.com/OHIF/Viewers/issues/5900)) ([b9029ef](https://github.com/OHIF/Viewers/commit/b9029ef6f8d63a0e36ec929310c1c5ad3f563ef8))
# [3.13.0-beta.48](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.47...v3.13.0-beta.48) (2026-04-01)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.47](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.46...v3.13.0-beta.47) (2026-03-28)
### Bug Fixes
* prevent black viewport when navigating series with client-created segmentation ([#5919](https://github.com/OHIF/Viewers/issues/5919)) ([e66fb5a](https://github.com/OHIF/Viewers/commit/e66fb5a2b8c93a60ea20d315f73def7a02ea205f))
# [3.13.0-beta.46](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.45...v3.13.0-beta.46) (2026-03-27)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.45](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.44...v3.13.0-beta.45) (2026-03-27)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.44](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.43...v3.13.0-beta.44) (2026-03-27)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.43](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.42...v3.13.0-beta.43) (2026-03-17)
### Bug Fixes
* **SR:** Added support for spline and live wire SR items. ([#5870](https://github.com/OHIF/Viewers/issues/5870)) ([1d4802c](https://github.com/OHIF/Viewers/commit/1d4802c2a38dd75dca7afca87913e100453c9135))
# [3.13.0-beta.42](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.41...v3.13.0-beta.42) (2026-03-17)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.40...v3.13.0-beta.41) (2026-03-16)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.39...v3.13.0-beta.40) (2026-03-13)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.38...v3.13.0-beta.39) (2026-03-13)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.37...v3.13.0-beta.38) (2026-03-12)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.36...v3.13.0-beta.37) (2026-03-12)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.35...v3.13.0-beta.36) (2026-03-11)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.34...v3.13.0-beta.35) (2026-03-09)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.33...v3.13.0-beta.34) (2026-03-09)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.32...v3.13.0-beta.33) (2026-03-05)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.31...v3.13.0-beta.32) (2026-03-05)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.30...v3.13.0-beta.31) (2026-03-04)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.29...v3.13.0-beta.30) (2026-03-04)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.28...v3.13.0-beta.29) (2026-03-04)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.27...v3.13.0-beta.28) (2026-03-03)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.26...v3.13.0-beta.27) (2026-03-02)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.25...v3.13.0-beta.26) (2026-02-28)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.24...v3.13.0-beta.25) (2026-02-26)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.23...v3.13.0-beta.24) (2026-02-24)
### Bug Fixes
* prevent viewer crash when opening DICOM Tag Browser from empty viewport ([#5827](https://github.com/OHIF/Viewers/issues/5827)) ([d11d6d4](https://github.com/OHIF/Viewers/commit/d11d6d401bc92a3870ec1089d97235b01a6b27c3))
# [3.13.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.22...v3.13.0-beta.23) (2026-02-23)
### Bug Fixes
* palette color 8 encoded 16 ([#5823](https://github.com/OHIF/Viewers/issues/5823)) ([eeca1f7](https://github.com/OHIF/Viewers/commit/eeca1f7a7b529d1700f5d281a6fd98074547ffe9)), closes [#5813](https://github.com/OHIF/Viewers/issues/5813)
# [3.13.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.21...v3.13.0-beta.22) (2026-02-23)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.20...v3.13.0-beta.21) (2026-02-23)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.19...v3.13.0-beta.20) (2026-02-21)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.18...v3.13.0-beta.19) (2026-02-20)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.17...v3.13.0-beta.18) (2026-02-19)
### Bug Fixes
* **segmentation overlay:** update viewport ds list upon seg delete - OHIF-2425 ([#5729](https://github.com/OHIF/Viewers/issues/5729)) ([b353541](https://github.com/OHIF/Viewers/commit/b35354120a01d89b27844f967c32c052bba8b096))
# [3.13.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.16...v3.13.0-beta.17) (2026-02-19)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.15...v3.13.0-beta.16) (2026-02-18)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.14...v3.13.0-beta.15) (2026-02-17)
### Bug Fixes
* **dicom-tag-browser:** Prevent long series names from overlapping - OHIF-2406 ([#5809](https://github.com/OHIF/Viewers/issues/5809)) ([cca1a86](https://github.com/OHIF/Viewers/commit/cca1a8683bc7d392a3a07268f24585642d13b1cd))
# [3.13.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.13...v3.13.0-beta.14) (2026-02-13)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.12...v3.13.0-beta.13) (2026-02-12)
### Bug Fixes
* **colors:** Replace hardcoded black with background color token ([#5815](https://github.com/OHIF/Viewers/issues/5815)) ([dbc31a5](https://github.com/OHIF/Viewers/commit/dbc31a5d4ec5b2238683a580af96aff23d9fafeb))
# [3.13.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.11...v3.13.0-beta.12) (2026-02-12)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.10...v3.13.0-beta.11) (2026-02-12)
### Bug Fixes
* **colors:** Replaces legacy colors with ui-next colors ([#5351](https://github.com/OHIF/Viewers/issues/5351)) ([9a2691a](https://github.com/OHIF/Viewers/commit/9a2691a71fe3723bb05cbd148968b64e5d0fa951))
# [3.13.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.9...v3.13.0-beta.10) (2026-02-11)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.9) (2026-02-11)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.8) (2026-02-11)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.7) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.5...v3.13.0-beta.6) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.4...v3.13.0-beta.5) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.3...v3.13.0-beta.4) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.2...v3.13.0-beta.3) (2026-02-10)
### Bug Fixes
* **app:** display study not found message for all modes ([#5752](https://github.com/OHIF/Viewers/issues/5752)) ([7f9e59e](https://github.com/OHIF/Viewers/commit/7f9e59ee3074e3511d22c7f0075856a7bd2cc32e))
# [3.13.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.1...v3.13.0-beta.2) (2026-02-10)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.0...v3.13.0-beta.1) (2026-02-09)
**Note:** Version bump only for package @ohif/extension-default
# [3.13.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.13.0-beta.0) (2026-02-07)
# [3.12.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.12.0) (2026-02-06)
**Note:** Version bump only for package @ohif/extension-default
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-default",
"version": "3.13.0-beta.66",
"version": "3.12.4",
"description": "Common/default features and functionality for basic image viewing",
"author": "OHIF Core Team",
"license": "MIT",
@@ -34,8 +34,8 @@
"test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests"
},
"peerDependencies": {
"@ohif/core": "3.13.0-beta.66",
"@ohif/i18n": "3.13.0-beta.66",
"@ohif/core": "3.12.4",
"@ohif/i18n": "3.12.4",
"dcmjs": "0.49.4",
"dicomweb-client": "0.10.4",
"prop-types": "15.8.1",
@@ -1,3 +1,5 @@
import { DicomMetadataStore } from '@ohif/core';
/**
*
* @param {*} servicesManager
@@ -5,8 +7,7 @@
async function createReportAsync({
servicesManager,
getReport,
reportType = 'Measurements',
successMessage,
reportType = 'measurement',
}: withAppTypes) {
const { displaySetService, uiNotificationService, uiDialogService } = servicesManager.services;
@@ -17,15 +18,18 @@ async function createReportAsync({
return;
}
// addInstances is called by the store command (storeMeasurements/storeSegmentation),
// so the display set should already exist at this point.
// The "Mode" route listens for DicomMetadataStore changes
// When a new instance is added, it listens and
// automatically calls makeDisplaySets
DicomMetadataStore.addInstances([naturalizedReport], true);
const displaySet = displaySetService.getMostRecentDisplaySet();
const displaySetInstanceUID = displaySet.displaySetInstanceUID;
uiNotificationService.show({
title: 'Create Report',
message: successMessage ?? `${reportType} saved successfully`,
message: `${reportType} saved successfully`,
type: 'success',
});
Loaded 100 of 417 files, more files were not shown because too many files have changed in this diff. Show more